iOS 下APNS推送处理函数具体解释

相比起Android,iOS在推送方面无疑惯例得更好。APNS(Apple Push Notification Service)是苹果公司提供的消息推送服务。其原理就是。第三方应用将要推送给用户的信息推送到苹果server。苹果server再通过统一的系统接口将这些信息推送到用户的手机上。假设对此不舍了解的朋友能够參见这篇文章:一步一步教你做ios 推送

本文着重叫在App端怎样处理推送信息。

主要涉及一下几个比較重要的函数,而这些函数都是AppDelegate类中:

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

做过iOS 开发的人对这个函数都会非常熟悉,这是在程序结束启动。并即将执行时调用的,通常一些初始化的工作能够在这个函数中处理。相同的。推送的相关初始化操作也须要在这个部分完毕。这一部分的工作主要分为两部分:
  • 推送类型的注冊:
[[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

中完毕。可是假设用户点击推送通知的时候程序还没有被启动。这个时候以上两个函数都是接收不到用户的推送通知的,这个时候须要在application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*) launchOptions 函数里面进行处理。

而推送消息的相关信息就存储在launchOptions这个字典里。详细參照例如以下代码:

    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传送到苹果的server,这个token就相当于设备的识别码,每一台苹果设备都有唯一的token,苹果的server就是通过这个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程序块。

在处理这类推送消息(即程序被启动后接收到推送消息)的时候。一般会遇到这种问题,就是当前的推送消息是当前程序正在前台执行时接收到的还是说是程序在后台执行,用户点击系统消息通知栏相应项进入程序时而接收到的?这个事实上非常easy,用以下的代码就能够解决:

void application:(UIApplication*)application didReceiveRemoteNotification:NSDictionary)userInfo fetchCompletionHandler:((^)UIBackgroundFetchResult)completionHandler{
if (application.applicationState == UIApplicationStateActive) {
        NSLog(@"active");
        //程序当前正处于前台
    }
    else if(application.applicationState == UIApplicationStateInactive)
    {
        NSLog(@"inactive");
        //程序处于后台
        
    }
}


关于userInfo的结构,參照苹果的官方结构:

{
    "aps" : {
        "alert" : "You got your emails.",
        "badge" : 9,
        "sound" : "bingbong.aiff"
    },
    "acme1" : "bar",
    "acme2" : 42
}

即key aps相应了有一个字典。里面是该次推送消息的详细信息。详细跟我们注冊的推送类型有关。

另外剩下的一些key就是用户自己定义的了。



原文地址:https://www.cnblogs.com/llguanli/p/7352398.html