APPLE iOS 远程推送APNS

苹果的远程推送APNS:


原理过程什么的就不说了,这里主要是为了记录一下今天解决推送所遇到的坑。

步骤主要分为四部分:

  • 请求证书
  • 处理证书以及p.12文件等问题
  • 客户端这边根据需要设置一下
  • 测试一下可行性

请求证书 && 处理证书及p.12文件


  1. 创建APP ID
    登录Apple Member Center :https://developer.apple.com/membercenter,选择certificates,identifiers&profiles
    选项,如下图所示:
    起始页

    选择identity
    中的APP IDs
    ,如下图所示:
    创建id

    注意:创建Explicit App ID
    时,要注意此时设置的Bundle ID要与APP以后的Bundle ID一致,如下图所示:
    Bundle ID
    选择
    Push Notification
    来开通Push功能,如下图所示:
    开通Push功能
    点击下方的
    register
    按钮,几秒钟之后下方会变成一个Done
    ,表示APP ID已经创建完成,如下图所示:
    感谢友盟+
    感谢友盟+
    感谢友盟+
    注意:
    创建的APP ID要与自己项目的Bundle ID保持一致。如果已经有APP ID,请确保自己的APP ID已经开通了Push功能,如果没有开通,可以点击APP ID,在其底部有一个Edit按钮,点击后选中Push服务并创建,如下图所示:

感谢友盟+

至此,APP ID创建完毕。

  1. 创建CSR文件
    如果你已经有CSR文件,请继续进行下一步的设置。

CSRCerificate Signing Request的英文缩写,即证书请求文件。证书申请者在申请数字证书时由CSP(加密服务提供者)在生成私钥的同时也生成证书请求文件。证书申请者只要把CSR文件提交给证书颁发机构后,证书颁发机构使用其根证书私钥签名就生成了证书公钥文件,也就是颁发给用户的证书。

在电脑中找到钥匙串----->钥匙串访问------>证书管理------>从证书颁发机构请求证书,如下图所示:

感谢友盟+

感谢友盟+

设置完证书信息后,点击“继续”,然后选择存储位置,点击存储,至此,CSR文件创建成功。

  1. 创建开发调试证书
    如果你已经有开发调试证书,请继续进行下一步的设置。

选择Development(如果是发布上线,需要选择Distribution),如下图所示:

这里写图片描述
之后,你将看到如下四个证书。这一步,我们选择iOS App Development证书,如下图所示:
这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

choose file...中选择本地的CertificateSigningRequest(CSR)文件,然后点击继续,如下图所示:
感谢友盟+

这里写图片描述

点击Download,将证书下载到本地,双击下载的开发调试证书(文件名为:iOS_development.cer),就可以在钥匙串访问中的我的证书中找到。

至此,开发调试证书设置完毕。

  1. 添加测试设备
    测试推送需要添加测试设备,添加方法如下所示:


    这里写图片描述
    这里写图片描述
    这里写图片描述
    这里写图片描述
  2. 创建Provisioning Profiles文件
    选择Development,创建开发环境的Provisioning Profiles(如果是发布上线,需要选择Distribution),如下图所示:
    这里写图片描述

    这里写图片描述

    创建新的Provisioning Profiles,并选择之前生成好的App ID。如下图所示:
    这里写图片描述

    选中创建的证书:
    这里写图片描述

选中测试设备:

这里写图片描述

这里写图片描述

把创建的Provisioning Profiles,调试证书推送证书下载下来(文件名:umengpushtestdemo.mobileprovision)以后双击证书。
这里写图片描述

  1. 创建推送证书
    选择Apple Push Notification service SSL(Sandbox)
    这里写图片描述

    注意:推送证书分为开发环境和生产环境,如果需要生成生产环境的推送证书请选择: Apple Push Notification service SSL (Sandbox&Production)
    ,如下图所示:
    这里写图片描述

选中APP ID后,点击continue,直到上传CRS文件,如下图所示:

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

点击Download,将证书下载到本地后,双击下载的开发环境推送证书(文件名为:aps_development.cer),就可以在钥匙串访问中的我的证书中找到。

