iOS远程通知相关
发布日期:2022-03-18 08:27:46 浏览次数:23 分类:技术文章

本文共 7735 字,大约阅读时间需要 25 分钟。

iOS远程通知相关

iOS APNs Auth Key

使用APNs Auth Key的好处:

  • 不用每年重新生成证书
  • One auth key can be used for all your apps – this avoids the complication of maintaining different certificates

具体配置可参考:


在iOS10中引入了UserNotifications.framework来集中管理通知,使用方式有点变化,可参考


参考

发送和接收远程通知主要有三个方面的内容:

1.app必须合理的配置,注册Apple Push Notification Service (APNS)
2.server发送push notification给APNS
3.app接收push notification,可以来执行一些特定的任务或者在application的代理的回调中处理用户的action

配置Push Notifications

启用Push Notification Service
App Settings -> Capabilities打开Push Notifications

这里写图片描述

注册Push Notifications

注册Push Notifications有两步:

1.获得用户的许可
2.系统会提供device token,可以把它作为device的地址

如下注册Push Notification

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

UIUserNotificationSettings用来存储app通知的设置

  • .Badge在app的图标的角上显示一个数字
  • .Soundapp播放声音
  • .Alertapp显示文字

application(_:didFinishLaunchingWithOptions:launchOptions:)中调用registerForPushNotifications(_:)

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

在弹出请求运行发送通知的提示框后,用户可选择接受或者拒绝。当用户做出选择后,UIApplicationDelegate的代理方法会被调用:

func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) { }

这个方法里的UIUserNotificationSettings不同于上面传的那个。

It’s extremely important to call registerUserNotificationSettings(_:) every time the app launches. This is because the user can, at any time, go into the Settings app and change the notification permissions. application(_:didRegisterUserNotificationSettings:) will always provide you with what permissions the user currently has allowed for your app.

现在就可以在application(_:didRegisterUserNotificationSettings:)中注册远程通知了:

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

