鉴于server稳定的开发难度非常大,小团队不建议自己开发。建议使用稳定的第三方推送方案,如个推,蝴蝶等。

要想使用苹果APNS推送消息,首先要把开发app的xcode所用证书上传到server上,当然你的证书要用的是hot证书或勾选push选项的公布者。普通研发者证书是收不到push消息的。

client设置

开启Remote notifications

须要在Xcode 中改动应用的 Capabilities 开启Remote notifications,请參考下图:



安装证书到服务端

你应该安装SSL证书和私匙到你的provider程序执行的server上。

过程例如以下:

0.安装该证书到mac电脑的钥匙串。

1.打开钥匙串,在左側面板上点击我的证书栏。

2.找到这个SSL证书。展开会看到证书和私匙。

3.我们选中证书和私匙,然后导出为”个人信息交换文件”–即扩展名为p12的文件。

4.providerserver程序最好用Ruby和Perl这类语言。能够方便的处理”个人信息交换文件”里的证书。mac下打开终端输入以下命令以把证书转换为这类语言乐于交流的格式:

openssl pkcs12 -in CertificateName.p12 -out CertificateName.pem -nodes

5.把这pem文件拷到server上并安装到某个适当的位置。

说完服务端了就详细说client吧,首先在AppDelegate.m(AppDelegate.mm)文件里的- (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions增加[AppDelegate registerForRemoteNotification];来又一次获取设备相关的token。不要缓存token.

当注销时,本账户在别的设备上登陆时(被踢掉)或者捕获到被拉掉事件时(- (void)applicationWillTerminate:(UIApplication *)application)须要取消推送的注冊,代码如[[UIApplication sharedApplication] unregisterForRemoteNotifications];//用户退出登录后,取消推送的注冊,登录时register。当然退出到登陆页面后登陆成功后还时须要又一次进行推送的注冊。

在didReceiveRemoteNotification能够处理收到的消息,能够仅仅记录到全局变量里临时不操作。也能够播放铃声。震动。弹出对话框。跳转页面等。像这个版本号更新的push消息处理就没有告知用户 if([type isEqualToString:@”psy_needUpgrade”])

{

NSString *url = [page objectForKey:@”downloadUrl”];

if(url != nil)

{

g_needUpgrade = 1;

g_downloadUrl = url;

}

return;

}

以下这段代码是对接收的push消息进行处理。

  1. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
  2. {
  3. FLDDLogDebug(@"push userinfo:%@", userInfo);
  4. NSDictionary *aps = [userInfo objectForKey:@"aps"];
  5. NSInteger count = [[aps objectForKey:@"badge"] toInt];
  6. [application setApplicationIconBadgeNumber:count];
  7. NSString *alert = [aps objectForKey:@"alert"];
  8. NSDictionary *page = [userInfo objectForKey:@"page"];
  9. NSString *actionId = [page objectForKey:@"id"];
  10. NSString *type = [page objectForKey:@"type"];
  11. NSString *title = [page objectForKey:@"title"];
  12. NSString *notifyType = [[page objectForKey:@"notifyType"] toString];
  13. NSString *subType = [[page objectForKey:@"subType"] toString];
  14. NSString *subId = [[page objectForKey:@"subId"] toString];//app消息相应的订单id
  15. NSString *phone = [page objectForKey:@"userTel"];
  16. NSString *userPhone = [User currentUser].phone;
  17. if (![phone isEqualToString:userPhone]) {
  18. return;
  19. }
  20. if([type isEqualToString:@"psy_needUpgrade"])
  21. {
  22. NSString *url = [page objectForKey:@"downloadUrl"];
  23. if(url != nil)
  24. {
  25. g_needUpgrade = 1;
  26. g_downloadUrl = url;
  27. }
  28. return;
  29. }
  30. if ([notifyType isEqualToString:@"1"]) {
  31. type = kFhlappnotify;
  32. }
  33. else if ([notifyType isEqualToString:@"2"]){
  34. type = kFhlordernotify;
  35. }
  36. if ([type isEqualToString:kFhlGrab]) {
  37. //set home refresh tag
  38. [[NSNotificationCenter defaultCenter] postNotificationName:REFRESH_HOME_NOTIFICATION object:nil];
  39. }
  40. if (application.applicationState == UIApplicationStateActive) {
  41. [application setApplicationIconBadgeNumber:0];
  42. if ([AppManager boolValueForKey:@"shock"]) {
  43. AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
  44. }
  45. else {
  46. [self playAudioWithIndex:type];
  47. }
  48. if ([type isEqualToString:kFhllogout]) {
  49. g_loginStat = LOGIN_STATE_EXIT_LOGIN;
  50. // [AppManager saveCurrentOrderRemind];
  51. [[UIApplication sharedApplication] unregisterForRemoteNotifications];
  52. [[User currentUser] removeUserInfo];
  53. [AppManager setUserDefaultsValue:@"" key:@"telephone"];
  54. [AppManager setUserDefaultsValue:@"" key:@"password"];
  55. UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil
  56. message:alert
  57. delegate:self
  58. cancelButtonTitle:@"确定"
  59. otherButtonTitles:nil, nil];
  60. alertView.tag = 1005;
  61. [alertView show];
  62. }
  63. else if ([type isEqualToString:kFhlGrab]) {
  64. //set home refresh tag
  65. // [AppManager setUserBoolValue:YES key:@"NeedRefreshHome"];
  66. }
  67. else if ([type isEqualToString:kFhlSend] || [type isEqualToString:kFhlReceived]) {
  68. // Order *order = [[Order alloc] init];
  69. // order.id = actionId;
  70. // [[NSNotificationCenter defaultCenter] postNotificationName:REFRESH_ORDER_NOTIFICATION object:nil userInfo:@{@"Order" : order, @"Option" : @(3)}];
  71. }
  72. else if ([type isEqualToString:kFhlBeAppoint]) {
  73. Order *order = [[Order alloc] init];
  74. order.id = subId;
  75. [[NSNotificationCenter defaultCenter] postNotificationName:REFRESH_ORDER_NOTIFICATION object:nil userInfo:@{@"Order" : order, @"Option" : @(3)}];
  76. }
  77. else {
  78. if ([subType isEqualToString:kFhlSubClosed] || [subType isEqualToString:kFhlSubRejected]) {
  79. Order *order = [[Order alloc] init];
  80. order.id = subId;
  81. if ([subType isEqualToString:kFhlSubRejected]) {
  82. order.state = @"50";
  83. }
  84. [[NSNotificationCenter defaultCenter] postNotificationName:REFRESH_ORDER_NOTIFICATION object:nil userInfo:@{@"Order" : order, @"Option" : @(3)}];
  85. }
  86. if ([type isEqualToString:kFhlcancel]) {
  87. Order *order = [[Order alloc] init];
  88. order.id = actionId;
  89. [[NSNotificationCenter defaultCenter] postNotificationName:REFRESH_ORDER_NOTIFICATION object:nil userInfo:@{@"Order" : order, @"Option" : @(4)}];
  90. }
  91. UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
  92. message:alert
  93. delegate:self
  94. cancelButtonTitle:@"忽略"
  95. otherButtonTitles:@"进入", nil];
  96. if (type.length > 0 && actionId.length > 0) {
  97. objc_setAssociatedObject(alertView, &AlertAssociatedKey,@{@"type" : type, @"actionId" : actionId}, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  98. }
  99. [alertView show];
  100. }
  101. }
  102. else if (application.applicationState == UIApplicationStateInactive){
  103. [self pushViewControllerWithType:type actionId:actionId];
  104. }
  105. }

