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

本文共 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月07日 17时54分56秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

linux 小数四则运行,shell四则运算(整数及浮点数)的方法介绍 2019-04-21
linux系统分区后进入紧急模式,Linux系统的救援模式应用详解 2019-04-21
linux配置匿名ftp服务器,在Linux环境中使用vsftpd搭建ftp实现匿名上传详细配置 2019-04-21
linux创建硬盘分区lvm,LVM创建及分区调整、更换LVM硬盘 2019-04-21
FreeBSD可以安装Linux软件吗,在Linux服务器上面通过网络安装FreeBSD 2019-04-21
.net core linux 桌面应用,C# dotnet core + AvaloniaUI 开发桌面软件,hello world 2019-04-21
linux tcp 113错误,linux系统报tcp_mark_head_lost错误的处理方法 2019-04-21
南昌工程学院c语言答案,南昌工程学院C语言程序设计基础课件第3讲运算符和表达式... 2019-04-21
python学画画_python学画画(下) 2019-04-21
云栖社区 mysql_【直播结束,已更新回放】PG、MySQL到底哪个好?云栖说这次请来五位专家撕了一下-阿里云开发者社区... 2019-04-21
老男孩mysql 百度云_英语语录:除了你,没人能掌控你的幸福 2019-04-21
mysql驱动多次执行问题_Laravel5.2队列驱动expire参数设置带来的重复执行问题 数据库驱动... 2019-04-21
mysql获取刚新增的数据库_如何取得刚插入数据库的数据的id mysql 2019-04-21
python将10到1递减_(Python)如何将3个递减列表合并成一个递减列表? 2019-04-21
python脚本怎么用来处理数据_长时间运行数据处理python脚本的程序结构 2019-04-21
python转成c 语言_将Python对象转换为C void类型 2019-04-21
resin mysql_Eclipse+resin+mysql 安装及环境配置 2019-04-21
redis的使用 Java_java中使用redis 2019-04-21
java 数组元素位置_Java – 在数组中获取元素位置 2019-04-21
c 泛型与java泛型_C ++和Java中的“泛型”类型之间有什么区别? 2019-04-21