之后,UIApplicationDelegate中方法会被调用,来告诉你registerForRemoteNotifications()的状态

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {  let tokenChars = UnsafePointer
(deviceToken.bytes) var tokenString = "" for i in 0..

如上所示,注册成功时调用application(_:didRegisterForRemoteNotificationsWithDeviceToken:),否则的话调用application(_:didFailToRegisterForRemoteNotificationsWithError:)

当前的application(_:didRegisterForRemoteNotificationsWithDeviceToken:) 方法实现中,只是把deviceToken转为一个字符串。可能结果如下:

这里写图片描述

创建SSL Certificate 和 PEM file

这里写图片描述

可能出现的问题

Some notifications received but not all: If you’re sending multiple push notifications simultaneously and only a few are received, fear not! That is intended behaviour. APNS maintains a QoS (Quality of Service) queue for each device with a push app. The size of this queue is 1, so if you send multiple notifications, the last notification is overridden.

Problem connecting to Push Notification Service: One possibility could be that there is a firewall blocking the ports used by APNS. Make sure you unblock these ports. Another possibility might be that the private key and CSR file are wrong. Remember that each App ID has a unique CSR and private key combination.

Push Notification的基本结构

在这个例子中,payload大概如下:

{  "aps":  {    "alert": "Breaking News!",    "sound": "default"    "link_url" : "https://raywenderlich.com,  }}

payload至少要包含一个apsaps也是一个字典。link_url是一个自定义的字段。在aps中可以添加5个key:

  • alert 可以是字符串或者字典,参考
  • badge 可以把它设为0来移除
  • sound 通过这个key,可以播放自定义的通知声音。自定义的通知声音必须短于30s,和一些其它限制,参考
  • content-available By setting this key to 1, the push notification becomes a silent one.
  • category 展示自定义的action

除此之外,你还可以添加其它自定义的数据,只要payload的大小不超过4096bytes。

处理Push Notifications

当app接收到了一个push notification,UIApplicationDelegate的一个方法将会被调用,要分不同的情况:

  • app没有运行,用户点击push notification,加载app,push notification会被传入application(_:didFinishLaunchingWithOptions:)方法的launchOptions
  • 如果app运行在前台,push notification不会展示,application(_:didReceiveRemoteNotification:) 会被调用
  • 如果app在运行,在后台被挂起,用户点击push notification,app进入前台,application(_:didReceiveRemoteNotification:) 会被调用

在第一种情况下application(_:didFinishLaunchingWithOptions:)方法中可以添加如下的代码:

// Check if launched from notification// 1if let notification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? [String: AnyObject] {  // 2  let aps = notification["aps"] as! [String: AnyObject]  createNewNewsItem(aps)  // 3  (window?.rootViewController as? UITabBarController)?.selectedIndex = 1}

上面的代码处理:

1.检查UIApplicationLaunchOptionsRemoteNotificationKey的value,是否存在,如果存在,就可以获取到发送的push notification payload

2.如果存在,获取aps字典

测试的时候编辑Scheme

编辑Scheme

Run -> Info下,选择Wait for executable to be launched

这里写图片描述

其它2种情况,在AppDelegate中添加如下的代码:

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {  let aps = userInfo["aps"] as! [String: AnyObject]  createNewNewsItem(aps)}

Actionable Notifications

可操作通知可以添加自定义的button到notification。你可能已近注意到了,在email通知中,有“reply” 或者 “favorite”的选项。

在定义actionable Notifications时,需要使用categories

修改registerForPushNotifications(_:)方法

1.创建一个新的notification action,title设为"View",当触发的时候会进入前台

let viewAction = UIMutableUserNotificationAction()viewAction.identifier = "VIEW_IDENTIFIER"viewAction.title = "View"viewAction.activationMode = .Foreground

action有个VIEW_IDENTIFIER标识符,用来区别不同的actions。

2.创建category

let newsCategory = UIMutableUserNotificationCategory()newsCategory.identifier = "NEWS_CATEGORY"newsCategory.setActions([viewAction], forContext: .Default)

NEWS_CATEGORY这个标识符,就是payload中要包含的,表示push notification属于这个category

3.构建UIUserNotificationSettings

let notificationSettings = UIUserNotificationSettings(forTypes: [.Badge, .Sound, .Alert], categories: [newsCategory])

4.修改通知体payload,要包含category

$body['aps'] = array(  'alert' => $message,  'sound' => 'default',  'link_url' => $url,  'category' => 'NEWS_CATEGORY',  );

点击的时候会加载app,但是并不会做其它的事情,还需要在代理中处理

这里写图片描述

处理Action

AppDelegate中,添加如下的方法:

func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [NSObject : AnyObject], completionHandler: () -> Void) {  // 1  let aps = userInfo["aps"] as! [String: AnyObject]   // 2  if let newsItem = createNewNewsItem(aps) {    (window?.rootViewController as? UITabBarController)?.selectedIndex = 1     // 3    if identifier == "VIEW_IDENTIFIER", let url = NSURL(string: newsItem.link) {      let safari = SFSafariViewController(URL: url)      window?.rootViewController?.presentViewController(safari, animated: true, completion: nil)    }  }   // 4  completionHandler()}

1.获取aps字典

2.创建NewsItem,然后进入新的section
3.检查action identifier,如果有url,就弹出一个SFSafariViewController
4.调用回调方法

Silent Push Notifications

Silent push notification可以唤醒app,并在后台执行一些任务。

a.在App Settings -> Capabilities中,打开Background Modes,勾上Remote Notifications

这里写图片描述

b.替换application(_:didReceiveRemoteNotification:)中的内容

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {  let aps = userInfo["aps"] as! [String: AnyObject]   // 1  if (aps["content-available"] as? NSString)?.integerValue == 1 {    // Refresh Podcast    // 2    let podcastStore = PodcastStore.sharedStore    podcastStore.refreshItems { didLoadNewItems in      // 3      completionHandler(didLoadNewItems ? .NewData : .NoData)    }  } else  {    // News    // 4    createNewNewsItem(aps)    completionHandler(.NewData)  }}

1.检查content-available是否为1,为1表示是silent notification

2.刷星podcast列表
3.列表被刷新后,调用completion handler,让系统知道是否有新数据被加载
4.不是silent notification

转载地址:https://windzen.blog.csdn.net/article/details/53924028 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:iOS自定义控件三
下一篇:iOS开发者账号相关

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2024年03月22日 06时43分23秒