简体   繁体   English

如何处理 swift 中的推送通知?

[英]How to handle push notification in swift?

I have an ios app where i send push using apns.我有一个 ios 应用程序,我在其中使用 apns 发送推送。 I need to handle push message and if it is correct show the message.我需要处理推送消息,如果正确则显示消息。 How can i realize it in swift?我如何在swift中实现它? This is my code:这是我的代码:

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

func registerForPushNotifications(application: UIApplication) {
    let notificationSettings = UIUserNotificationSettings(
        forTypes: [.Badge, .Sound, .Alert], categories: nil)
    application.registerUserNotificationSettings(notificationSettings)
}

func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
    if notificationSettings.types != .None {
        application.registerForRemoteNotifications()
    }
}

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
    let tokenChars = UnsafePointer<CChar>(deviceToken.bytes)
    var tokenString = ""

    for i in 0..<deviceToken.length {
        tokenString += String(format: "%02.2hhx", arguments: [tokenChars[i]])
    }

    print("Device Token:", tokenString)
}

func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
    print("Failed to register:", error)
}

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {



}

func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {

}

func applicationDidBecomeActive(application: UIApplication) {
    UIApplication.sharedApplication().applicationIconBadgeNumber = 0
}

In what function i can handle push notification there?在什么 function 我可以在那里处理推送通知?

To handle push notifications when arrived in your iOS application is tricky part in order to take their full advantage. 到达你的iOS应用程序时处理推送通知是一个棘手的部分,以充分利用它。

When push notification arrives, your application can be in 当推送通知到达时,您的应用程序可以进入

Closed state – App is killed, Running state – App is in Foreground, Suspended state – App is in Background , 关闭状态 - 应用程序被杀死,运行状态 - 应用程序处于前台,暂停状态 - 应用程序处于后台

Handle push notification when arrived 到达时处理推送通知

Lets discuses one by one how to handle them in each state 让我们逐一讨论如何在每个州处理它们

Closed state: 封闭状态:

When Application is closed (some other app is running or phone is locked), push notification arrived and you tapped on it to open the app. 当应用程序关闭(某些其他应用程序正在运行或手机被锁定)时,推送通知到达,您点击它以打开应用程序。 Control will be given to appDelegate's method ie didFinishLaunchingWithOptions : Please note that when you normally launch the app by taping its icon from your phone. 将对appDelegate's方法进行控制,即didFinishLaunchingWithOptions :请注意,当您通常通过从手机中点按其图标来启动应用程序时。 didFinishLaunchingWithOptions: called first with its launchOptions==nil. didFinishLaunchingWithOptions:首先使用launchOptions == nil调用。 In case you launch the app by clicking received push notifications didFinishLaunchingWithOptions: called with its launchOptions!=nil . 如果您通过单击收到的推送通知启动应用程序,则执行didFinishLaunchingWithOptions:使用其launchOptions!=nil调用。 Here comes the point If you want to do something special when your application is launched upon clicking push notification you need to add code in your didFinishLaunchingWithOptions : 关键点如果你想在点击推送通知启动应用程序时做一些特别的事情,你需要在didFinishLaunchingWithOptions添加代码:

like this 像这样

if (launchOptions != nil)
{
   //do some thing special e.g. display particular ViewController or Set some notification badge value.
}

Running state 运行状态

If your application is running (in foreground) and push notification received, nothing related to that notification will be displayed on screen – no alert, no message, no sound. 如果您的应用程序正在运行(在前台)并且收到推送通知,则屏幕上将不显示与该通知相关的任何内容 - 没有警报,没有消息,没有声音。 Instead following method of appDelegate will be called 而是将调用appDelegate的跟随方法

   func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
}

You can implement this method according to your need that how you want to respond to the notification. 您可以根据需要实现此方法,以便您希望如何响应通知。

Suspended state 暂停状态

If your application is in background (phone is locked or some other app is running) and push notification recieved, notification will be displayed with sound and on clicking that notification app will be launched with following method of appDelegate is called 如果您的应用程序处于后台(手机已锁定或某些其他应用程序正在运行)并且已收到推送通知,则会显示声音通知,并且点击该通知应用程序将启动以下appDelegate方法被调用

    func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
}

Its the same that is called when notification received in Running state. 与在运行状态下收到通知时调用的相同。 Please note that you can always find if your app is awakened from background state in this method by using UIApplication's applicationState property. 请注意,通过使用UIApplication的applicationState属性,您始终可以在此方法中找到您的应用是否从后台状态唤醒。 In this case you can do something special when application is opened from background via push notification. 在这种情况下,您可以通过推送通知从后台打开应用程序时执行一些特殊操作。

