2121
2222这里 Provider 是指某个应用的 Developer,当然如果开发者使用 LeanCloud 的服务,把发送消息的请求委托给我们,那么这里的 Provider 就是 LeanCloud 的推送服务程序了。上图 ">
2323< meta property ="og:image " content ="https://dn-yuankeqiang.qbox.me/remote_notif_simple_2x.png ">
24- < meta property ="og:updated_time " content ="2015-11-26T08:25:56 .000Z ">
24+ < meta property ="og:updated_time " content ="2015-11-26T08:35:45 .000Z ">
2525< meta name ="twitter:card " content ="summary ">
2626< meta name ="twitter:title " content ="细说iOS消息推送 ">
2727< meta name ="twitter:description " content ="[转载自leancloud]
@@ -261,8 +261,7 @@ <h3 id="APNs_的推送机制">APNs 的推送机制</h3><p>与 Android 上我们
261261< span class ="number "> 3.</ span > 应用将 DeviceToken 保存起来,这里就是通过 [AVInstallation saveInBackground] 将 DeviceToken 保存到 LeanCloud;
262262< span class ="number "> 4.</ span > 当某些特定事件发生,开发者委托 LeanCloud 来发送推送消息,这时候 LeanCloud 的推送服务器就会给 APNs 发送一则推送消息,APNs 最后消息送到用户设备。
263263</ code > </ pre > < p > < a href ="https://dn-yuankeqiang.qbox.me/registration_sequence_2x.png " target ="_blank " rel ="external "> leancloud</ a > </ p >
264- < p > ###推送相关的几个概念 </ p >
265- < h4 id ="消息类型 "> 消息类型</ h4 > < p > 一条消息推送过来,可以有如下几种表现形式: </ p >
264+ < h3 id ="推送相关的几个概念 "> 推送相关的几个概念</ h3 > < h4 id ="消息类型 "> 消息类型</ h4 > < p > 一条消息推送过来,可以有如下几种表现形式: </ p >
266265< ul >
267266< li > 显示一个 alert 或者 banner,展现具体内容。 </ li >
268267< li > 在应用 icon 上提示一个新到消息数。 </ li >
@@ -282,12 +281,12 @@ <h4 id="代码里面如何实现推送">代码里面如何实现推送</h4><p>
282281< p > 请注意,注册流程需要在应用每次启动时调用,这并不不会带来额外的负担,因为 iOS 操作系统在第一次获得了有效的 device token 之后,会本地缓存起来,以后应用再调用 registerForRemoteNotificationTypes: 的时候会立刻返回,并不会再进行网络请求。另外,应用层面不应该对 device token 进行缓存,因为 device token 也有可能变化——如果用户重装了操作系统,那么 APNs 再次给出的 device token 就会和之前的不一样,又或者是,用户 恢复了原来的备份到新的设备上,那么原来的 device token 也会失效。 </ p >
283282< p > 其次,我们要处理收到消息之后的回调。 </ p >
284283< p > 我们可以设想一下消息通知的几种使用场景: </ p >
285- < ol >
286- < li > 在应用没有被启动的时候,接收到了消息通知。这时候操作系统会按照默认的方式来展现一个 alert 消息,在应用的 icon 上标记一个数字,甚至播放一段声音。 </ li >
287- < li > 用户看到消息之后,点击了一下 action 按钮或者点击了应用图标。如果 action 按钮被点击了,系统会通过调用 application:didFinishLaunchingWithOptions: 这个代理方法来启动应用,并且会把 notification 的 payload 数据传递进去。如果应用图标被点击了,系统也一样会调用 application:didFinishLaunchingWithOptions: 这个代理方法来启动应用,唯一不同的是这时候启动参数里面不会有任何 notification 的信息。示例代码如下: </ li >
288- < li > </ li >
289- </ ol >
290- < figure class ="highlight "> < table > < tr > < td class ="gutter "> < pre > < span class ="line "> 1</ span > < br > </ pre > </ td > < td class ="code "> < pre > < span class ="line "> - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // do initializing works ... if (launchOptions) { // do something else ... [AVAnalytics trackAppOpenedWithLaunchOptions:launchOptions]; } [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound]; return YES; } ``` 3.如果远程消息发送过来的时候,应用正在运行,这时候会发生什么呢?应用代理的 application:didReceiveRemoteNotification: 方法会被调用,同时远程消息中的 payload 数据会作为参数传递进去。示例代码如下: ```objective-c - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { if (application.applicationState == UIApplicationStateActive) { // 转换成一个本地通知,显示到通知栏,你也可以直接显示出一个 alertView,只是那样稍显 aggressive:) UILocalNotification *localNotification = [[UILocalNotification alloc] init]; localNotification.userInfo = userInfo; localNotification.soundName = UILocalNotificationDefaultSoundName; localNotification.alertBody = [[userInfo objectForKey:@"aps"] objectForKey:@"alert"]; localNotification.fireDate = [NSDate date]; [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; } else { [AVAnalytics trackAppOpenedWithRemoteNotificationPayload:userInfo]; } }</ span > < br > </ pre > </ td > </ tr > </ table > </ figure >
284+ < p > 1/ 在应用没有被启动的时候,接收到了消息通知。这时候操作系统会按照默认的方式来展现一个 alert 消息,在应用的 icon 上标记一个数字,甚至播放一段声音。 < br > 2/ 用户看到消息之后,点击了一下 action 按钮或者点击了应用图标。如果 action 按钮被点击了,系统会通过调用 application:didFinishLaunchingWithOptions: 这个代理方法来启动应用,并且会把 notification 的 payload 数据传递进去。如果应用图标被点击了,系统也一样会调用 application:didFinishLaunchingWithOptions: 这个代理方法来启动应用,唯一不同的是这时候启动参数里面不会有任何 notification 的信息。示例代码如下: </ p >
285+ < pre > < code class =" objective-c " > - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // do initializing works ... if (launchOptions) { // do something else ... [AVAnalytics trackAppOpenedWithLaunchOptions:launchOptions]; } [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound]; return YES; }
286+ </ code > </ pre >
287+ < p > 3/ 如果远程消息发送过来的时候,应用正在运行,这时候会发生什么呢?应用代理的 application:didReceiveRemoteNotification: 方法会被调用,同时远程消息中的 payload 数据会作为参数传递进去。示例代码如下: </ p >
288+ < pre > < code class ="objective-c "> - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { if (application.applicationState == UIApplicationStateActive) { // 转换成一个本地通知,显示到通知栏,你也可以直接显示出一个 alertView,只是那样稍显 aggressive:) UILocalNotification *localNotification = [[UILocalNotification alloc] init]; localNotification.userInfo = userInfo; localNotification.soundName = UILocalNotificationDefaultSoundName; localNotification.alertBody = [[userInfo objectForKey:@"aps"] objectForKey:@"alert"]; localNotification.fireDate = [NSDate date]; [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; } else { [AVAnalytics trackAppOpenedWithRemoteNotificationPayload:userInfo]; } }
289+ </ code > </ pre >
291290
292291
293292 </ div >
0 commit comments