以下这断代码就是详细的推送的注冊:

“`

+ (void)registerForRemoteNotification {

  1. FLDDLogDebug(@"*\n*\n*\nregisterForRemoteNotification\n*\n*\n*\n");
  2. if (IOS8_OR_LATER) {
  3. UIUserNotificationType types = UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIRemoteNotificationTypeNewsstandContentAvailability;
  4. UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
  5. [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
  6. } else {
  7. [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeNewsstandContentAvailability)];
  8. }

}

苹果APNS在app中的详细实现的更多相关文章

  1. 手把手教你配置苹果APNS推送服务|钿畑的博客 | 钿畑的博客

    http://www.360doc.com/content/15/0118/17/1073512_441822850.shtml# 钿畑的文章索引 1. 什么是推送通知 2. 什么是APNS? 3. ...

  2. 苹果开发之App签名

    如果你的Apple ID账号(可使用邮箱来注册)为Apple developer类型的话,登录之后是看不到Certificates, Indentifiers & Profiles信息的 Ap ...

  3. iOS开发之功能模块--Apns推送中的的json格式介绍

    在开发向苹果Apns推送消息服务功能,我们需要根据Apns接受的数据格式进行推送.下面接受我在进行apns推送时候总结的一点apns服务接受的Json数据格式 示例 1: 以下负载包含哦一个简单的 a ...

  4. 我刚知道的WAP app中meta的属性

    之前我一直做的都是WEB前端开发,来北京以后面试了一个移动前端开发,WAP前端开发. 其实在原来公司的时候也做过这方面的开发,可面试的时候面试官问我,要想强制让文档与设备的宽度保持1:1,mate标签 ...

  5. 我刚知道的WAP app中meta的属性(转载)

    之前我一直做的都是WEB前端开发,来北京以后面试了一个移动前端开发,WAP前端开发. 其实在原来公司的时候也做过这方面的开发,可面试的时候面试官问我,要想强制让文档与设备的宽度保持1:1,mate标签 ...

  6. Apns推送中的的json格式介绍

    在开发向苹果Apns推送消息服务功能,我们需要根据Apns接受的数据格式进行推送.下面接受我在进行apns推送时候总结的一点apns服务接受的Json数据格式 示例 1: 以下负载包含哦一个简单的 a ...

  7. App Transfer:苹果允许iOS App从一个开发者帐号转至另一个开发者账号

    App Transfer:苹果允许iOS App从一个开发者帐号转至另一个开发者账号 苹果在WWDC上宣布超过30万的开发者为iOS平台开发超过90万的应用,你可能会想到有人想出售或者购买app. 现 ...

  8. 苹果开发——向App Store提交应用

    原地址:http://zengwu3915.blog.163.com/blog/static/2783489720137410539278/ 完成一个app应用后,肯定是要提交的,下面聊一下关于向Ap ...

  9. 在APP中集成iAd Banner展示广告盈利

    如果你已经做了一款超牛X的APP.你也许还有一件是需要操心.APP够好了,怎么盈利呢?你可以对下载你的APP的用户收费.也可以完全的免费,然后在APP里放广告来实现盈利.现在来说,除非一款APP真的是 ...

随机推荐

  1. 63.C++异常

    #include <iostream> using namespace std; //异常与错误不一样,异常一般能正常工作 //错误就是程序无法正常工作,无法编译 //异常让程序在错误的输 ...

  2. 关于SQL分页存储过程的分析

    建 立一个 Web 应用,分页浏览功能必不可少.这个问题是数据库处理中十分常见的问题.经典的数据分页方法是:ADO 纪录集分页法,也就是利用ADO自带的分页功能(利用游标)来实现分页.但这种分页方法仅 ...

  3. 洛谷P2251 质量检测

    题目背景 无 题目描述 为了检测生产流水线上总共N件产品的质量,我们首先给每一件产品打一个分数A表示其品质,然后统计前M件产品中质量最差的产品的分值Q[m] = min{A1, A2, ... Am} ...

  4. API集合开发文档

    百度翻译api https://www.cnblogs.com/DevilX5/p/7079470.html 实现QQ第三方登录.网站接入 http://blog.csdn.net/u01067894 ...

  5. javafx HTMLEditor

    public class EffectTest extends Application { //===================== private final String INITIAL_T ...

  6. mac: brew的删除

    ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)" ...

  7. Java中Webservice调用.NET天气接口生成客户端异常

    学习webservice时候有个例子调用公网的天气预报接口实现查询天气的功能.然而在使用命令编译客户端代码的时候出错了.大概看了一下网上说是需要将将文件中所有出现的 < s:element re ...

  8. 计算机视觉(ComputerVision, CV)相关领域的站点链接

    关于计算机视觉(ComputerVision, CV)相关领域的站点链接,当中有CV牛人的主页.CV研究小组的主页,CV领域的paper,代码.CV领域的最新动态.国内的应用情况等等. (1)goog ...

  9. 将字符串使用md5加密

    >>> import md5 >>> md5.md5('123').hexdigest() '202cb962ac59075b964b07152d234b70' & ...

  10. android-LinearLayout 控件占满父容器位置实现

    经常碰到需要把一个控件放在手机底部的情况,以前都是在LinearLayout尝试使用gravity="bottom" ,但是,没有效果,后来在网上查到了方法,如下 <Line ...