As per your problem, 根据你的问题,

You cannot toggle the visibility of the notification once it has been received on the device. 一旦在设备上收到通知,您就无法切换通知的可见性。

This kind of feature/functionality is only possible on Android. 这种功能/功能仅适用于Android。 As on receiving the notification, Android devs can decide whether to render the view or not. 在收到通知时,Android开发人员可以决定是否呈现视图。

So try to control it from the server side. 所以尝试从服务器端控制它。

I would like to give an example about handling remote push notifications.我想举一个关于处理远程推送通知的例子。
All will be in AppDelegate.swift file;所有将在 AppDelegate.swift 文件中;

First of all get your token after registration from this function to can send Remote Push Notifications (RPM) from your servers or provider:首先从这个 function 注册后获取您的令牌,以便可以从您的服务器或提供商发送远程推送通知 (RPM):

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    
    // Send device token that accepted to retrieve remote notifications to server
    let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
    NSLog("APNs registration success, device token: \(token)")
}

Check remote notification info is exist in launch options inside didFinishLaunchWithOptions method to know did app launched by tapping notification alert like this:检查didFinishLaunchWithOptions方法中的启动选项中是否存在远程通知信息,以了解是否通过点击通知警报启动了应用程序,如下所示:

// Check if there any user info about remote notifications in 'launchOptions'
        /// Get user your data from userInfo dictionary if you need
    if let userInfo = launchOptions?[.remoteNotification] as? [String: AnyObject],
          let exmplValue = userInfo["yourValue"] as? String {
        NSLog("[AppDelegate] - Info: App launched by tapping notification alert. We have new value: \(exmplValue)")
       /// Here you can change rootVC or storing some values to process it in your mainVC etc.
    }

Then implement didReceiveRemoteNotification function like in below to handle push notifications in both state active and inactive:然后像下面那样实现didReceiveRemoteNotification function 以处理 state 活动和非活动中的推送通知:

/// This function made for handling push notifications when app running (both states active or inactive)
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
    
    /// Hide badge number if it exist
    application.applicationIconBadgeNumber = 0
    
    /// Get user your data from userInfo dictionary if you need
    guard let aps = userInfo["aps"] as? [String: Any],
          let alert = aps["alert"] as? [String: Any],
          let title = alert["title"] as? String,
          let body = alert["body"] as? String,
          let exampleValue = userInfo["example"] as? String else {
        NSLog("[AppDelegate] - Warning: user info missing aps or other data.")
        return
    }
    
   /// Check current application state
   if UIApplication.shared.applicationState == .active {
      // Your app in foreground, you can ask user to want to take action about what you want to do.
   } else {
      // Your app in background at most in inactive mode, user when taps on notification alert app will become active so you can do whatever you want directly
   }
}

Bonus:奖金:
Implement UNUserNotificationCenterDelegate in your AppDelegate.swift file then inside didFinishLaunchWithOptions confirm to delegate of notification center like this: UNUserNotificationCenter.current().delegate = self Finally override this function to adjusting badge, sound, alert of notification that will present.在您的 AppDelegate.swift 文件中实施UNUserNotificationCenterDelegate ,然后在didFinishLaunchWithOptions确认通知中心的委托,如下所示: UNUserNotificationCenter.current().delegate = self最后覆盖此 function 以调整将出现的通知的徽章、声音和警报。

    // Assign delegate to show LPN or RPN badge, alert, sound
func userNotificationCenter(_ center: UNUserNotificationCenter,
                            willPresent notification: UNNotification,
                            withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

    /// I would like to notify user by sound only when app is active
    /// otherwise show notification (alert, badge, sound)
    if UIApplication.shared.applicationState == .active {
        completionHandler(.sound)
    } else {
        completionHandler([.alert, .badge, .sound])
    }
    
}

Please remember in these examples i don't implemented silent (background) notifications because of when i activate silent notifications my app handling all type of notifications inside below function and i cannot understand my app launched by tapping RPM or something else, briefly am not familiar with this case so if you need it you must add background modes capability and check Remote Notifications in your Targets -> Your App -> Signing& Capabilities, then implement this function to handle RPM:请记住,在这些示例中,我没有实施静默(后台)通知,因为当我激活静默通知时,我的应用程序处理 function 以下的所有类型的通知,我无法理解我的应用程序是通过点击 RPM 或其他方式启动的,暂时不熟悉对于这种情况,如果您需要它,您必须添加后台模式功能并在您的目标中检查远程通知 -> 您的应用程序 -> 签名和功能,然后实施此 function 来处理 RPM:

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    <#code#>
}

Happy coding快乐编码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM