iOS 远程推送

APNS的推送机制

iOS 远程推送_第1张图片
4196_130321132850_1.png

Provider就是我们自己程序的后台服务器,APNS是Apple Push Notification Service的缩写,也就是苹果的推送服务器。

这里 Provider 是指某个应用的Developer,当然如果开发者使用AVOS Cloud的服务,把发送消息的请求委托给我们,那么这里的Provider就是AVOS Cloud的推送服务程序了。上图可以分为三步:
第一步:AVOS Cloud推送服务程序把要发送的消息、目的设备的唯一标识打包,发给APNs。
第二步:APNs在自身的已注册Push服务的应用列表中,查找有相应标识的设备,并把消息发送到设备。
第三步:iOS系统把发来的消息传递给相应的应用程序,并且按照设定弹出Push通知

iOS 远程推送_第2张图片
8deb07df-1356-3aed-8c2e-3e41d25d4e2f.jpg

从上图我们可以看到:

1、应用程序注册消息推送。(去苹果开发中心,生成消息推送的证书)

2、iOS从APNS Server获取device token,应用程序接收device token。

3、应用程序将device token发送给PUSH服务端程序。

4、服务端程序向APNS服务发送消息。

5、APNS服务将消息发送给iPhone应用程序。

========================================
为了实现消息推送,有两点非常重要:
1,App的推送证书
要能够完整实现一条消息推送,需要我们在App ID中打开Push Notifications,需要我们准备好Provisioning Profile和SSL证书,并且一定要注意Development和Distribution环境是需要分开的。最后,把SSL证书导入到AVOS Cloud平台,就可以尝试远程消息推送了。具体的操作流程可以参考我们的使用指南:iOS推送证书设置指南。

2,设备标识DeviceToken
知道了谁要推送,或者说要推送给哪个App之后,APNs还需要知道推到哪台设备上,这就是设备标识的作用。获取设备标识的流程如下:

iOS 远程推送_第3张图片
8369_140528111300_1.png

第一步:App打开推送开关,用户要确认TA希望获得该App的推送消息
第二步:App获得一个DeviceToken
第三步:App将DeviceToken保存起来,这里就是通过[AVInstallation saveInBackground]将DeviceToken保存到AVOS Cloud
第四步:当某些特定事件发生,开发者委托AVOS Cloud来发送推送消息,这时候AVOS Cloud的推送服务器就会给APNs发送一则推送消息,APNs最后消息送到用户设备

推送相关的几个概念
消息类型
一条消息推送过来,可以有如下几种表现形式:

  1. 显示一个alert或者banner,展现具体内容
  2. 在应用icon上提示一个新到消息数
  3. 播放一段声音

开发者可以在每次推送的时候设置,在推送达到用户设备时开发者也可以选择不同的提示方式。

代码里面如何实现推送
首先,我们要获取DeviceToken。
App需要每次启动的时候都去注册远程通知——通过调用UIApplication的registerForRemoteNotificationTypes:方法,传递给它你希望支持的消息类型参数即可,例如:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    // do some initiale working 
    ... 
     
    [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound]; 
    return YES; 
} 

如果注册成功,APNs会返回给你设备的token,iOS系统会把它传递给app delegate代理——application:didRegisterForRemoteNotificationsWithDeviceToken:方法,你应该在这个方法里面把token保存到AVOS Cloud后台,例如:

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 
    NSLog(@"Receive DeviceToken: %@", deviceToken); 
    AVInstallation *currentInstallation = [AVInstallation currentInstallation]; 
    [currentInstallation setDeviceTokenFromData:deviceToken]; 
    [currentInstallation saveInBackground]; 
} 

如果注册失败,application:didFailToRegisterForRemoteNotificationsWithError:方法会被调用,通过NSError参数你可以看到具体的出错信息,例如:

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { 
    NSLog(@"注册失败,无法获取设备ID, 具体错误: %@", error); 
} 

请注意:注册流程需要在app每次启动时调用,这并不不会带来额外的负担,因为iOS操作系统在第一次获得了有效的device token之后,会本地缓存起来,以后app再调用registerForRemoteNotificationTypes:的时候会立刻返回,并不会再进行网络请求。另外,app层面不应该对device token进行缓存,因为device token也有可能变化——如果用户重装了操作系统,那么APNs再次给出的device token就会和之前的不一样,又或者是,用户restore了原来的backup到新的设备上,那么原来的device token也会失效。

其次,我们要处理收到消息之后的回调
我们可以设想一下消息通知的几种使用场景:

1,在app没有被启动的时候,接收到了消息通知。这时候操作系统会按照默认的方式来展现一个alert消息,在app icon上标记一个数字,甚至播放一段声音。

2,用户看到消息之后,点击了一下action按钮或者点击了应用图标。如果action按钮被点击了,系统会通过调用application:didFinishLaunchingWithOptions:这个代理方法来启动应用,并且会把notification的payload数据传递进去。如果应用图标被点击了,系统也一样会调用application:didFinishLaunchingWithOptions:这个代理方法来启动应用,唯一不同的是这时候启动参数里面不会有任何notification的信息。

示例代码如下:
- (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; 
} 

,如果远程消息发送过来的时候,app正在运行,这时候会发生什么呢?

app代理的application:didReceiveRemoteNotification:方法会被调用,同时远程消息中的payload数据会作为参数传递进去。

转载地址:
http://www.cocoachina.com/industry/20140528/8582.html

你可能感兴趣的:(iOS 远程推送)