感谢Hello杰少的文章,我在此基础上进行丰富
1/11. 获取CSR文件
为了便于文件管理,所有文件都放在AppPush文件夹中。命令行中的命令也在改文件夹下。
本次操作基于开发模式下,生产模式下类同,相关文件改为在Distribution下创建即可。
2/11. 进入MemberCenter,选择创建 AppID。填写App ID Description,然后选择Explicit App ID(推送不能使用模糊匹配的id)填写你所要开发的app的准确Bundle ID
。 同时要在App Services中勾选Push Notifications,然后continue,然后register。
3/11. 接下来配置推送证书。可以在appID中配置,也可以在Certificates配置,但在appID中更便捷。 选择刚刚创建的appID,然后可以看到Push Notifications处于可设置状态,选择Edit。
4/11. 接下来在push notifications下选择创建证书,此时其实也就是跳转到了Certificates中来配置。
5/11. 接下来continue,然后在提示要csr文件时提交刚开始创建的csr文件,然后生成证书,下载下来后保存文件名为aps_push.cer,然后双击证书自动安装到钥匙串中。
6/11 接着还需要mobileprovision文件。选择创建profile,然后选择iOS App Development,点击continue。选择上面创建的AppID,选择开发者账号,选择测试设备,然后一路continue,最后输入profile文件名,这里设为pushTest。然后Generate,再下载下来双击即可自动安装到xcode中。
7/11. 在钥匙串中找到刚刚安装的aps_push.cer证书,右键选择导出,然后这里最好把存储文件名修改为英文,然后选择存储。接着要求设置证书密码,这里设置为abc123,然后还要输入管理员密码。搞定这些,所需要的p12文件就OK了。
8/11. 在接下来还要对证书进行整合处理,在终端中进入AppPush文件夹,
然后执行命令openssl x509 -in aps_push.cer -inform der -out PushCert.pem
获得一个PushCert.pem文件。
接着再执行命令openssl pkcs12 -nocerts -in pushTest.p12 -out PushKey.pem
,这时需要输入p12文件的密码,就是上边设置的abc123,然后还要设置PushKey.pem文件的密码,依然设为abc123. 最后获的一个PushKey.pem文件。
然后还有最后一击,执行命令cat PushCert.pem PushKey.pem > ck.pem
获取最终服务器要用的ck.pem文件。
9/11. 经过以上的步骤,所需要的文件都准备好了,但是为了确保完事具备,还要进行简单的测试。
执行命令telnet gateway.sandbox.push.apple.com 2195
,检测是否可以访问apple的推送服务器.显示如下则表明是OK的。(中间需要使用control+c来中断连接)
执行命令openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushCert.pem -key PushKey.pem
测试上面生成的证书是否OK。内容很多,但只用关心最后是否如图所示,是则表示证书是OK的。这里也要输入密码及用control+c中断连接
10/11. 经过上面的繁琐步骤终于准备好素材了。。。。。。开始实际代码开发吧。 新建工程,保证工程的Bundle ID和上边请求证书时使用的Bundle ID一致即可。然后代码的战场在AppDelegate.m中,不涉及其他地方。运行一次程序,从log信息中获取到deviceToken值(注意:如果上面没有安装profile文件,那么也会获取到一个deviceToken值,但是这个值是没卵用的)。
//
// AppDelegate.m
// apnsTest
//
// Created by yuweiMac on 16/4/28.
// Copyright © 2016年 yuweiMac. All rights reserved.
//
#import "AppDelegate.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// 调用该方法有3种路径:点击appIcon或者点击通知进入或者第三方应用跳转。
// 如果点击appIcon进入时launchOptions为nil。其他则 !nil,但两者的key同
if (launchOptions == nil) {
[self showAlertWithTitle:@"由AppIcon启动" msg:[launchOptions description]];
}else{
if ([[launchOptions allKeys] containsObject:@"UIApplicationLaunchOptionsURLKey"]) {
[self showAlertWithTitle:@"由第三方应用启动" msg:[launchOptions description]];
} else {
[self showAlertWithTitle:@"点击通知启动" msg:[launchOptions description]];
}
}
// 注册推送权限.iOS8之前的注册方式不一样,但现在最低兼容ios8,忘了7吧
// if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)])
// {
//IOS8
//创建UIUserNotificationSettings,并设置消息的显示类类型
// 可以通过判断是否已经注册远程通知来决定是否要进行注册操作,这里不这么做。
// if (![application isRegisteredForRemoteNotifications]) {
// 注册通知权限
UIUserNotificationSettings *notiSettings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert) categories:nil];
[application registerUserNotificationSettings:notiSettings];
// 注册远程通知
[application registerForRemoteNotifications];
// }
// } else{ // ios7
// [application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert)];
// }
return YES;
}
-(void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings{
// 成功注册消息通知权限
NSLog(@"成功注册消息通知");
}
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
// 成功注册远程推送并获得deviceToken信息
NSLog(@"didRegisterForRemote---deviceToken-->%@", deviceToken);
}
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
// 注册远程推送失败
NSLog(@"FailToRegisterForRemoteN---fail-->%@",error);
}
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
// 当应用在前台时接收到远程推送消息
[self showAlertWithTitle:@"收到远程推送消息" msg:[userInfo description]];
}
//当从第三方应用跳转到本应用时会调用该方法
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
NSLog(@"-->%@ -->%@",url,sourceApplication);
return YES;
}
//弹出信息警告框
-(void)showAlertWithTitle:(NSString*)title msg:(NSString*)msg{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:nil otherButtonTitles:@"确定",nil];
[alert show];
}
@end
11//11.接下来要写一个AppPush.php文件,来向apns服务器发送内容。
需要注意的几个地方:deviceToken填写你接收到的token;passPhrase则填写你的ck.pem设置的密码。当然如果你在上边保存文件时命名不是ck,那还需要替换程序内的文件名称$pemFile。 最后再在终端中执行命令php AppPush.php
,然后一切都应该很美好的OK了。
$message,
'sound' => 'default'
);
// Encode the payload as JSON
$payload = json_encode($body);
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;
// Close the connection to the server
fclose($fp);
?>