我在我的应用程序中使用推送通知服务。当应用程序在后台时,我能够在通知屏幕上看到通知(当我们从iOS设备顶部向下滑动时显示的屏幕)。但如果应用程序是在前台的委托方法
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
正在被调用,但通知屏幕上没有显示通知。
我想在通知屏幕上显示通知,不管应用程序是在后台还是前台。我厌倦了寻找解决办法。任何帮助都非常感激。
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])
}
}
用于swift 5解析推送通知字典
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
}
}
当应用程序在前台显示横幅消息时,使用以下方法。
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
...
}
也适用于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])
}
}
}
要注意的主要事情是不要使用声音,而在前景,它不会显示横幅
在你的应用委托中使用下面的代码
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])
}
}