主要流程和注意事项
数据通讯流程
- 使用前证书准备
从证书颁发机构颁发证书
保存证书到一个文件夹apns
登陆苹果开发者帐号,新建一个AppID,选择网页上的AppIDs,然后点击右上角的 “加号”
Bundle id必须和app的一致。
选择推送
最后提交就可以了。
开始创建证书
Development选项是用来作为开发使用的证书,Production选项则是用来发布产品使用的。两个选项生成证书的步骤是一样的,现在我们使用开发者的选项进行证书的制作,选择Development选项。
选择刚才创建的app_id.
加入刚才使用钥匙串生成的证书。最后提交保存下载aps_development .cer到apns文件夹。
生成Provisioning Profiles(一种是为开发使用的,还有一种则是为发布到appStore上面。)
同样选择刚才创建的id.
选择开发者账号
选择设备
写个名字就可以提交了,然后在下载保存到afns文件夹中。
首先双击我们生成的 “aps_development .cer” 文件,进入钥匙串访问,找到我们的专用秘钥,右击到处保存到afns中。
这样所有文件就已经生成了,在文件里面应该有四个文件。
下面就可以开始操作终端了,打开终端将他们生成.pem文件。
把aps_development .cer文件生成.pcm文件,cd到afns文件夹下
把push.p12文件生成为.pem文件
密码则是你导出证书所设的密码,接着还会让你输入.pem文件的密码,最少四位这样我们在afns文件夹中就又得到了两个文PushChatCert.pem和PushChatKey.pem。
把PushChatCert.pem和PushChatKey.pem合并为一个pem文件,
afns文件夹中又多了一个ck.pem文件,开始测试。
我们可以使用“telnet gateway.sandbox.push.apple.com 2195”来检测一下,如果显示下图则表示成功了
我们使用我们生成的证书和私钥来设置一个安全的链接去链接苹果服务器,在终端输入如下命令:openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushChatCert.pem -key PushChatKey.pem需要输入密码,返回一系列的数据。
出现如何表示测试成功。
- 代码使用流程
- 注册通知
- 绑定deviceToken
- 针对远程推送消息进行处理
- 不同场景下推送消息的流程
- app在前台运行时收到推送
- app退出在后台状态收到推送
- app处于关闭退出状态时收到推送
- 其他
- 网络状态不佳时远程消息推送情况
- 推送的内容格式
证书准备
流程
- 注册通知
// ios8后,需要添加这个注册,才能得到授权
if ([[UIApplication sharedApplication] respondsToSelector:@selector(isRegisteredForRemoteNotifications)]) {
UIUserNotificationType type = UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound;
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:type categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
} else {
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert];
}
并且push权限也需要开启(capabilities下面的push notifications需要开启)
- 绑定deviceToken( deviceToken相当于设备的一个标识,服务器根据这个标识来进行消息推送。)
- 当用户同意app接收远程消息推送后,手机会向APNs发起一个请求去获取deviceToken;
- APNs收到请求,根据其相应流程及算法发送对应的deviceToken给手机;
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSString *token = [NSString stringWithFormat:@"%@", deviceToken];
NSLog(@"My token is:%@", token);
//这里应将device token发送到服务器端
}
- 手机再将deviceToken传递给app;
- app再将deviceToken发送到后台服务器进行保存。
- 针对远程推送消息进行处理,远程推送消息发送过来时,点开消息常常会有一些针对性处理或流程,最常见的就是跳转页面等。
- app在前台运行时收到推送
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
for (id key in userInfo) {
NSLog(@"key: %@, value: %@", key, [userInfo objectForKey:key]);
}
/* eg.
key: aps, value: {
alert = "\U8fd9\U662f\U4e00\U6761\U6d4b\U8bd5\U4fe1\U606f";
badge = 1;
sound = default;
}
*/
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"remote notification" message:userInfo[@"aps"][@"alert"] delegate:nil cancelButtonTitle:@"cancel" otherButtonTitles:nil, nil];
[alert show];
}
- app退出在后台状态收到推送
屏幕上会出现通知提醒,如果点开消息进入app,app运行到前台时会调用“didReceiveRemoteNotification”方法,这也就是之前为什么要区分一下applicationState的原因,因为二者都是通过这一步来处理。
application.applicationState == UIApplicationStateBackground
app处于关闭退出状态时收到推送
同样屏幕上出现通知提醒,点开消息进入app,启动时“didFinishLaunchingWithOptions”方法里的launchOptions对应UIApplicationLaunchOptionsRemoteNotificationKey部分内容不再为空,含有的即是推送内容,针对处理即可。
NSDictionary *pushNotificationKey = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (pushNotificationKey) {
NSLog(@"%@",pushNotificationKey);
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"remote notification" message:[NSString stringWithFormat:@"%@",pushNotificationKey[@"aps"][@"alert"]] delegate:nil cancelButtonTitle:@"cancel" otherButtonTitles:nil, nil];
[alert show];
}else
{
}
其他
- 网络状态不佳时远程消息推送情况
如果手机不在网的时候,APNs会有一个QoS的东西把消息保存很短的时间,等手机在网时再推送过来,当然离线时间久了,消息也就收不到了,但在实际中发现貌似网络不佳的时候一般就收不到了。
如果手机离线时,服务器推送了多条消息,即时上线了收到消息,也只会收到最新的一条
- 推送的内容格式
推送的内容都有固定格式和长度,包括title(iOS8.2后增加的)、body、sound等,如果本地没有设置对应的声音文件,sound的值为default,收到推送的时候响起的是默认的提示音,并且推送消息的长度限制为256个字节(iOS8中这一限制放大到2kb).
php文件网上自己找一个就可以了,把相应的deviceToken和ck密码修改后就可以保存到afns文件中,在手机上面执行app开始运行,然后在终端执行php xxx.php命令就可以开始发送推送,出现如下表示发送成功。
1.苹果消息推送服务器APNs地址
开发版:gateway.sandbox.push.apple.com 2195
发布版:gateway.push.apple.com 2195
2.证书的时效
开发版:有效期大概四个月左右
发布版:有效期是一年
3.deviceToken的唯一性
在iOS7之前,苹果对于一个设备上的多个App,生成相同的deviceToken,iOS7之后(包括iOS7),苹果对于一个设备上的多个App,生成不同的deviceToken,经测试,同一个App,删除之后重新编译安装,获取到的deviceToken也不相同。也就是说一个deviceToken只能对于一个iOS设备,但一个iOS设备可以同时拥有多个deviceToken。
这种新改变导致APNs上创建了一张新老token的映射表,如果你一直用老的token,那没问题,但是,一旦服务器使用新的deviceToken,映射表中的记录就会被删除,这意味着,老的deviceToken就不能用了,必然发送失败。