繁体   English   中英

在前台应用程序时获取推送通知 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)和一个用于点击消息以进行自定义操作的选项。 它还支持在用户有时间阅读/关闭旧通知之前到达多个通知的情况(不限制可以堆积多少......)

链接到 GitHub:AGPushNote

用法基本是在线的:

 [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 in didFinishLaunch

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 添加到您的项目中。

这是我用过的一对:

https://github.com/terryworona/TWMessageBarManager

https://github.com/toursprung/TSMessages

这是在活动 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风格,所以我创建了一个小的帮助视图,也许对某人有用。

GitHub 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] }

iOS 14+

遵循这个答案有一个区别,不推荐使用.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM