如何在 iOS (Swift4) 上后台使用 FCM 获取推送通知



如何在后台获取推送通知?我在 Swift4 iOS 11 中遇到了一个问题,其中包含 FCM 的推送通知,只有在打开应用程序时才能在后台检索通知。

这是我的编码:

应用委托.swift

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {

var window: UIWindow?
static var DEVICE_ID = String()

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

UIApplication.shared.statusBarStyle = .lightContent

FirebaseApp.configure()

if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self

UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound], completionHandler: { (success, error) in
print(success)
})

Messaging.messaging().delegate = self

} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}

application.registerForRemoteNotifications()

return true
}

func connectToFcm() {
Messaging.messaging().shouldEstablishDirectChannel = true

if let token = InstanceID.instanceID().token() {
AppDelegate.DEVICE_ID = token
print("*********")
print("Token Instance: (token)")
print("*********")
}
}

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

completionHandler([.alert, .sound])

}

func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
connectToFcm()
}

func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {

guard let data: [String: Any] = remoteMessage.appData as? [String: Any] else {
return
}

print(data)


}

func applicationDidBecomeActive(_ application: UIApplication) {
UIApplication.shared.applicationIconBadgeNumber = 0
connectToFcm()
}

func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {


completionHandler(.newData)

}


}

示例:使用邮递员发送推送通知的图像

AppDelegate 中的以下源代码.swift:

import UIKit
import UserNotifications
import FirebaseCore
import FirebaseMessaging
import FirebaseInstanceID
struct DataNotif: Codable {
var title: String?
var body: String?
private enum CodingKeys: String, CodingKey {
case title
case body
}
}
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {
var window: UIWindow?
let gcmMessageIDKey = "message_id"
static var DEVICE_ID = String()
var msg_body = ""
var msg_title = ""
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UIApplication.shared.statusBarStyle = .lightContent
FirebaseApp.configure()
Messaging.messaging().delegate = self
if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
return true
}
func connectToFcm() {
Messaging.messaging().shouldEstablishDirectChannel = true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
if let refreshedToken = InstanceID.instanceID().token() {
AppDelegate.DEVICE_ID = refreshedToken
print("*********")
print("InstanceID token: (refreshedToken)")
print("*********")
}else{
print("Can't get token device")
}
connectToFcm()
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Failed to register for remote notifications with error: (error)")
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print(userInfo)
guard let data: [String: Any] = userInfo as? [String: Any] else {
return
}
let listData = data["notification"] as! String
let jsonData = listData.data(using: .utf8)
do {
let decoder = JSONDecoder()
let dataJson = try decoder.decode(DataNotif.self, from: jsonData!)
msg_body = dataJson.body!
msg_title = dataJson.title!
createNotification(title: msg_title, body: msg_body)
}catch{
print("error")
}
completionHandler(.newData)
}
// messaging
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
if let token = InstanceID.instanceID().token() {
AppDelegate.DEVICE_ID = token
print("*********")
print("Token Instance: (token)")
print("*********")
}
connectToFcm()
}
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
print("Received data message: (remoteMessage.appData)")
guard let data: [String: Any] = remoteMessage.appData as? [String: Any] else {
return
}
print(data)
let listData = data["notification"] as! String
let jsonData = listData.data(using: .utf8)
do {
let decoder = JSONDecoder()
let dataJson = try decoder.decode(DataNotif.self, from: jsonData!)
msg_body = dataJson.body!
msg_title = dataJson.title!
createNotification(title: msg_title, body: msg_body)
}catch{
print("error")
}
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .badge, .sound])
}
func applicationDidBecomeActive(_ application: UIApplication) {
UIApplication.shared.applicationIconBadgeNumber = 0
connectToFcm()
}
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if let vc = window?.rootViewController as? HomeController {
vc.scheduleNotification()
}
completionHandler(.newData)
}
func applicationDidEnterBackground(_ application: UIApplication) {
Messaging.messaging().shouldEstablishDirectChannel = false
print("Disconnect FCM")
}
func createNotification(title: String, body: String) {
let content = UNMutableNotificationContent()
content.title = NSString.localizedUserNotificationString(forKey: title, arguments: nil)
content.body = NSString.localizedUserNotificationString(forKey: body, arguments: nil)
content.sound = UNNotificationSound.default()
content.badge = NSNumber(integerLiteral: UIApplication.shared.applicationIconBadgeNumber + 1)
let request = UNNotificationRequest.init(identifier: "pushNotif", content: content, trigger: nil)
let center = UNUserNotificationCenter.current()
center.add(request)
}
}

