很久以前写demo,现在回忆下~~~可能有点错误
GIthub:https://github.com/BigShow1949/YFPushTest
步骤:
1)添加APP ID.
苹果开发者中心: Identifiers--->App IDs 添加一个ID,比如我的Name:YFPushTest, 这里的ID一定是项目的Bundle Identifier , 比如:com.YFPushTest.BigShow.YFPushTest;
2)生成苹果推送证书(生产&测试)
取名比如: com.YFPushTest.BigShow.YFPushTest, 选择APP ID的时候,要选择我们刚才创建的那个,不要选其他了的(很多AppID时候,容易忘记)
3)生成描述文件
取名:YFPushTestProfile, 同样, AppID不要选错了
4)上代码:
1 #import "AppDelegate.h" 2 3 @interface AppDelegate () 4 5 @end 6 7 @implementation AppDelegate 8 9 10 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 11 { 12 // application.applicationIconBadgeNumber = 0; 13 14 if ([UIDevice currentDevice].systemVersion.doubleValue >= 8.0) 15 { 16 // 1.请求授权可以给用户发送通知 17 UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert categories:nil]; 18 19 [application registerUserNotificationSettings:settings]; 20 } 21 else 22 { 23 [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound]; 24 } 25 26 if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) 27 { 28 // 跳转 29 } 30 31 return YES; 32 } 33 34 35 /** 36 * 远程推送注册成功 37 * 38 * @param deviceToken deviceToken 39 */ 40 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 41 { 42 // 25bb75ac 3ffcebd7 90d9f517 1ebca904 154a367a 87781e5d b9ea288e 37fdf487 43 NSLog(@"-----deviceToken ---- ---- %@ devDesc ---%@", deviceToken,deviceToken.description); 44 45 //tokenStr 得到可用的token。 46 NSString *tokenStr = [NSString stringWithFormat:@"%@",deviceToken]; 47 tokenStr = [tokenStr stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];//将其中的<>去掉 48 tokenStr = [tokenStr stringByReplacingOccurrencesOfString:@" " withString:@""];//将其中的空格去掉 49 50 NSLog(@"token--- %@",tokenStr); 51 // //注册成功,返回token 52 // UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"APNS返回的Token:" message:tokenStr delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil]; 53 // 54 // [alert show]; 55 56 // applicationIconBadgeNumber 57 } 58 59 60 /** 61 * 注册失败 62 * 63 */ 64 - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error 65 { 66 67 NSLog(@"注册失败 ---- %@",error); 68 NSString *tokenStr = [NSString stringWithFormat:@"%@",error]; 69 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"注册失败!" message:tokenStr delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil]; 70 [alert show]; 71 NSLog(@"注册失败%@",error); 72 73 74 }//NS_AVAILABLE_IOS(3_0); 75 76 77 78 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 79 { 80 NSLog(@"接收到推送通知 ---- %@", userInfo); 81 82 /* 83 84 "name" : "YFPushTest", 85 "action_type" : "1", 86 "message" : "您的车辆京KKKKKK于2016-4-22 驶入邯郸", 87 "aps" : { 88 "alert" : "This is some fancy message.", 89 "badge" : 1, 90 "sound" : "您的车辆京KKKKKK于2016-4-22 驶入邯郸" 91 }; 92 93 */ 94 95 // application.applicationIconBadgeNumber -=1; 96 //将推送消息以alert形式呈现 97 NSString *message = [[userInfo objectForKey:@"aps"]objectForKey:@"alert"]; 98 99 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:message delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil]; 100 101 [alert show]; 102 } 103 104 105 // This callback will be made upon calling -[UIApplication registerUserNotificationSettings:]. The settings the user has granted to the application will be passed in as the second argument. 106 - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings 107 { 108 109 NSLog(@"ls---- %@",notificationSettings); 110 111 // 2.注册远程通知 112 [application registerForRemoteNotifications]; 113 114 }//NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED; 115 116 117 // Called when your app has been activated by the user selecting an action from a remote notification. 118 // A nil action identifier indicates the default action. 119 // You should call the completion handler as soon as you've finished handling the action. 120 - (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void(^)())completionHandler 121 { 122 123 NSLog(@"ios9新增 --- %@ -- %@ --- %@",identifier,userInfo,responseInfo); 124 125 126 }//NS_AVAILABLE_IOS(9_0) __TVOS_PROHIBITED; 127 128 129 // Called when your app has been activated by the user selecting an action from a remote notification. 130 // A nil action identifier indicates the default action. 131 // You should call the completion handler as soon as you've finished handling the action. 132 - (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler 133 { 134 135 NSLog(@"ios8新增 --- %@ -- %@ --- %@",identifier,userInfo,application); 136 137 138 }//NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED; 139 140 141 142 143 @end
5)都搞好了,我们得模拟发推送。这里我们用这个测试程序:https://github.com/shaojiankui/SmartPush 把我们刚刚生成的推送证书下载下来, 然互拖过来:
然后连接服务器,再点击推送就OK~~~~~~
可能出现的问题:
1)注册失败Error Domain=NSCocoaErrorDomain Code=3000 "未找到应用程序的“aps-environment”的授权字符串"
这是因为推动证书设置错误了.而且会调用 远程推送注册失败这个方法(- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error);首先检查:三个证书的APPID是否是对的;三个证书是否都双击安装了;APPID的ID是否为项目的Bundle Identifier; 基本也就这些情况吧, 有其他情况的可以评论补充.
6) 生成p12文件或者pem文件给后台
苹果原生推送参考文档:http://superdanny.link/2016/02/02/iOS-Apple-Push-Notification-Service/
PHP需要的.pem 证书:
1.cd 到推送证书所在文件夹
2.把 .cer 的 SSL 证书转化为 .pem 文件(就是在Mac上生成的本地证书)
测试:openssl x509 -in aps_development.cer -inform der -out PushChatCert.pem
生产:openssl x509 -in aps_distribution.cer -inform der -out PushChatCert_distribution.pem
3.把私钥 .p12 文件转化为 .pem 文件
测试:openssl pkcs12 -nocerts -out PushChatKey.pem -in aps_development.p12
生产:openssl pkcs12 -nocerts -out PushChatKey_distribution.pem -in aps_distribution.p12
Enter Import Password:
MAC verified OK
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
4.对生成的两个pem 文件再生成一个pem文件,来把证书和私钥整合到一个文件里
cat PushChatCert.pem PushChatKey.pem > ck.pem
5.测试证书是否正确
telnet gateway.sandbox.push.apple.com 2195
Trying 17.110.226.164...
Connected to gateway.sandbox.push-apple.com.akadns.net.
Escape character is '^]'.
Connection closed by foreign host.
它将尝试发送一个规则的,不加密的连接到APNS服务。如果你看到上面的反馈,那说明你的MAC能够到达APNS。按下Ctrl+C关闭连接。如果得到一个错误信息,那么你需要确保你的防火墙允许2195端口。一般这里都不会出现什么问题
6.使用我们生成的SSL证书和私钥来设置一个安全的链接去链接苹果服务器:
测试:openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushChatCert.pem -key PushChatKey.pem
生产:openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushChatCert_distribution.pem -key PushChatKey_distribution.pem
你会看到一个完整的输出,让你明白OpenSSL在后台做什么。如果链接是成功的,你可以随便输入一个字符,按下回车,服务器就会断开链接,如果建立连接时有问题,OpenSSL会给你返回一个错误信息。
Java/.Net需要的.p12证书
需要一个 .cerSigningRequest(csr)文件
测试:
openssl pkcs12 -export -in PushChatCert.pem -inkey PushChatKey.pem -certfile aps_development.cer -name “PushChat_Development” -out PushChat_Development.p12
生产:
openssl pkcs12 -export -in PushChatCert_distribution.pem -inkey PushChatKey_distribution.pem -certfile aps_distribution.cer -name “PushChat_Distribution” -out PushChat_Distribution.p12
输出下面语句说明成功:
Enter pass phrase for PushChatKey.pem:
Enter Export Password:
Verifying - Enter Export Password:
APNS地址
测试地址gateway.sandbox.push.apple.com:2195
发布地址 gateway.push.apple.com:2195
测试的地址用的是沙盒,发布地址是不同的。发布软件的时候记得改过来
Easy APNS为开发者提供了一种很直观的可以用来控制整个 推送通知后端部分的方式。
模拟推送一:通过终端推送
PHP:
1.php push.php
2.结果为:
Connected to APNS Message successfully delivered
模拟推送二:通过工具推送 Github 上下载推送工具 NWPusher
注意:当上线产品推送证书过期时,不要惊慌,我们不需要更新推送证书之后重新提交 AppStore 。只需要替换服务器端的推送证书即可(记得重启服务器,不然推送在测试环境下有效,但是在真实环境下是无效的)。 |