iOS远程推送原理及实现过程

转载

推送通知,是现在的应用必不可少的功能。那么在 iOS 中,我们是如何实现远程推送的呢?iOS 的远程推送原理又是什么呢?在做 iOS 远程推送时,我们会遇到各种各样的问题。那么首先让我们准备一些做推送需要的东西。我们需要一个付费的苹果开发者账号(免费的不可以做远程推送),有了开发者账号,我们可以去苹果开发者网站,配置自己所需要的推送的相关证书。然后下载证书,供我们后面使用,详细的证书配置过程,我们下面再说。

首先我们要说说iOS推送通知的基本原理:

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

设备注册APNs的流程图:


20160513091634267.png

上图完成了如下步骤:
1.Device(设备)连接APNs服务器并携带设备序列号(UUID)
2.连接成功,APNs经过打包和处理产生devicetoken并返回给注册的Device(设备)
3.Device(设备)携带获取的devicetoken发送到我们自己的应用服务器
4.完成需要被推送的Device(设备)在APNs服务器和我们自己的应用服务器的注册

推送过程图:
![20160513091634268.png](http://upload-images.jianshu.io/upload_images/2135374-fe959fea773ee260.png?
imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

推送的过程经过如下步骤:
1.首先,我们的设备安装了具有推送功能的应用(应用程序要用代码注册消息推动),我们的 iOS设备在有网络的情况下会连接APNs推送服务器,连接过程中,APNS 服务器会验证devicetoken,连接成功后维持一个基于TCP 的长连接;
2.Provider(我们自己的应用服务器)收到需要被推送的消息并结合被推送的 iOS设备的devicetoken一起打包发送给APNS服务器;
3.APNS服务器将推送信息推送给指定devicetoken的iOS设备;
4.iOS设备收到推送消息后通知我们的应用程序并显示和提示用户(声音、弹出框)

比较直观的流程图:


20160513091634269.png

信息包结构图:


20160513091634271.png

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

Payload(消息体)的结构:

{
“aps”:{
“alert”:“听云给您发送了新消息”,
“badge”:1,
“sound”:“default”
},
}

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

下面就是我们推送通知所需要的证书的推送过程:

1.首先我们要新建一个Certificate Signing Request(也就是CSR)的请求文件

在应用程序里的使用工具中找到钥匙串访问,选择从证书颁发机构请求证书

20160513091634273.png
20160513091634274.png

注意:邮箱地址,填自己的开发者账号,常用名,随便填一个记住就行。然后选择存储到磁盘。继续就行。

20160513091634276.png

保存位置在 tingyun(指定自己的文件夹,这里我选择的是我的文件夹),点击存储

然后点击完成后我们会在 tingyun 里看到一个CertificateSigningRequest.certSigningRequest的请求文件,也就是我们说的CSR文件。在我们生成CSR文件的同时,会在钥匙串访问中生成一对秘钥,名称为刚才我们填写的常用名

2.配置AppID

苹果开发者网站点击Account

20160513091635277.png

选择 Certificates,identifiers&Profiles

20160513091635278.png

选择 Identifiers ->App IDs 点击上方的+号创建一个 App ID.

20160513091635279.png

Name: 填写 App 的名字就行

App ID Suffix 选择不用通配符的及 Explicit App ID

Bundle ID:填写自己应用的 Bundle ID 一定要和自己应用的一致.

20160513091635280.png

在下面的 App Services 中选择自己需要的服务

我们需要推送服务,所以在Push Notifications上打勾
然后点击continue

20160513091635281.png

3.创建证书

证书需要创建两种,一种是开发的、一种是发布的,开发的是做测试用的。
选择Development 点击右上角的+号,创建证书,我们首先创建开发证书


20160513091635282.png

选择Apple Push Notification service SSL (Sandbox),创建推送服务证书点击下一步

20160513091635283.png

这儿的 App ID 选择我们刚才创建的 App ID

然后点击下一步,下一步

20160513091635284.png

这儿点击 Choose File,选择我们刚才创建的 CSR 文件.

然后点击生成(Generate)

最后点击下载,下载证书。将下载的证书,放到指定位置。


20160513091635285.png

发布证书的创建和开发证书一样,选择Production->Apple Push Notification service SSL (Production)后面和开发证书一样

20160513091636286.png

20160513091636287.png

4.添加 Devices:

首先选中你要添加哪种设备,然后在左上角点击“+”号。


20160513091636288.png

Name 填写一个设备名字。

UDID 填写自己需要加入测试的设备的 UDID。

然后点击下一步

20160513091636289.png

然后点击 Register 即可


20160513091636290.png

点击Done。

5.查找设备的 UDID:

用自己的 iOS 设备连接到电脑上,打开 iTunes。

在设备摘要处可以看见一个序列号,点击序列号就会变成 UDID。

20160513091636293.png

6.生成配置文件

配置文件也有两种,一种是开发的,一种是发布的,开发的使我们做测试需要的,发布的是我们在 Appstore 上发布时需要的,我们都需要生成。

我们先生成开发配置文件,选择Provisioning Profiles->Development点击右上角的+号。

20160513091637294.png

选择iOS App Development 点击下一步

20160513091637295.png

这儿的 App ID 仍然选择我们刚才创建的 App ID

20160513091637296.png

这儿选择我们开发者的证书,如果不知道是哪个选择全部即可

20160513091637298.png

这儿选择我们的测试设备,如果没有则在前面的Devices里面添加即可

20160513091637299.png
20160513091637300.png

随便取个名字即可,然后下载下来

20160513091637301.png

发布配置文件和开发配置文件一样创建,选择Distribution->Ad Hoc即可,后面与发布配置文件一样。

20160513091637302.png
20160513091638303.png
20160513091638304.png
证书配置完成,打开我们创建的应用项目
打开AppDelegate.m 文件,在
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 方法中添加下面代码,注册消息推送

-(BOOL)application:(UIApplication*)applicationdidFinishLaunchingWithOptions:(NSDictionary*)launchOptions{
//Overridepointforcustomizationafterapplicationlaunch.
/**消息推送注册*/
if([UIDevicecurrentDevice].systemVersion.floatValue>=8.0){

UIUserNotificationSettings*settings=[UIUserNotificationSettingssettingsForTypes:UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlertcategories:nil];
[applicationregisterUserNotificationSettings:settings];
[applicationregisterForRemoteNotifications];
}else{
[applicationregisterForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeAlert)];
}

returnYES;
}
下面方法是返回ANPs苹果推送服务器生成的唯一标识
/**接收服务器传回的设备唯一标识token*/
-(void)application:(UIApplication*)applicationdidRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken{

//第一次运行获取到DeviceToken时间会比较长!
//将deviceToken转换成字符串,以便后续使用
NSString*token=[deviceTokendescription];
NSLog(@"description%@",token);
}

