iOS推送通知原理

一、推送通知的基本原理:

苹果的推送服务通知是由自己专门的推送服务器APNs (Apple Push Notification service)来完成的,其过程是 APNs 接收到我们自己的应用服务器发出的被推送的消息,将这条消息推送到指定的 iOS 的设备上,然后再由 iOS设备通知到我们的应用程序,我们将会以通知或者声音的形式收到推送回来的消息。 iOS 远程推送的前提是,装有我们应用程序的 iOS 设备,需要向 APNs 服务器注册,注册成功后,APNs 服务器将会给我们返回一个 devicetoken,我们获取到这个 token 后会将这个 token 发送给我们自己的应用服务器。当我们需要推送消息时,我们的应用服务器将消息按照指定的格式进行打包,然后结合 iOS 设备的 devicetoken 一起发给 APNs 服务器。我们的应用会和 APNs 服务器维持一个基于 TCP 的长连接,APNs 服务器将新消息推送到iOS 设备上,然后在设备屏幕上显示出推送的消息。

设备注册APNs的流程图:


推送流程图

上图完成了如下步骤:

1.Device(设备)连接APNs服务器并携带设备序列号(UUID)

2.连接成功,APNs经过打包和处理产生devicetoken并返回给注册的Device(设备)

3.Device(设备)携带获取的devicetoken发送到我们自己的应用服务器

4.完成需要被推送的Device(设备)在APNs服务器和我们自己的应用服务器的注册

推送过程图:


Push 过程

1.首先,我们的设备安装了具有推送功能的应用(应用程序要用代码注册消息推动),我们的 iOS设备在有网络的情况下会连接APNs推送服务器,连接过程中,APNS 服务器会验证devicetoken,连接成功后维持一个基于TCP 的长连接;

2.Provider(我们自己的应用服务器)收到需要被推送的消息并结合被推送的 iOS设备的devicetoken一起打包发送给APNS服务器;

3.APNS服务器将推送信息推送给指定devicetoken的iOS设备;

4.iOS设备收到推送消息后通知我们的应用程序并显示和提示用户(声音、弹出框)

信息包结构图:


信息结构图

上图显示的这个消息体就是我们的应用服务器(Provider)发送给APNs服务器的消息结构,APNs验证这个结构正确并提取其中的信息后,再将消息推送到指定的iOS设备。这个结构体包括五个部分,第一个部分是命令标示符,第二个部分是我们的devicetoken的长度,第三部分是我们的devicetoken字符串,第四部分是推送消 息体(Payload)的长度,最后一部分也就是真正的消息内容了,里面包含了推送消息的基本信息,比如消息内容,应用Icon右上角显示多少数字以及推送消息到达时所播放的声音等

Payload(消息体)的结构:

 “aps”:{ 

 “alert”:“send message”, 

 “badge”:1,

 “sound”:“default” }

}

这其实就是个JSON结构体,alert标签的内容就是会显示在用户手机上的推送信息,badge显示的数量(注意是整型)是会在应用Icon右上角显示的数量,提示有多少条未读消息等,sound就是当推送信息送达是手机播放的声音,传defalut就标明使用系统默认声音。

二、配置证书

1.登录Apple的Developer Member Center、

打开Safari浏览器,地址栏输入并打开此网址:https://developer.apple.com/membercenter/index.action,然后用开发者账号登录.

选择点击Certificates, Identifiers & Profiles., 打开后在左侧列表中选择Certificates大类下面的All子类,出现如下界面:


Apple dev

2.选择证书的类型,Sandbox或者Productuon

根据你的需求选择Apple Push Notification service SSL (Sandbox) 或者 Apple Push Notification service SSL (Sandbox & Production)类型的证书.

然后点击继续.

这里要注意一点,选择证书的正确类型非常重要:

一个用Development Provisioning Profile签名的App生成的 Device Token只能和Sandbox APNS Server结合使用(开发环境测试用).

一个用AdHoc Provisioning Profile或者AppStore Provisioning Profile签名的App生成的Device Token只能和Production APNS Server结合使用(生产环境发布使用).

提示:

有些用户已经报告过关于使用二合一的推送证书(Apple Push Notification service SSL (Sandbox & Production),新出的 )在调试测试环境进行推送时会出问题.


生成推送证书

3.选择你对应的App ID

前提你要先已经创建了你App使用的App ID,并在App ID下拉选项中选择你对应的App ID.

点击继续按钮继续.


选择对应AppleID

4.查看创建证书签名请求相关步骤信息

查看一下如何创建一个CSR文件的信息.

点击继续.


apns-04

该页面有关于如何一步一步创建CSR文件的详细信息,下面我们就跟着一步一步来创建CSR文件.

5.打开钥匙串访问程序

打开Launchpad中的其他组的Keychain Access App,就是钥匙串访问程序.


apns-05

6.创建证书签名请求文件

