![](/img/trans.png)
[英]how to handle while multiple push notification comes at same time in foreground of app in iOS
[英]Get push notification while App in foreground iOS
我在我的应用程序中使用推送通知服务。 当应用程序在后台时,我可以在通知屏幕上看到通知(当我们从 iOS 设备顶部向下滑动时显示的屏幕)。 但是如果应用程序在前台,委托方法
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
正在被调用,但通知屏幕中未显示通知。
我想在通知屏幕上显示通知,无论应用程序是在后台还是前台。 我厌倦了寻找解决方案。 任何帮助是极大的赞赏。
要在应用程序处于前台时显示横幅消息,请使用以下方法。
iOS 10,Swift 3/4 :
// This method will be called when app received push notifications in foreground func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.alert,.badge,.sound]) }
iOS 10,Swift 2.3 :
@available(iOS 10.0, *) func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) { //Handle the notification completionHandler( [UNNotificationPresentationOptions.Alert, UNNotificationPresentationOptions.Sound, UNNotificationPresentationOptions.Badge]) }
您还必须将您的应用代理注册为通知中心的代理:
import UserNotifications // snip: class AppDelegate, UIResponder, UIApplicationDelegate: UNUserNotificationCenterDelegate // snip, func application(_ application: UIApplication. didFinishLaunchingWithOptions launchOptions: [UIApplication?LaunchOptionsKey. Any].) -> Bool { // set the delegate in didFinishLaunchingWithOptions UNUserNotificationCenter.current().delegate = self. }
下面的代码将为您工作:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { application.applicationIconBadgeNumber = 0; //self.textView.text = [userInfo description]; // We can determine whether an application is launched as a result of the user tapping the action // button or whether the notification was delivered to the already-running application by examining // the application state. if (application.applicationState == UIApplicationStateActive) { // Nothing to do if applicationState is Inactive, the iOS already displayed an alert view. UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Did receive a Remote Notification" message:[NSString stringWithFormat:@"Your App name received this notification while it was running:\n%@",[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]]delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alertView show]; } }
物镜 C
对于iOS 10
,我们需要集成willPresentNotification
方法以在foreground
显示通知横幅。
如果应用程序处于前台模式(活动)
- (void)userNotificationCenter:(UNUserNotificationCenter* )center willPresentNotification:(UNNotification* )notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler { NSLog( @"Here handle push notification in foreground" ); //For notification Banner - when app in foreground completionHandler(UNNotificationPresentationOptionAlert); // Print Notification info NSLog(@"Userinfo %@",notification.request.content.userInfo); }
对于任何可能感兴趣的人,我最终创建了一个自定义视图,该视图看起来像顶部的系统推送横幅,但添加了一个关闭按钮(蓝色小 X)和一个用于点击消息以进行自定义操作的选项。 它还支持在用户有时间阅读/关闭旧通知之前到达多个通知的情况(不限制可以堆积多少......)
用法基本是在线的:
[AGPushNoteView showWithNotificationMessage:@"John Doe sent you a message;"]
它在 iOS7 上看起来像这样(iOS6 的外观和感觉是 iOS6...)
如果应用程序在前台运行,iOS 将不会显示通知横幅/警报。 这是设计使然。 但是我们可以通过使用UILocalNotification
来实现它,如下所示
在接收到远程时检查应用程序是否处于活动状态 state
通知。 如果在活动 state 中触发 UILocalNotification。
if (application.applicationState == UIApplicationStateActive ) { UILocalNotification *localNotification = [[UILocalNotification alloc] init]; localNotification.userInfo = userInfo; localNotification.soundName = UILocalNotificationDefaultSoundName; localNotification.alertBody = message; localNotification.fireDate = [NSDate date]; [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; }
SWIFT:
if application.applicationState ==.active { var localNotification = UILocalNotification() localNotification.userInfo = userInfo localNotification.soundName = UILocalNotificationDefaultSoundName localNotification.alertBody = message localNotification.fireDate = Date() UIApplication.shared.scheduleLocalNotification(localNotification) }
Xcode 10 Swift 4.2
当您的应用程序处于前台时显示推送通知 -
第一步:在 AppDelegate class 中添加委托 UNUserNotificationCenterDelegate。
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
第 2 步:设置 UNUserNotificationCenter 委托
let notificationCenter = UNUserNotificationCenter.current() notificationCenter.delegate = self
第 3 步:此步骤将允许您的应用程序在前台显示推送通知
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.alert,.sound]) }
第四步:这一步是可选的。 检查您的应用程序是否在前台,如果它在前台,则显示 Local PushNotification。
func application(_ application: UIApplication,didReceiveRemoteNotification userInfo: [AnyHashable: Any],fetchCompletionHandler completionHandler:@escaping (UIBackgroundFetchResult) -> Void) { let state: UIApplicationState = application.applicationState if (state ==.inactive || state ==.background) { // go to screen relevant to Notification content print("background") } else { // App is in UIApplicationStateActive (running in foreground) print("foreground") showLocalNotification() } }
本地通知 function -
fileprivate func showLocalNotification() { //creating the notification content let content = UNMutableNotificationContent() //adding title, subtitle, body and badge content.title = "App Update" //content.subtitle = "local notification" content.body = "New version of app update is available." //content.badge = 1 content.sound = UNNotificationSound.default() //getting the notification trigger //it will be called after 5 seconds let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false) //getting the notification request let request = UNNotificationRequest(identifier: "SimplifiedIOSNotification", content: content, trigger: trigger) //adding the notification to notification center notificationCenter.add(request, withCompletionHandler: nil) }
对于 Swift 5
1) 使用
UNUserNotificationCenterDelegate
确认 AppDelegate 的委托2)
UNUserNotificationCenter.current().delegate = self
indidFinishLaunch
3)在
AppDelegate
中实现以下方法。
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { print("Push notification received in foreground.") completionHandler([.alert,.sound,.badge]) }
而已
如果应用程序在前台运行,iOS 将不会显示通知横幅/警报。 这是设计使然。 您必须编写一些代码来处理您的应用程序在前台接收通知的情况。 您应该以最合适的方式显示通知(例如,将徽章编号添加到UITabBar
图标、模拟通知中心横幅等)。
我在我的应用程序中使用了推送通知服务。 当应用程序在后台运行时,我可以在通知屏幕(从iOS设备顶部向下滑动时显示的屏幕)上看到通知。 但是如果应用程序位于前台,则委托方法
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
正在被呼叫,但通知未显示在通知屏幕中。
我想在通知屏幕上显示通知,而不管应用程序是在后台还是在前台。 寻找解决方案让我很累。 任何帮助是极大的赞赏。
您可以创建自己的模仿横幅警报的通知。
一种方法是创建一个自定义 uiview,它看起来像横幅,可以动画和响应触摸。 考虑到这一点,您可以创建具有更多功能的更好的横幅。
或者您可以寻找一个 api 为您完成它并将它们作为 podfiles 添加到您的项目中。
这是我用过的一对:
这是在活动 state(前台或打开)中的应用程序时接收推送通知的代码。 UNUserNotificationCenter 文档
@available(iOS 10.0, *) func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) { completionHandler([UNNotificationPresentationOptions.Alert,UNNotificationPresentationOptions.Sound,UNNotificationPresentationOptions.Badge]) }
如果需要访问通知的userInfo 使用代码: notification.request.content.userInfo
将 completionHandler 行添加到委托方法为我解决了同样的问题:
//Called when a notification is delivered to a foreground app. @available(iOS 10.0, *) func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.alert,.badge,.sound]) }
对于 swift 5 解析 PushNotification 字典
func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable: Any]) { if application.applicationState ==.active { if let aps1 = data["aps"] as? NSDictionary { if let dict = aps1["alert"] as? NSDictionary { if let strTitle = dict["title"] as? String, let strBody = dict["body"] as? String { if let topVC = UIApplication.getTopViewController() { //Apply your own logic as per requirement print("strTitle::\(strTitle), strBody:: \(strBody)") } } } } } }
获取我们在其上显示 topBanner 的 top viewController
extension UIApplication { class func getTopViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? { if let nav = base as? UINavigationController { return getTopViewController(base: nav.visibleViewController) } else if let tab = base as? UITabBarController, let selected = tab.selectedViewController { return getTopViewController(base: selected) } else if let presented = base?.presentedViewController { return getTopViewController(base: presented) } return base } }
在您的应用委托中使用以下代码
import UIKit import UserNotifications @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate { var currentToken: String? var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. application.registerForRemoteNotifications() let center = UNUserNotificationCenter.current() center.requestAuthorization(options: [.alert,.sound,.badge]) { (granted, error) in // Enable or disable features based on authorization. if granted == true { print("Allow") UIApplication.shared.registerForRemoteNotifications() } else { print("Don't Allow") } } UNUserNotificationCenter.current().delegate = self return true } func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data){ let tokenParts = deviceToken.map { data -> String in return String(format: "%02.2hhx", data) } let token = tokenParts.joined() currentToken = token //get device token to delegate variable } public class var shared: AppDelegate { return UIApplication.shared.delegate as: AppDelegate } func userNotificationCenter(_ center, UNUserNotificationCenter: willPresent notification, UNNotification: withCompletionHandler completionHandler. @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([,alert.,badge. sound]) } }
最好的方法是使用扩展 AppDelegate 在AppDelegate
中添加UNUserNotificationCenterDelegate
extension AppDelegate: UNUserNotificationCenterDelegate
该扩展告诉应用程序能够在使用时获得通知
并实现这个方法
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler(.alert) }
仅当应用程序位于Foreground时,才会在委托上调用此方法。
所以最终的实现:
extension AppDelegate: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler(.alert) } }
并且要调用它,您必须在didFinishLaunchingWithOptions
中的 AppDelegate 中设置委托添加此行
UNUserNotificationCenter.current().delegate = self
你可以修改
completionHandler(.alert)
和
completionHandler([.alert,.badge,.sound]))
也可以在 iOS 14+ 中工作,无需手动处理任何警报或视图,只需让 iOS 做它的事情
在我们接收通知的地方用下面的代码替换
func userNotificationCenter( _ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void ) { if (UIApplication.shared.applicationState ==.inactive || UIApplication.shared.applicationState ==.background) { if #available(iOS 14.0, *) { completionHandler([[.banner,.sound]]) } else { completionHandler([.alert,.sound]) } } else { if #available(iOS 14.0, *) { completionHandler([[.banner]]) } else { completionHandler([.alert]) } } }
要注意的主要事情是不要在前台使用声音,它不会显示横幅
如上所述,您应该使用UserNotification.framework
来实现这一点。 但出于我的目的,无论如何我都必须在应用程序中显示它,并且想要拥有iOS 11
风格,所以我创建了一个小的帮助视图,也许对某人有用。
100% 工作测试
首次导入
import UserNotifications
然后在 class 中添加委托
UNUserNotificationCenterDelegate
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate
当应用程序打开并收到通知时,以下方法负责。
将呈现
@available(iOS 10.0, *) func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { let content = notification.request.content let alertVC = UIAlertController.init(title: title, message: body, preferredStyle:.alert) alertVC.addAction(UIAlertAction.init(title: appLan_share.Ok_txt, style:.default, handler: { _ in //handle tap here or navigate somewhere….. })) vc?.present(alertVC, animated: true, completion: nil) print("notification Data: \(content.userInfo.values)") completionHandler([.alert,.sound]) }
您还可以通过检查当前应用程序 state 来处理应用程序 state。
此外,如果您的应用程序未运行,则以下方法负责处理推送通知
收到
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfo let aps = userInfo["aps"] as? [String: Any] let alert = aps?["alert"] as? [String: String] }
遵循这个答案有一个区别,不推荐使用.alert,使用.banner:
class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate { func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil ) -> Bool { UNUserNotificationCenter.current().delegate = self return true } func userNotificationCenter( _ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void ) { completionHandler([.banner,.badge,.sound]) } }
如果您的应用程序在前台 state,这意味着您当前正在使用同一个应用程序。 所以一般不需要在顶部显示通知。
但是,如果您想在这种情况下显示通知,则必须创建自定义警报视图或自定义视图,例如 Toast 或其他东西,以向用户显示您已收到通知。
如果您的应用中有此类功能,您也可以在顶部显示徽章。
正如@Danial Martine 所说,iOS 不会显示通知横幅/警报。 这是设计使然。 但如果真的必须这样做,那么有一种方法。 我也通过同样的方式实现了这一点。
1.从Parse FrameWork下载解析框架
2.导入#import <Parse/Parse.h>
3.将以下代码添加到您的 didReceiveRemoteNotification 方法
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { [PFPush handlePush:userInfo]; }
PFPush 将负责如何处理远程通知。 如果应用程序在前台,则会显示警报,否则会在顶部显示通知。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.