为啥我在 Swift5 中收不到推送消息?
Posted
技术标签:
【中文标题】为啥我在 Swift5 中收不到推送消息?【英文标题】:Why can't I get a push message in Swift5?为什么我在 Swift5 中收不到推送消息? 【发布时间】:2019-09-24 10:40:03 【问题描述】:我目前正在尝试获取推送消息。但是,您无法收到推送消息。我错过了什么?
AppDelegate
import UIKit
import UserNotifications
import Firebase
import FirebaseMessaging
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
self.window = UIWindow(frame: UIScreen.main.bounds)
// Override point for customization after application launch.
//create the notificationCenter
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()
FirebaseApp.configure()
Messaging.messaging().delegate = self
return true
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
let token = deviceToken.map String(format: "%02x", $0) .joined()
Log.Info("Registration succeeded!")
Log.Info("Token: \(token)")
LocalStorage.set(token, "dacDeviceToken")
Messaging.messaging().apnsToken = deviceToken
InstanceID.instanceID().instanceID (result, error) in
if let error = error
Log.Error("Error fetching remote instance ID: \(error)")
else if let result = result
Log.Info("Remote instance ID token: \(result.token)")
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error)
Log.Warning("Registration failed!")
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any])
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
// With swizzling disabled you must let Messaging know about the message, for Analytics
// Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
if let messageID = userInfo["gcmMessageIDKey"]
Log.Info("Message ID: \(messageID)")
// Print full message.
Log.Info(userInfo)
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)
// If you are receiving a notification message while your app is in the background,
// this callback will not be fired till the user taps on the notification launching the application.
// TODO: Handle data of notification
// With swizzling disabled you must let Messaging know about the message, for Analytics
// Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
if let messageID = userInfo["gcmMessageIDKey"]
Log.Info("Message ID: \(messageID)")
// Print full message.
Log.Info(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
func applicationWillResignActive(_ application: UIApplication)
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
func applicationDidEnterBackground(_ application: UIApplication)
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
func applicationWillEnterForeground(_ application: UIApplication)
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
func applicationDidBecomeActive(_ application: UIApplication)
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
func applicationWillTerminate(_ application: UIApplication)
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
func getNotificationSettings()
UNUserNotificationCenter.current().getNotificationSettings settings in
print("Notification settings: \(settings)")
guard settings.authorizationStatus == .authorized else return
DispatchQueue.main.async
UIApplication.shared.registerForRemoteNotifications()
@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
// Print message ID.
Log.Info("Message ID: \(userInfo["gcm.message_id"]!)")
// Print full message.
print("%@", userInfo)
Log.Info(userInfo)
extension AppDelegate : MessagingDelegate
// Receive data message on iOS 10 devices.
func applicationReceivedRemoteMessage(_ remoteMessage: MessagingRemoteMessage)
print("%@", remoteMessage.appData)
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String)
Log.Info("Firebase registration token: \(fcmToken)")
let dataDict:[String: String] = ["token": fcmToken]
NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
// TODO: If necessary send token to application server.
// Note: This callback is fired at each app startup and whenever a new token is generated.
我的日志
2019-09-24 19:31:46.519806+0900 测试[586:74065] -
[I-ACS036002] 分析屏幕报告已启用。
调用+[FIRAnalytics setScreenName:setScreenClass:]设置屏幕
name 或覆盖默认的屏幕类名称。禁用屏幕
报告,将标志 FirebaseScreenReportingEnabled 设置为 NO(布尔值)
在 Info.plist 2019-09-24 19:31:46.756433+0900 测试[586:74071]
6.9.0 - [Firebase/Messaging][I-FCM001000] FIRMessaging 远程通知代理已启用,将调整远程通知接收器
处理程序。如果您希望手动集成 Firebase 消息传递,
将“FirebaseAppDelegateProxyEnabled”添加到您的 Info.plist,并设置它
到NO。按照以下说明操作:
以确保正确集成。 2019-09-24 19:31:46.759687+0900
测试[586:74071] 6.9.0 - [Firebase/Analytics][I-ACS023007] 分析 v.60102000 开始于 2019-09-24 19:31:46.760699+0900 测试[586:74071] 6.9.0 - [Firebase/Analytics][I-ACS023008] 要启用调试日志记录,请设置以下应用程序参数:-FIRAnalyticsDebugEnabled 信息:2019-09-24 10:31:46 +0000 - AppDelegate.swift 消息传递(_:didReceiveRegistrationToken:) [Line:196]
Firebase 注册令牌: dZ4US-5dJqk:APA91bF0-**************** 信息:2019-09-24 10:31:46 +0000 - AppDelegate.swift 应用程序(_:didRegisterForRemoteNotificationsWithDeviceToken :) [Line:82] 注册成功!信息:2019-09-24 10:31:46 +0000 - AppDelegate.swift
应用程序(:didRegisterForRemoteNotificationsWithDeviceToken:) [行:83] 令牌: 213eba827****************************** 信息: 2019-09-24 10:31:46 +0000 - AppDelegate.swift 应用程序(:didRegisterForRemoteNotificationsWithDeviceToken:) [Line:90] 远程实例 ID 令牌: dZ4US-5dJqk:APA91bF0-77***********
2019-09-24 19:31:46.921546+0900 测试[586:74071] [MC] 系统组 systemgroup.com.apple.configurationprofiles 路径的容器是 /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles 2019-09-24 19:31:46.923537+0900 测试[586:74071] [MC] 从 公开有效的用户设置。
发送测试 FCM
我什么也得不到。我的应用无论是在前台还是在后台都不会收到推送消息。
请多多帮助我。
你在图中添加的token就是设备token值。令牌值在日志中可见。
编辑
我看到了答案并跟着它,但它不起作用。
【问题讨论】:
【参考方案1】:你能把 GoogleService-Info.plist 文件放到你的项目中吗?
在我的代码中尝试这个 100% 工作
import Firebase
import FirebaseCore
import FirebaseMessaging
import UserNotifications
import UserNotificationsUI
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate , MessagingDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
Messaging.messaging().delegate = self
FirebaseApp.configure()
//Register App For Push Notification
self.registerAppForPushNotificaition()
application.registerForRemoteNotifications()
return true
func registerAppForPushNotificaition()
if #available(iOS 10.0, *)
let center = UNUserNotificationCenter.current()
let inviteCategory = UNNotificationCategory(identifier: "Notification", actions: [], intentIdentifiers: [], options: UNNotificationCategoryOptions.customDismissAction)
let categories = NSSet(objects: inviteCategory)
center.delegate = self
center.setNotificationCategories(categories as! Set<UNNotificationCategory>)
center.requestAuthorization(options: [.sound, .badge, .alert], completionHandler: (granted, error) in
if !(error != nil)
DispatchQueue.main.async(execute:
UIApplication.shared.registerForRemoteNotifications()
)
)
else
UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types:[.sound , .alert , .badge] , categories: nil))
UIApplication.shared.registerForRemoteNotifications()
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
completionHandler(.alert)
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
Auth.auth().setAPNSToken(deviceToken, type: AuthAPNSTokenType.sandbox)
Messaging.messaging().apnsToken = deviceToken
let token = InstanceID.instanceID().token()
if token != nil
fcmID = token!
func application(application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData)
Messaging.messaging().apnsToken = deviceToken as Data
// print(deviceToken)
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error)
NSLog("Failed to get Access Token: \(error)")
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)
if Auth.auth().canHandleNotification(userInfo)
completionHandler(UIBackgroundFetchResult.noData)
return
completionHandler(UIBackgroundFetchResult.newData)
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String)
print("fcmToken \(fcmToken)")
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage)
print("remort \(remoteMessage.appData)")
【讨论】:
请看我编辑的问题。该文件已添加。 我应该将它添加到函数的顶部吗?【参考方案2】:我看到了答案并按照它,但它不起作用。但是,当你在Fire Base上添加了一个新项目,再次添加了iOS应用,试了试,就成功了。我不确定出了什么问题。那是我的代码有问题吗?我想,但是当我在问题中使用代码时,它也起作用了。我只是为我的解决方案创建并添加了一个新项目。
【讨论】:
以上是关于为啥我在 Swift5 中收不到推送消息?的主要内容,如果未能解决你的问题,请参考以下文章