- 首先我们先介绍一下APNs工作原理
1)首先应用程序会将'要发送的消息'和'设备令牌(deviceToken)'打包发给APNs。
2)APNs会在自己已经注册的iphone列表中根据'设备令牌(deviceToken)'查找目标iphone。然后将消息发给目标iphone。
3)iphone会把'消息'发送给相应的程序,并且已设定的方式弹出。
利用PHP,实现一个简单的🌰吧!!!
需要(下面对应的文件名称噢):
php文件 : pushMe.php
certificates : aps_development-7.cer
appID : touteng
provisioning profiles : pp
p12(pem) : push.p12
配置证书:
1、在进行此步骤时,假设已经有了一个appID (此iD不可以是统配的,统配的不可以做推送) , 下载证书名字为 'aps_development-7.cer'
下载证书'双击'导入钥匙串中,假设证书名字是'aps_development-7.cer'.
终端输入: 'openssl x509 -in aps_development-7.cer -inform der -out PushChatCert.pem'//生成的PushChatCert.pem将会和p12生成的pem合成ck.pem
2、配置app IDs
-
创建完成后Configurable 会变成绿色
3、导出p12文件
'创建'并且'下载'然后'双击'证书,进入钥匙串导出名为'push.p12'的文件,导出过程需要输入密码,例如1234
4、生成ck.pem文件
- 配置p12文件:push.p12
终端:'openssl pkcs12 -in pushCert.p12 -out PushChatKey.pem -nodes'
- 合成 'ck.pem'
然后将上一步生成的'PushChatCert.pem'和刚生成的'PushChatKey.pem'合并成'ck.em',我需要通过'ck.pem'进行推送,一般推送不成功与'ck.pem'有关
终端: 'cat PushChatCert.pem PushChatKey.pem > ck.pem'
5、配置pp
6.php文件
该文件参考http://blog.csdn.net/zhugq_1988/article/details/37656107 中的php文件
7.配置php文件
$deviceToken ='你的deviceToken';
$passphrase = '1234';//你设置的密码
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');//生成的pem名字要相同,将你的pem文件和php文件放在同一目录下
8.新建Xcode项目,配置好证书。
在AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)]) {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge|UIUserNotificationTypeAlert|UIUserNotificationTypeSound categories:nil];
[application registerForRemoteNotifications];
[application registerUserNotificationSettings:settings];
} else {
[application registerForRemoteNotificationTypes:UIUserNotificationTypeSound | UIUserNotificationTypeBadge| UIUserNotificationTypeAlert];
}
return YES;
}
添加:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo {
NSLog(@"userInfo : %@", userInfo);
NSLog(@"收到:%@", [[userInfo objectForKey:@"aps"] objectForKey:@"alert"]);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:[[userInfo objectForKey:@"aps"] objectForKey:@"alert"] delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil, nil];
[alert show];
}
// 获取Token
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
//注册成功,将deviceToken保存到应用服务器数据库中
NSMutableString *deviceTokenString1 = [NSMutableString string];
const char *bytes = deviceToken.bytes;
int iCount = deviceToken.length;
for (int i = 0; i < iCount; i++) {
[deviceTokenString1 appendFormat:@"%02x", bytes[i]&0x000000FF];
}
}
// 获取Token失败返回信息
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(@"error : %@", error);
}
9.打开终端,进行推送
'cd'到php文件目录下(确保你的pushMe.php和ck.pem在同一目录下)
终端:php pushMeBaby.php
终端结果如下,你就可以看到手机的推送了:
bogon:~ wang$ cd /Users/wang/Desktop/LLLLLLLLL
bogon:LLLLLLLLL wang$ php pushMeBaby.php
Connected to APNS
Message successfully delivered
bogon:LLLLLLLLL wang$
如果没有看到推送,1检查deviceToken,2看看证书是否正确,3钥匙串里面的证书是否失效了,4php文件配置是否正确。
(我刚开始配置没有成功是因为我的钥匙串里面的证书全部失效了,参考网址:http://blog.csdn.net/manmanking/article/details/50668526)
⚠
-APNS 接口
消息推送:
开发接口:gateway.sandbox.push.apple.com:2195
发布接口:gateway.push.apple.com:2195
反馈服务:
开发接口:feedback.sandbox.push.apple.com:2196
发布接口:产品接口:feedback.push.apple.com:2196
- 手机的deviceToken不是一成不变
- 检验证书是否正确的方法:
$ telnet gateway.sandbox.push.apple.com 2195
Trying 17.172.232.226…
Connected to gateway.sandbox.push-apple.com.akadns.net.
Escape character is ‘^]’.
它将尝试发送一个规则的,不加密的连接到APNS服务。如果你看到上面的反馈,那说明你的MAC能够到达APNS。按下Ctrl C 关闭连接。如果得到一个错误信息,那么你需要确保你的防火墙允许2195端口。
- 然后再次连接,这次用我们的SSL证书和私钥来设置一个安全的连接:
$ openssl s_client -connect gateway.sandbox.push.apple.com:2195
-cert PushChatCert.pem -key PushChatKey.pem
Enter pass phrase for PushChatKey.pem:
你会看到一个完整的输出,让你明白OpenSSL在后台做什么。如果连接是成功的,你可以键入一些字符。当你按下回车后,服务就会断开连接。如果在建立连接时有问题,OpenSSL将会给你一个错误消息,但是你不得不向上翻输出LOG,来找到它。
当然上面要测试prodution版本是否正确的话,把
gateway.sandbox.push.apple.com换成
gateway.push.apple.com就好。
补充:
获取Token 的几种方法:
第一种:
-(NSString *)stringWithDeviceToken:(NSData *)deviceToken
{
const char *data = [deviceToken bytes];
NSMutableString *token = [NSMutableString string];
for (int i = 0; i < [deviceToken length]; i++)
{
[token appendFormat:@"%02.2hhX", data[i]];
}
return [token copy];
}
第二种:
NSString *deviceTokenString2 = [[[[deviceToken description] stringByReplacingOccurrencesOfString:@"<"withString:@""]
stringByReplacingOccurrencesOfString:@">" withString:@""]
stringByReplacingOccurrencesOfString:@" " withString:@""];
第三种:
上述代码中的一种。
忘了参考的那个的网址了,嘿嘿!!
参考:
http://blog.csdn.net/jiajiayouba/article/details/39926017
http://stephen830.iteye.com/blog/1702748
http://blog.csdn.net/studyrecord/article/details/39620377