点击钥匙串访问程序的菜单栏

选择证书助理子菜单

选择从证书颁发机构请求证书...子子菜单


apns-06

7.填写证书签名请求文件详细信息

输入email地址,为了安全和保险起见,最好填写和你Apple开发者账号对应的email地址.

接着输入常用名称.

最好选择存储到磁盘选项.

最后点击继续.

apns-07

8.保存证书签名请求文件到磁盘

选择一个存储位置以及输入一个你喜欢的文件名称

点击保存


apns-08

9.完成证书签名请求文件制作

点击完成


apns-09

10.上传正确签名请求文件

继续回到第四步后的浏览器界面

选择 Choose File...来上传

在弹出的文件打开对话框中定位到刚刚存储的证书签名请求文件所在目录,并选择打开该CSR文件.

点击继续


apns-10

11.下载证书文件

上一步继续之后,你的证书应该就已经生成好了.

点击下载按钮来下载证书.

打开下载的证书文件,一般会自动用钥匙串访问程序打开的.


apns-11

三、代码配置

打开AppDelegate.m 文件,在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 方法中添加下面代码,注册消息推送

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

    // Override point for customization after application launch.

    if (IOSVersion >= 10.0) {

            UNUserNotificationCenter *center = [UNUserNotificationCenter     currentNotificationCenter];

        // 必须写代理,不然无法监听通知的接收与点击

        center.delegate=self;

        [centerrequestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {

            if(granted) {

                // 点击允许

                NSLog(@"注册成功");

                [centergetNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {

                    NSLog(@"%@", settings);

                }];

            }else{

                // 点击不允许

                NSLog(@"注册失败");

            }

        }];

    }else{

         [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];

    }

    [[UIApplication sharedApplication] registerForRemoteNotifications];

}


#pragma mark Push methodsIniOS9

- (void)application:(UIApplication*)application didRegisterUserNotificationSettings:(UIUserNotificationSettings*)notificationSettings

{

    [application registerForRemoteNotifications];

}

/** APP已经接收到“远程”通知(推送) - 透传推送消息  */

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

    NSLog(@"\n>>>[Receive RemoteNotification - Background Fetch]:%@\n\n",userInfo);

    completionHandler(UIBackgroundFetchResultNewData);

}

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

{

NSLog(@"userInfo == %@",userInfo);

}

#pragma mark Push methodsIniOS10

- (void)userNotificationCenter:(UNUserNotificationCenter*)center willPresentNotification:(UNNotification*)notification withCompletionHandler:(void(^)(UNNotificationPresentationOptionsoptions))completionHandler{

    completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert);

}

//App通知的点击事件

- (void)userNotificationCenter:(UNUserNotificationCenter*)center didReceiveNotificationResponse:(UNNotificationResponse*)response withCompletionHandler:(void(^)(void))completionHandler{

    //收到推送的请求

    UNNotificationRequest*request = response.notification.request;


    //收到推送的内容

    UNNotificationContent*content = request.content;


    //收到用户的基本信息

    NSDictionary*userInfo = content.userInfo;

    completionHandler();// 系统要求执行这个方法

}

下面方法是返回 ANPs 苹果推送服务器生成的唯一标识

/** 接收服务器传回的设备唯一标识 token */

- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken

{

    NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];

     // 第一次运行获取到DeviceToken时间会比较长!

    // 将deviceToken转换成字符串,以便后续使用

    NSString *token = [deviceToken description];

    NSLog(@"description %@", token);

}

/** 注册推送服务失败 */

- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error

{

NSLog(@"注册失败 %@",error);

}

四、测试

测试推送链路是否通畅的工具有很多,大家自行选择,比如个推等等。。。需要注意的是推送是有丢失率的,不是100%每推必达!!!

Demo地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,640评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,254评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,011评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,755评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,774评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,610评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,352评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,257评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,717评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,894评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,021评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,735评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,354评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,936评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,054评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,224评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,974评论 2 355

推荐阅读更多精彩内容

  • 极光推送: 1.JPush当前版本是1.8.2,其SDK的开发除了正常的功能完善和扩展外也紧随苹果官方的步伐,SD...
    Isspace阅读 6,719评论 10 16
  • 推送通知,是现在的应用必不可少的功能。那么在 iOS 中,我们是如何实现远程推送的呢?iOS 的远程推送原理又是什...
    皮皮瑞阅读 1,299评论 0 3
  • 概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣的那么通过通知...
    莫离_焱阅读 6,514评论 1 8
  • 推送通知 注意:这里说的推送通知跟NSNotification有所区别 NSNotification是抽象的,不可...
    iOS开发攻城狮阅读 4,225评论 1 13
  • 推送通知注意:这里说的推送通知跟NSNotification有所区别NSNotification是抽象的,不可见的...
    醉叶惜秋阅读 1,515评论 0 3