应用不运行时如何处理推送通知?
How Can I Handle Push Notification When App Is Not Running?
我在我的项目中添加了一个信号,用于发送任何新闻通知,以便在他们单击通知时向他们显示详细信息视图。当应用程序处于前台或后台时它运行良好,但当应用程序不是 运行.
时它不起作用
我研究了一下,他们说当应用程序没有启动时,didRecieve 方法没有被调用。所以,我必须在 didFinishLaunchingWithOptions 方法中处理通知,我试过了,但还是一样。
AppDelegate.swift
import UIKit
import CoreData
import Firebase
import OneSignal
import GoogleMobileAds
import UserNotifications
import SDWebImageWebPCoder
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var shortcutItemToProcess: UIApplicationShortcutItem?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
GADMobileAds.sharedInstance().start(completionHandler: nil)
let onesignalInitSettings = [kOSSettingsKeyAutoPrompt: false]
OneSignal.initWithLaunchOptions(launchOptions,
appId: "xxxxxxxxxxxxxxxxxxx",
handleNotificationAction: nil,
settings: onesignalInitSettings)
OneSignal.inFocusDisplayType = OSNotificationDisplayType.notification
OneSignal.promptForPushNotifications(userResponse: { accepted in
})
let WebPCoder = SDImageWebPCoder.shared
SDImageCodersManager.shared.addCoder(WebPCoder)
registerForPushNotifications()
return true
}
func registerForPushNotifications() {
let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.delegate = self
let readAction = UNNotificationAction(identifier: "read", title: "Read", options: [.foreground])
let closeAction = UNNotificationAction(identifier: "close", title: "Close", options: [])
let category = UNNotificationCategory(identifier: "etkilesim", actions: [readAction, closeAction], intentIdentifiers: [], options: [])
notificationCenter.setNotificationCategories([category])
notificationCenter.requestAuthorization(options: [.alert, .sound, .badge]) {
(granted, error) in
guard granted else { return }
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
// Grab a reference to the shortcutItem to use in the scene
if let shortcutItem = options.shortcutItem {
shortcutItemToProcess = shortcutItem
}
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
}
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .sound])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
var postId:String = ""
var postType:String = ""
if let custom = response.notification.request.content.userInfo["custom"] as? NSDictionary{
if let a = custom["a"] as? NSDictionary{
if let id = a["id"] as? String{
postId = id
}
if let type = a["rights"] as? String{
postType = type
}
}
}
if response.actionIdentifier == "read" {
if postId != ""{
NotificationCenter.default.post(name: NSNotification.Name("Detail"), object: nil, userInfo: ["id": postId, "type": postType])
}
}else if response.actionIdentifier == "close" {
print("KAPAT")
} else {
if postId != ""{
NotificationCenter.default.post(name: NSNotification.Name("Detail"), object: nil, userInfo: ["id": postId, "type": postType])
}
}
completionHandler()
}
}
您必须添加后台模式 -> 远程通知到您的应用程序功能,以便完全访问委托方法,例如:didReceiveRemoteNotification
。
我建议您将远程 nots 存储在链接到每个 user/device 的后端,并在每次应用程序启动时立即获取它们。只有这样才能保证数据的一致性。
请检查this question。
哈哈。我用异步包装了我的代码,现在运行良好。
if response.actionIdentifier == "read" {
if postId != ""{
DispatchQueue.main.async(execute: {
NotificationCenter.default.post(name: NSNotification.Name("Detail"), object: nil, userInfo: ["id": postId, "type": postType])
})
completionHandler()
}
}else if response.actionIdentifier == "close" {
print("CLOSE")
completionHandler()
} else {
if postId != ""{
DispatchQueue.main.async(execute: {
NotificationCenter.default.post(name: NSNotification.Name("Detail"), object: nil, userInfo: ["id": postId, "type": postType])
})
completionHandler()
}
}
我在我的项目中添加了一个信号,用于发送任何新闻通知,以便在他们单击通知时向他们显示详细信息视图。当应用程序处于前台或后台时它运行良好,但当应用程序不是 运行.
时它不起作用我研究了一下,他们说当应用程序没有启动时,didRecieve 方法没有被调用。所以,我必须在 didFinishLaunchingWithOptions 方法中处理通知,我试过了,但还是一样。
AppDelegate.swift
import UIKit
import CoreData
import Firebase
import OneSignal
import GoogleMobileAds
import UserNotifications
import SDWebImageWebPCoder
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var shortcutItemToProcess: UIApplicationShortcutItem?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
GADMobileAds.sharedInstance().start(completionHandler: nil)
let onesignalInitSettings = [kOSSettingsKeyAutoPrompt: false]
OneSignal.initWithLaunchOptions(launchOptions,
appId: "xxxxxxxxxxxxxxxxxxx",
handleNotificationAction: nil,
settings: onesignalInitSettings)
OneSignal.inFocusDisplayType = OSNotificationDisplayType.notification
OneSignal.promptForPushNotifications(userResponse: { accepted in
})
let WebPCoder = SDImageWebPCoder.shared
SDImageCodersManager.shared.addCoder(WebPCoder)
registerForPushNotifications()
return true
}
func registerForPushNotifications() {
let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.delegate = self
let readAction = UNNotificationAction(identifier: "read", title: "Read", options: [.foreground])
let closeAction = UNNotificationAction(identifier: "close", title: "Close", options: [])
let category = UNNotificationCategory(identifier: "etkilesim", actions: [readAction, closeAction], intentIdentifiers: [], options: [])
notificationCenter.setNotificationCategories([category])
notificationCenter.requestAuthorization(options: [.alert, .sound, .badge]) {
(granted, error) in
guard granted else { return }
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
// Grab a reference to the shortcutItem to use in the scene
if let shortcutItem = options.shortcutItem {
shortcutItemToProcess = shortcutItem
}
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
}
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .sound])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
var postId:String = ""
var postType:String = ""
if let custom = response.notification.request.content.userInfo["custom"] as? NSDictionary{
if let a = custom["a"] as? NSDictionary{
if let id = a["id"] as? String{
postId = id
}
if let type = a["rights"] as? String{
postType = type
}
}
}
if response.actionIdentifier == "read" {
if postId != ""{
NotificationCenter.default.post(name: NSNotification.Name("Detail"), object: nil, userInfo: ["id": postId, "type": postType])
}
}else if response.actionIdentifier == "close" {
print("KAPAT")
} else {
if postId != ""{
NotificationCenter.default.post(name: NSNotification.Name("Detail"), object: nil, userInfo: ["id": postId, "type": postType])
}
}
completionHandler()
}
}
您必须添加后台模式 -> 远程通知到您的应用程序功能,以便完全访问委托方法,例如:didReceiveRemoteNotification
。
我建议您将远程 nots 存储在链接到每个 user/device 的后端,并在每次应用程序启动时立即获取它们。只有这样才能保证数据的一致性。
请检查this question。
哈哈。我用异步包装了我的代码,现在运行良好。
if response.actionIdentifier == "read" {
if postId != ""{
DispatchQueue.main.async(execute: {
NotificationCenter.default.post(name: NSNotification.Name("Detail"), object: nil, userInfo: ["id": postId, "type": postType])
})
completionHandler()
}
}else if response.actionIdentifier == "close" {
print("CLOSE")
completionHandler()
} else {
if postId != ""{
DispatchQueue.main.async(execute: {
NotificationCenter.default.post(name: NSNotification.Name("Detail"), object: nil, userInfo: ["id": postId, "type": postType])
})
completionHandler()
}
}