下面方法是当有消息推送回来时,接收推送消息   
/**设备接收到来自苹果推送服务器的消息时触发的,用来显示推送消息*/

-(void)application:(UIApplication*)applicationdidReceiveRemoteNotification:(NSDictionary*)userInfo{

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

上面方法是当注册推送服务失败时,接收错误信息
/**注册推送服务失败*/
-(void)application:(UIApplication*)applicationdidFailToRegisterForRemoteNotificationsWithError:(NSError*)error{
NSLog(@"注册失败%@",error);
}

服务器端(Java服务器)

服务器端我们需要,一个后缀为. p12的证书,以及需要的 jar 包

服务器端的证书生成方式:
打开我们前面下载的证书,在钥匙串中找到它

20160513091638305.png

点击鼠标右键选择导出

20160513091638306.png

导出后缀为.p12的文件保存到自己的电脑上,需要输入一个密码,在 Java 服务器端要用到

20160513091638307.png

Java服务器端需要的 Jar 包

20160513091638308.png

Java 服务器端代码:


import javapns.back.PushNotificationManager;
import javapns.back.SSLConnectionHelper;
import javapns.data.Device;
import javapns.data.PayLoad;
public class pushService {
    public static void main(String[]args) {
        
        
        try{
        String deviceToken = "eab6df47eb4f81e0aaa93bb208cffd7dc3884fd346ea0743fcf93288018cfcb6";
        //被推送的iphone应用程序标示符
        PayLoad payLoad=newPayLoad();
        payLoad.addAlert("测试我的push消息");
        payLoad.addBadge(1);
        payLoad.addSound("default");
        
        PushNotificationManager pushManager=PushNotificationManager.getInstance();
        pushManager.addDevice("iphone",deviceToken);
        
                //测试推送服务器地址:gateway.sandbox.push.apple.com/2195
            //产品推送服务器地址:gateway.push.apple.com/2195
        Stringhost="gateway.sandbox.push.apple.com";//测试用的苹果推送服务器
        intport=2195;
        String certificatePath="/Users/hsw/Desktop/PushTest/PushTest.p12";//刚才在mac系统下导出的证书
        
        String certificatePassword="123456";
        
        pushManager.initializeConnection(host,port,certificatePath,certificatePassword,SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);
        
        //SendPush
        Device client=pushManager.getDevice("iphone");
        pushManager.sendNotification(client,payLoad);//推送消息
        pushManager.stopConnection();
        pushManager.removeDevice("iphone");
        }
        catch(Exceptione){
        e.printStackTrace();
        System.out.println("pushfaild!");
        return;
        }
        System.out.println("pushsucceed!");
        }

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

推荐阅读更多精彩内容