** 这里我要说的坑就是,在双击开发证书之后,在登录选项下,竟然没有发现上述图片所说的那个秘钥!!!!!!!在这里我删了又重来删了有重来好几次了**

最后。。。。我™直接拉进去,竟然可以了~

  1. 导出推送证书的P12文件
    注意:在钥匙串访问(KeyChain)的我的证书中选择刚刚导入的证书,选择导出,注意不要选中私钥,并设置相应密码即可。
这里写图片描述
这里写图片描述
这里写图片描述

注意:此步骤所设置的密码将在之后在U-Push后台上传推送证书时所使用。

感谢友盟+

生产环境的推送证书也是以同样的方式导出。
至此,P12证书导出完毕。

上面所说的那些,我都是在友盟看回来的,感谢友盟

客户端接收设置


1、注册远程推送以及设置相关选项:

    // 这里其实还有个ios版本区分的,但是项目需求是7.0以上的版本,所以这里没有考虑其他情况。
    UIRemoteNotificationType types = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert;
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:types];

这里还需要对Capabilites进行设置以确保能接受到推送:

屏幕快照 2016-07-19 20.09.12.png

2、在APPDelegate.m的接收函数


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    if (launchOptions) {
        //如果应用还没启动,则通过push冷启动后,仍能在激动之后获取Dictionary
        NSDictionary *userInfo = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
        
        if (userInfo) {
            //有推送消息优先处理推送消息
            NSLog(@"Dictionary:%@",userInfo);
        }
        //  当userInfo设置了badge,应用图标上将一直显示一个数字提示,如果要清除数字提示,或者设置成其他数字,调用下面函数就可以完成。
        [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
        
    }

    return YES;
}

//注册成功回调方法,其中deviceTocken是APNS返回的token
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{

    NSLog(@"Devtocken:%@",deviceToken);
}

//注册失败返回调用方法,处理失败情况
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{

    NSLog(@"获取DeviceTocken失败:%@",error);
    
}

//当程序在前台运行,接收到消息不会有消息提示(提示框或横幅)。
//当程序运行在后台,接收到消息会有消息提示,点击消息后进入程序,
//AppDelegate的didReceiveRemoteNotification函数会被调用,消息做为此函数的参数传入
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)payload {
    
    NSLog(@"remote notification: %@",[payload description]);
    NSString* alertStr = nil;
    NSDictionary *apsInfo = [payload objectForKey:@"aps"];
    NSObject *alert = [apsInfo objectForKey:@"alert"];
    if ([alert isKindOfClass:[NSString class]])
    {
        alertStr = (NSString*)alert;
    }
    else if ([alert isKindOfClass:[NSDictionary class]])
    {
        NSDictionary* alertDict = (NSDictionary*)alert;
        alertStr = [alertDict objectForKey:@"body"];
    }
    application.applicationIconBadgeNumber = [[apsInfo objectForKey:@"badge"] integerValue];
    
    //当程序存活并受到来自APNS的推送时执行的方法:
    if ([application applicationState] == UIApplicationStateActive && alertStr != nil)
    {
        UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Pushed Message" message:alertStr delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertView show];    
    }
    
    if ([application applicationState] == UIApplicationStateBackground) {
        UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Pushed Message" message:alertStr delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertView show];
    }
}

测试一下


在网上搜罗了一下,有好几种方式可以达到检测的目的,首推的,也是最简单的,在Mac上运行的,直接在github上可以拿到改demo:PushMeBaby

这里只需要简单的在APPdelegate中配置一下DeviceToken以及把推送证书放到项目工程中就可以了。 ** 此处有坑 **:这里需要把这个选项给选上,不然在读取证书路径的时候就会失败。

屏幕快照 2016-07-19 20.16.30.png

** 同时这里还存在第二个坑:**
在设置deviceToken时,需要保留空格,去掉尖括弧

屏幕快照 2016-07-19 20.18.28.png

运行一下,push一下就可以了,有时候网络问题也会导致一些延迟。

这里我其实还测试了另外的一种方法:php推送

