鉴于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消息进行处理。

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
FLDDLogDebug(@"push userinfo:%@", userInfo); NSDictionary *aps = [userInfo objectForKey:@"aps"]; NSInteger count = [[aps objectForKey:@"badge"] toInt];
[application setApplicationIconBadgeNumber:count]; NSString *alert = [aps objectForKey:@"alert"];
NSDictionary *page = [userInfo objectForKey:@"page"];
NSString *actionId = [page objectForKey:@"id"];
NSString *type = [page objectForKey:@"type"];
NSString *title = [page objectForKey:@"title"];
NSString *notifyType = [[page objectForKey:@"notifyType"] toString];
NSString *subType = [[page objectForKey:@"subType"] toString];
NSString *subId = [[page objectForKey:@"subId"] toString];//app消息相应的订单id
NSString *phone = [page objectForKey:@"userTel"]; NSString *userPhone = [User currentUser].phone;
if (![phone isEqualToString:userPhone]) {
return;
} if([type isEqualToString:@"psy_needUpgrade"])
{
NSString *url = [page objectForKey:@"downloadUrl"];
if(url != nil)
{
g_needUpgrade = 1;
g_downloadUrl = url;
}
return;
} if ([notifyType isEqualToString:@"1"]) {
type = kFhlappnotify;
}
else if ([notifyType isEqualToString:@"2"]){
type = kFhlordernotify;
} if ([type isEqualToString:kFhlGrab]) {
//set home refresh tag
[[NSNotificationCenter defaultCenter] postNotificationName:REFRESH_HOME_NOTIFICATION object:nil];
} if (application.applicationState == UIApplicationStateActive) { [application setApplicationIconBadgeNumber:0]; if ([AppManager boolValueForKey:@"shock"]) {
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); }
else {
[self playAudioWithIndex:type];
} if ([type isEqualToString:kFhllogout]) {
g_loginStat = LOGIN_STATE_EXIT_LOGIN; // [AppManager saveCurrentOrderRemind]; [[UIApplication sharedApplication] unregisterForRemoteNotifications];
[[User currentUser] removeUserInfo];
[AppManager setUserDefaultsValue:@"" key:@"telephone"];
[AppManager setUserDefaultsValue:@"" key:@"password"]; UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil
message:alert
delegate:self
cancelButtonTitle:@"确定"
otherButtonTitles:nil, nil];
alertView.tag = 1005;
[alertView show]; }
else if ([type isEqualToString:kFhlGrab]) {
//set home refresh tag // [AppManager setUserBoolValue:YES key:@"NeedRefreshHome"];
}
else if ([type isEqualToString:kFhlSend] || [type isEqualToString:kFhlReceived]) {
// Order *order = [[Order alloc] init];
// order.id = actionId;
// [[NSNotificationCenter defaultCenter] postNotificationName:REFRESH_ORDER_NOTIFICATION object:nil userInfo:@{@"Order" : order, @"Option" : @(3)}]; }
else if ([type isEqualToString:kFhlBeAppoint]) { Order *order = [[Order alloc] init];
order.id = subId; [[NSNotificationCenter defaultCenter] postNotificationName:REFRESH_ORDER_NOTIFICATION object:nil userInfo:@{@"Order" : order, @"Option" : @(3)}]; }
else { if ([subType isEqualToString:kFhlSubClosed] || [subType isEqualToString:kFhlSubRejected]) { Order *order = [[Order alloc] init];
order.id = subId; if ([subType isEqualToString:kFhlSubRejected]) {
order.state = @"50";
} [[NSNotificationCenter defaultCenter] postNotificationName:REFRESH_ORDER_NOTIFICATION object:nil userInfo:@{@"Order" : order, @"Option" : @(3)}];
} if ([type isEqualToString:kFhlcancel]) { Order *order = [[Order alloc] init];
order.id = actionId; [[NSNotificationCenter defaultCenter] postNotificationName:REFRESH_ORDER_NOTIFICATION object:nil userInfo:@{@"Order" : order, @"Option" : @(4)}]; } UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
message:alert
delegate:self
cancelButtonTitle:@"忽略"
otherButtonTitles:@"进入", nil];
if (type.length > 0 && actionId.length > 0) {
objc_setAssociatedObject(alertView, &AlertAssociatedKey,@{@"type" : type, @"actionId" : actionId}, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } [alertView show];
}
}
else if (application.applicationState == UIApplicationStateInactive){
[self pushViewControllerWithType:type actionId:actionId];
}
}

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

“`

+ (void)registerForRemoteNotification {

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

}

苹果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. 项目: 更新(二) python 实现大概FTP的功能

    服务器利用 socketserver 模块 构造, 实现了 多进程. 客户端仍然利用的是底层的 socket模块. 只不过进行了更深度的 解耦, 新加或者删除 某些功能 更方便 在上一个版本的基础上, ...

  2. K短路 spfa + A*

    #include <stdio.h> #include <string.h> #include <queue> #include <algorithm> ...

  3. ip---查看网络信息

    Linux的ip命令和ifconfig类似,但前者功能更强大,并旨在取代后者. ifconfig属于net-tools.ip属于iproute2 设置一个IP地址,可以使用下列ip命令: ip add ...

  4. 火狐—火狐浏览器中的“HttpWatch”

    在IE下通过HttpWatch能够查看HTTP请求的相关细节.这对我们分析程序的运行效率很有帮助,但是在火狐浏览器中的难道就没有相似的工具了吗?答案是否定的--火狐浏览器中也有.在火狐浏览器中该工具叫 ...

  5. 杭电(hdu)2053 Switch Game 水题

    Switch Game Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  6. TimePickerDialog -下划线颜色修改

    首先就是去framework下去找与之相关的theme属性 最开始的时候,直接找的是<item name="datePickerStyle">@style/Widget ...

  7. Javascript 继承和克隆

    个人总结: call 继承的是父类私有 prototype 继承的父类公有 create 可以将公有或私有继承到子类上去(克隆) for in 克隆 不管公有还是私有的都克隆成私有的 1.原型继承:将 ...

  8. C#监控代码运行的时间

    System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); //开始监视代码运行时间 ...

  9. Servlet 规范笔记—基于http协议的servlet

    在上一章节,我们大概的描述了servlet的规范以及servlet和servlet容器的概念和用途,我们清楚的知道servlet容器提供了接收来自client端的请求,然后根据请求进行处理(如:执行对 ...

  10. NIO专栏学习

    http://blog.csdn.net/column/details/12993.html