在 Swift iOS 中推送通知

Posted

技术标签:

【中文标题】在 Swift iOS 中推送通知【英文标题】:Push notifications in Swift iOS 【发布时间】:2017-03-23 07:08:14 【问题描述】:

我正在使用 ios Swift 通知模块。我没有在设备上收到警报/横幅通知。

当应用程序打开(即在前台)时,我能够收到通知,但在应用程序处于后台或终止时不会收到通知。

以下是我的代码

import UIKit

import UserNotifications

import Firebase

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, FIRMessagingDelegate 

    var window: UIWindow?

    //  MARK: - Application Life Cycle
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 
        // Override point for customization after application launch.

        FIRApp.configure()

        askNotificationPermission(application)

        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.firInstanceIDTokenRefresh, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(self.getFirebaseInstaceID(_:)), name: NSNotification.Name.firInstanceIDTokenRefresh, object: nil)

        connectToFcm()

        return true
    

    // MARK:- Push Notification Delegate Methods
    @nonobjc func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) 
        FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.sandbox)
    

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) 
        print(error)
    

    func applicationReceivedRemoteMessage(_ remoteMessage: FIRMessagingRemoteMessage) 
        let appdata = remoteMessage.appData as NSDictionary as! [String: AnyObject]
        print(appdata)
    

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) 
        print(userInfo)
    

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) 
        print(userInfo)
        completionHandler(UIBackgroundFetchResult.newData)
    

    // Receive displayed notifications for iOS 10 devices.
    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) 

        let userInfo = notification.request.content.userInfo
        print("Message ID: \(userInfo["gcm.message_id"]!)")
        print("%@", userInfo)
    

    //  MARK: - Permissions
    func askNotificationPermission(_ application: UIApplication) 
        if #available(iOS 10.0, *) 

            let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
            UNUserNotificationCenter.current().requestAuthorization(options: authOptions, completionHandler:  (finished, error) in

            )

            UNUserNotificationCenter.current().delegate = self

            FIRMessaging.messaging().remoteMessageDelegate = self

         else 

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

        application.registerForRemoteNotifications()
    

    //  MARK: - Firebase Connection Methods
    @objc func getFirebaseInstaceID(_ notification: Notification) 

        if isNotNull(FIRInstanceID.instanceID().token() as AnyObject?) 
            let strFirebaseInstanceID = FIRInstanceID.instanceID().token()! as String
            if !strFirebaseInstanceID.isEmpty 
                print("Firebase Instance ID - \(strFirebaseInstanceID)")
                setString(strValue: strFirebaseInstanceID, forKey: Default.firebaseInstanceID)

                NotificationCenter.default.post(name: Notification.Name(rawValue: Notifications.nSendFirebaseID), object: nil)
             else 
                setString(strValue: "", forKey: Default.firebaseInstanceID)
            
         else 
            setString(strValue: "", forKey: Default.firebaseInstanceID)
        

        connectToFcm()
    

    func connectToFcm() 
        FIRMessaging.messaging().connect  (error) in
            if (error != nil) 
                print("Unable to connect with FCM. \(error)")
             else 
                print("Connected to FCM.")
            
        
    

【问题讨论】:

您能分享一下您发送的有效载荷吗? 你在什么操作系统上遇到这个问题? @Karthick 我在 iOS 10.1 中遇到了这个问题 刚刚在其中一个答案中看到了您的评论。您能否发布您使用通知控制台发送的示例消息的屏幕截图? (删除敏感细节 亲爱的@VaibhavJhaveri,我们已将您的更改回滚到与社区编辑选择更加同步的版本。如果您有疑虑,我建议您重新阅读 help pages 或特别是 "how-to-ask"。您也可以在 Meta 上搜索并最终在 Meta 上提出问题。 【参考方案1】:

对于 iOS 10.*,您需要在下面的 willPresent notification 方法列表的完成处理程序中提供推送通知呈现选项。尝试这样可能会有所帮助。

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

        completionHandler([.alert, .badge, .sound])


谢谢。

【讨论】:

试过了。没有帮助【参考方案2】:

当您使用 FCM 发送推送时,请尝试将此有效负载发送到 FCM 进行推送。


  "to": "<REGISTRATION_TOKEN_HERE>",
  "notification": 
    "body": "Yipeee!!! I nailed it",
    "sound" : "default"
  ,
  "data" : ""

【讨论】:

我正在使用 Firebase 控制台发送通知 我没有尝试使用控制台发送推送,但我使用 googleapi 的 Using post request,网址为 https://gcm-http.googleapis.com/gcm/send 和标题 Authorization:key=yourKey Content-Type:application/json @TechGeek_iOS https://gcm-http.googleapis.com/gcm/send 是 GCM 端点。尽管两者仍然兼容,但对于 FCM,请尽可能使用 https://fcm.googleapis.com/fcm/send。 :) 另外,我注意到你的格式——"to": "FCM_INSTANCE_ID/GCM_ID_GOES_HERE"。在那里包含GCM_ID 是没有意义的(我什至不确定GCM_ID 是什么意思。 FCM_INSTANCE_ID 为 FIRInstanceID.instanceID().token,为每个设备生成【参考方案3】:

我忘了添加这个方法

didReceiveRemoteNotification

【讨论】:

以上是关于在 Swift iOS 中推送通知的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中推送 iOS8 的通知状态

如何在前台 iOS Swift 3.0 中接收推送通知?

当用户使用 iOS 13 Swift 5 点击推送通知时,在特定视图中打开应用程序

Swift iOS 10 的推送通知

如何使用swift为IOS推送通知打开新的WebView

ios swift使用啥推送通知? [关闭]