
本文共 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的图标的角上显示一个数字.Sound
app播放声音.Alert
app显示文字
在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至少要包含一个aps
,aps
也是一个字典。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
aps
字典 测试的时候编辑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(_:)
方法
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
字典
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
completion handler
,让系统知道是否有新数据被加载 4.不是silent notification 转载地址:https://windzen.blog.csdn.net/article/details/53924028 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
关于作者