Firebase 为推送通知提供后台和前台支持。您可以通过以下步骤轻松解决问题:

在应用委托中.swift导入 Firebase 库

import Firebase
import FirebaseInstanceID
import FirebaseMessaging
import UserNotifications

每当应用程序启动注册推送通知服务时,请将以下代码行添加到您的 didFinishLaunchingWithOptions 中

func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
registerForPushNotifications(application: application)
return true
}

添加 appDelegate 的扩展方法,以注册远程通知并从 APNS 获取设备令牌

extension AppDelegate {
func registerForPushNotifications(application: UIApplication) {
if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
// For iOS 10 data message (sent via FCM
Messaging.messaging().delegate = self
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
let savedAPNSToken = UserDefaults.standard.object(forKey: "savedAPNSToken") as? String
if savedAPNSToken != token {
UserDefaults.standard.set(token, forKey: "savedAPNSToken")
UserDefaults.standard.synchronize()
Messaging.messaging().apnsToken = deviceToken
}
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print(error.localizedDescription)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
completionHandler(UIBackgroundFetchResult.newData)
}
}

使用以下通知中心方法处理前台和后台状态中的通知:

// MARK: - UNUserNotificationCenterDelegate
@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {
// Receive displayed notifications for iOS 10 devices.
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
completionHandler([.alert])
}

/// Handle tap on the notification banner
///
/// - Parameters:
///   - center: Notification Center
///   - response: Notification response
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
completionHandler()
}

Firebase 令牌续订:

// MARK: - MessagingDelegate
extension AppDelegate : MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
// Note: This callback is fired at each app startup and whenever a new token is generated.
let savedFCMToken = UserDefaults.standard.object(forKey: "savedFCMToken") as? String
if savedFCMToken != fcmToken {
UserDefaults.standard.set(fcmToken, forKey: "savedFCMToken")
UserDefaults.standard.synchronize()
// Update FCMToken to server by doing API call...
}
}
}

我无法在您的代码中找到问题,但我正在发布应该如何完成的步骤:-

  1. 注册推送通知

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    

    FirebaseApp.configure(( self.registerForPushNotifications(application( 返回真值 } func registerForPushNotifications(_ application: UIApplication({ Messaging.messaging((.delegate = self 如果 #available(iOS 10, *( {

    let center = UNUserNotificationCenter.current()
    center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
    // Enable or disable features based on authorization.
    }
    center.delegate=self
    application.registerForRemoteNotifications()
    }
    else{
    let settings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
    application.registerUserNotificationSettings(settings)
    application.registerForRemoteNotifications()
    }
    }
    

2.然后处理您的 didRegisterForRemoteNotificationsWithDeviceToken 委托:-

func application(_ application: UIApplication, 
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
}
  1. 处理您的 Firebase 消息代理:-

    扩展 AppDelegate: MessagingDelegate { func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String( {

    let token = fcmToken
    // you can send your token to Server, from where you'll get the Push Notification
    
    }
    

    }

4.然后处理您的联合国大学通知中心代表:-

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
// this is called when application is Foreground and push arrives we show alert, sound, here.
completionHandler([.alert, .sound])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Swift.Void){
let pushDictionary = response.notification.request.content.userInfo
// handle your push here
}

最新更新