1 .首先将证书文件和私钥处理成单个方便使用的pem文件,假设CSR、p12和cer文件都放在桌面上。

$ cd ~/Desktop$ls
aps_development.cer
CertificateSigningRequest.certSigningRequest
PushKey.p12

2 .将aps_development.cer转换为pem文件。

$ openssl x509 -in aps_development.cer -inform der -out PushCert.pem
$ls
aps_development.cer
CertificateSigningRequest.certSigningRequest
PushCert.pem
PushKey.p12

3 .将p12私钥文件转换为pem文件。

$ openssl pkcs12 -nocerts -out PushKey.pem -in PushKey.p12 
Enter Import Password:
MAC verified OK
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:

4 .将两个文件合成同一个。

$ cat PushCert.pem PushKey.pem > ck.pem
$ls
aps_development.cer
CertificateSigningRequest.certSigningRequest
ck.pem
PushCert.pem
PushKey.pem 
PushKey.p12

5 .测试证书是否有效。

$ openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushCert.pem -key PushKey.pem

如果有效的话,会输出一堆信息,并且建立连接,否则不会成功建立连接。
6 .使用PHP进行测试,下载SimplePush.php,修改文件并填入deviceToken和密码。在终端运行该代码。

$ php simplepush.php Connected to APNSMessage successfully delivered

成功发送推送消息。
(此方法感谢:戴维营教育原创文章)


** 关于推送json格式的说明 **

  • 推送负载:

远程通知负载的大小根据Provider使用的API不同而不同。当使用HTTP/2 provider API时,负载最大为4096bytes,即4kB;当使用legacy binary interface时,负载最大为2048bytes,即2kB。当负载大小超过规定的负载大小时,APNs会拒绝发送此消息。

  • 远程推送负载内容

内容格式必要要知道的啊,服务端一般会要我们客户端定义好格式给他们的。
每一条通知的消息都会组成一个JSON字典对象,其格式如下所示,示例中的key值为苹果官方所用key。自定义字段的时候要避开这些key值。

每一条通知的消息都会组成一个JSON字典对象,其格式如下所示,示例中的key值为苹果官方所用key。自定义字段的时候要避开这些key值。


{
     "aps" : {  
         "alert"              :              {   // string or dictionary
            "title"          :   "string"
            "body"           :   "string",
            "title-loc-key"  :   "string or null"
            "title-loc-args" :   "array of strings or null"
            "action-loc-key" :   "string or null"
            "loc-key"        :   "string"
            "loc-args"       :   "array of strings"
            "launch-image"   :   "string"
         },
          "badge"             :    number,
          "sound"             :    "string"
          "content-available" :    number;
          "category"          :    "string"
     },
}

aps:推送消息必须有的key
alert:推送消息包含此key值,系统就会根据用户的设置展示标准的推送信息
badge:在app图标上显示消息数量,缺少此key值,消息数量就不会改变,消除标记时把此key对应的value设置为0
sound:设置推送声音的key值,系统默认提示声音对应的value值为default
content-available:此key值设置为1,系统接收到推送消息时就会调用不同的回调方法,iOS7之后配置后台模式
category:UIMutableUserNotificationCategory's identifier 可操作通知类型的key值
title:简短描述此调推送消息的目的,适用系统iOS8.2之后版本
body:推送的内容
title-loc-key:功能类似title,附加功能是国际化,适用系统iOS8.2之后版本
title-loc-args:配合title-loc-key字段使用,适用系统iOS8.2之后版本
action-loc-key:可操作通知类型key值,不详细叙述
loc-key:参考title-loc-key
loc-args:参考title-loc-args
launch-image:点击推送消息或者移动事件滑块时,显示的图片。如果缺少此key值,会加载app默认的启动图片。

后边这一对是自定义的,但是要注意不可以和前面的重复


          "badge"             :    number,
          "sound"             :    "string"
          "content-available" :    number;
          "category"          :    "string"

此处出自TIME_for 的《iOS推送之远程推送(iOS Notification Of Remote Notification》)

搬运工再次感谢各位前辈的付出。谢谢!

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

推荐阅读更多精彩内容