相比起AndroidiOS在推送方面无疑惯例得更好。APNSApple Push Notification Service是苹果公司提供的消息推送服务。其原理就是第三方应用将要推送给用户的信息推送到苹果服务器苹果服务器再通过统一的系统接口将这些信息推送到用户的手机上。如果对此不舍了解的朋友可以参见这篇文章一步一步教你做ios 推送

本文着重叫在App端如何处理推送信息。主要涉及一下几个比较重要的函数而这些函数都是AppDelegate类中

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

做过iOS 开发的人对这个函数都会很熟悉这是在程序结束启动并即将运行时调用的通常一些初始化的工作可以在这个函数中处理。同样的推送的相关初始化操作也需要在这个部分完成。这一部分的工作主要分为两部分 推送类型的注册 

?

1
[[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound | UIRemoteNotificationAlert];

这行代码告诉了系统该程序注册的推送消息类型通常包括badge、声音以及alert通知。 处理程序没有启动时的推送消息 如果是程序正在运行或者说程序正在后台那么这个时候处理推送消息的工作都是在

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 或者


-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler

中完成。但是如果用户点击推送通知的时候程序还没有被启动这个时候以上两个函数都是接收不到用户的推送通知的这个时候需要在applicationUIApplication *application didFinishLaunchingWithOptionsNSDictionary*) launchOptions 函数里面进行处理。而推送消息的相关信息就存储在launchOptions这个字典里。具体参照如下代码


?

1
2
3
4
5
6
7
8
9
10
NSDictionary* pushInfo = [launchOptions objectForKey:@"UIApplicationLaunchOptionsRemoteNotificationKey"];
if (pushInfo)
{
    NSDictionary *apsInfo = [pushInfo objectForKey:@"aps"];
    if(apsInfo)
    {
        //your code here
    }
     
}




- (void)application:(UIApplication *)applicationdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)pToken & - (void)application:(UIApplication *)applicationdidFailToRegisterForRemoteNotificationsWithError:(NSError *)error

为了让device端可以接收到推送消息需要将设备的token传送到苹果的服务器这个token就相当于设备的识别码每一台苹果设备都有唯一的token苹果的服务器就是通过这个token找到对应的设备并传送相应地消息。这两个函数就是在传送token成功或者失败后调用的用户在对应的函数里面做一些相应地处理。 

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo和


-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler

都是程序在运行过程中无论当前程序处于前台还是后台接收到推送消息的处理函数。根据苹果的官方文档建议大家使用


-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler

因为前者在程序处于后台的时候是无法接收到推送信息的经实测-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo其实可以接收到不知道是怎么回事希望大虾解疑。另外就是-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler 还有一个作用。根据苹果给出的文档系统给出30s的时间对推送的消息进行处理此后就会运行CompletionHandler程序块。

在处理这类推送消息即程序被启动后接收到推送消息的时候通常会遇到这样的问题就是当前的推送消息是当前程序正在前台运行时接收到的还是说是程序在后台运行用户点击系统消息通知栏对应项进入程序时而接收到的这个其实很简单用下面的代码就可以解决


?

1
2
3
4
5
6
7
8
9
10
11
12
void application:(UIApplication*)application didReceiveRemoteNotification:NSDictionaryuserInfo fetchCompletionHandler:((^)UIBackgroundFetchResult)completionHandler{
if (application.applicationState == UIApplicationStateActive) {
        NSLog(@"active");
        //程序当前正处于前台
    }
    else if(application.applicationState == UIApplicationStateInactive)
    {
        NSLog(@"inactive");
        //程序处于后台
         
    }
}



关于userInfo的结构参照苹果的官方结构



?

1
{

?

1
"aps" : {

?

1
"alert" : "You got your emails.",

?

1
"badge" : 9,

?

1
"sound" : "bingbong.aiff"

?

1

?

1
"acme1" : "bar",

?

1
"acme2" : 42

?

1
}

?

1

即key aps对应了有一个字典里面是该次推送消息的具体信息。具体跟我们注册的推送类型有关。另外剩下的一些key就是用户自定义的了。