参考来自:http://blog.csdn.net/shenjie12345678/article/details/41120637
如果还有不明白的地方 可以 结合http://www.open-open.com/lib/view/open1431566847716.html 学习。
用推荐方式去实现更好!之后的内容是我的学习过程,方便理解。同样也可以实现
推荐方式: http://blog.csdn.net/think12/article/details/8863411 from同事推荐[将文件的命名与文中保持一致,后面的命令行直接copy打印即可]
经验:只要正确下载好了配置文件和证书,在发送测试推送的时候 直接在命令行执行 php文件即可
注意事项:
* 在程序中注册推送的时候一定要区分系统版本 IO8之前和之后的注册方式是不同的!!!![见下面的绿色背景代码]
注册推送的目的是想apns发送本应用的id和bundle,注册成功后apns会返回devicetoken
devicetoken 并不是是唯一的,deviceToken的生成方式就是手机id+应用的bundle,测试版 和 发布版的deviceToken也不一样
1、主要注意证书、AppID、配置文件的设置和命名的规范【这个命名规范非常重要!格式错了 下面的整个过程结束后也得不到预期的结果】
1.2例如 在AppID的命名时 bundle的命名应该为 com.xxx.项目名称如下图
Provider是给你手机应用发出推送消息的服务器,而APNS(Apple Push Notification Service)则是苹果消息推送服务器。你本地的服务器当需要给应用推送一条消息的时候,先要将消息发出到苹果推送服务器,然后再由苹果推送服务器将消息发到安装了该应用的手机。
接下来再看一张解释图:
根据上图的逻辑我来给大家解释一下:
1.你的IOS应用需要去注册APNS消息推送功能。
2.当苹果APNS推送服收到来自你应用的注册消息就会返回一串device token给你(很重要)
3.将应用收到的device Token传给你本地的Push服务器。
4.当你需要为应用推送消息的时候,你本地的推送服务器会将消息,以及Device Token打包发送到苹果的APNS服
5.APNS再将消息推送给目的iphone
第二部分
1.从证书颁发机构颁发证书
打开你mac的钥匙串访问 然后点击钥匙串访问
用户电子邮件信息
就填写你苹果开发者账号的名称即可(应该是一个邮件名称),点击保存到磁盘的选项,点击继续,显示如下
点击存储,文件名为:CertificateSigningRequest.certSigningRequest 随后将他放在一个文件夹中我们取名push吧!
第三部分
访问苹果开发者网址:https://developer.apple.com/
选中MemberCenter选项,进入登陆页面,用你的苹果开发者账号登陆,过一会网页就会自动跳转到下图。点击红色所选部分
内容进行下一步的操作。
选择Certificates选项,设置证书,如图所示先解释一下
Development选项的作用顾名思义就是用来作为开发使用的证书,Production选项则
是用来发布产品使用的,名称很陌生是不是,之前的开发者网页是没有这一选项的,可能是苹果把他修改了,用这个名称更加能让人
理解吧(字面上解释就是产品么)。两个选项生成证书的步骤是一样的,现在我们使用开发者的选项进行证书的制作,步骤如下:
选择Development选项
点击上面的加号选项,
选择APNS选项(开发么当然是在沙盒环境下了,模拟真实情况),然后Continue
这个AppID我们在下一部分讲如何生成,现在我用的是已经生成好的一个应用ID,继续Continue
这边就要选择在钥匙串访问环节下载下来的CertificateSigningRequest.certSigningRequest文件了,选择并生成
点击下载,得到aps_development .cer,保存到push文件中去。
第四部分
新建一个AppID,选择网页上的AppIDs,然后点击右上角的 “加号”
App的取名只要按照苹果要求的就可以了
然后BundleID是比较重要的,在提交审核以及测试(苹果的TestFlight)和付费环节都需要用到,也只需按照苹果要求来写就好了。
接下来就是对你的应用需要使用苹果的哪些服务进行选择就行了,例如广告,游戏中心,推送,付费等等情况。
最后选择“Submit”选项,在下一个界面中选择“done”选项,这样我们设置AppID的步骤我们就完成了。
第五部分:生成Provisioning Profiles
这个配置概要文件分为两种,一种是为开发使用的,还有一种则是为发布到appStore上面。
创建发布版的ProvisioningProfile与开发版的流程相同,点击Development然后点击右上角的加号
会进入选择何种配置概要文件的界面
我们现在时测试,所以选择“IOS App Development”的选项,在下面的Distribution发布选项中有两个选择,“App Store”以及“Ad hoc”,你可以根据下面的描述
选择你发布所需的选项。点击Continue进入下一步。
选择你上一步创建的AppID,点击Continue 进行下一步
选择你的开发者账号,Continue进行下一步
在这一步上选择你的设备(你只有在这一步上勾选了你的设备,你才能在设备上用这个签名进行调试)。关于如何将你的设备号添加进去也是非常
简单的,选择左侧的"Devices",然后点击右上角的加号,在随后出来的页面上添加你设备的UUID(在XCode中可以查看到)以及name( 可以随便取,自己看的懂就行)
然后Register一下,照着流程走到最后一步就完成了。
好咋们继续回到上面的Provisioning Profile配置环节,当你选好了你的设备后点击“Continue”进入下一页,
输入一个文件名(最好是起的能看懂是干嘛的,当然也可以随便起),点击“Generate”进入下一个页面,在这个页面中就会有一个下载按钮让你下载这个文件,
我们把它下载下来放在Push文件夹中。
第六部分
好了,前期的准备工作都已经做完了,现在让我们开始推送吧!(吼吼)
首先双击我们生成的 “aps_development .cer” 文件,进入钥匙串访问,找到我们的专用秘钥(根据在第二部分中从证书机构颁发证书操作中填写的常用名)
我在第二部分填写的是“silicon”,由于换了一台mac之前安装的没有了,之前没有截图,所以随便找了个图给大家看一下,凭大家的聪明才智应该不难理解吧。
然后右击导出,会弹出如下所示的图。
将他存储到push文件夹中,命名为“push.p12”,在这一步中导出会让你输入密码并验证,你可以自定义一个密码,例如abc123
现在push文件夹中应该有几个文件“aps_development .cer” ,"push.p12",“CertificateSigningRequest.certSigningRequest”以及刚才下下来的配置概要文件。
接下来我们打开终端将他们生成.pem文件
1.把aps_development .cer文件生成.pcm文件,cd到push文件夹下
2.把push.p12文件生成为.pem文件
上边输入的密码则是你导出证书所设的密码,即abc123.接着还会让你输入.pem文件的密码,还是使用abc123好了,防止混淆。
这样我们在push文件夹中就又得到了两个文件,PushChatCert.pem和PushChatKey.pem。
3.把PushChatCert.pem和PushChatKey.pem合并为一个pem文件,
在push文件夹中又多了一个ck.pem文件,以上我们把需要使用的文件都准备好了
接下来就要测试一下啦,是不是很激动~
为了测试证书工作的状况,我们可以使用“telnet gateway.sandbox.push.apple.com 2195”来检测一下,如果显示
则表示成功了。
然后,我们使用我们生成的证书和私钥来设置一个安全的链接去链接苹果服务器
在终端输入如下命令:openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushChatCert.pem -key PushChatKey.pem
需要输入密码(abc123 我们刚才所设置的)。
然后他会返回一系列的数据,这里我就粘贴一部分啦:
CONNECTED(00000003)
depth=1 /C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
。。。。。(省略)
。。。。。(省略)
。。。。。(省略)
Start Time: 1416389389
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
测试就到这里啦。。。
第七部分
1.建立推送项目
在appdelegate.m中加入以上代码,
由于ios8的推送跟ios7及以下的不一样,所以需要加判断来注册消息推送。
函数:
会接收来自苹果服务器给你返回的deviceToken,然后你需要将它添加到你本地的推送服务器上。(很重要,决定你的设备能不能接收到推送消息)。
这个函数则是当设备接收到来自苹果推送服务器的消息时触发的,用来显示推送消息。
当注册失败时,触发此函数。
2.PHP服务端
将simplepush.php这个推送脚本也放在push文件夹中
deviceToken填写你接收到的token,passPhrase则填写你的ck.pem设置的密码。
此刻就是见证奇迹的时候了
使用终端进入到push文件夹,在终端输入 php simplepush.php
若显示以上提示则表示推送成功了。
附上一张成功图。
感谢这篇博客的指导:http://blog.csdn.net/showhilllee/article/details/8631734
本文着重叫在App端如何处理推送信息。主要涉及一下几个比较重要的函数,而这些函数都是AppDelegate类中:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
做过iOS 开发的人对这个函数都会很熟悉,这是在程序结束启动,并即将运行时调用的,通常一些初始化的工作可以在这个函数中处理。同样的,推送的相关初始化操作也需要在这个部分完成。这一部分的工作主要分为两部分: 推送类型的注册:
1
|
[[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound | UIRemoteNotificationAlert];
|
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 或者:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
中完成。但是如果用户点击推送通知的时候程序还没有被启动,这个时候以上两个函数都是接收不到用户的推送通知的,这个时候需要在application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*) launchOptions 函数里面进行处理。而推送消息的相关信息就存储在launchOptions这个字典里。具体参照如下代码:
1
2
3
4
5
6
7
8
9
10
|
NSDictionary* pushInfo = [launchOptions objectForKey:@ "UIApplicationLaunchOptionsRemoteNotificationKey" ];
if (pushInfo)
{
NSDictionary *apsInfo = [pushInfo objectForKey:@ "aps" ];
if (apsInfo)
{
//your code here
}
}
|
- (void)application:(UIApplication *)applicationdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)pToken & - (void)application:(UIApplication *)applicationdidFailToRegisterForRemoteNotificationsWithError:(NSError *)error
为了让device端可以接收到推送消息,需要将设备的token传送到苹果的服务器,这个token就相当于设备的识别码,每一台苹果设备都有唯一的token,苹果的服务器就是通过这个token找到对应的设备,并传送相应地消息。这两个函数就是在传送token成功或者失败后调用的,用户在对应的函数里面做一些相应地处理。- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo和
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
都是程序在运行过程中(无论当前程序处于前台还是后台)接收到推送消息的处理函数。根据苹果的官方文档,建议大家使用
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
因为前者在程序处于后台的时候是无法接收到推送信息的(经实测-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo其实可以接收到,不知道是怎么回事,希望大虾解疑)。另外就是-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler 还有一个作用。根据苹果给出的文档,系统给出30s的时间对推送的消息进行处理,此后就会运行CompletionHandler程序块。
在处理这类推送消息(即程序被启动后接收到推送消息)的时候,通常会遇到这样的问题,就是当前的推送消息是当前程序正在前台运行时接收到的还是说是程序在后台运行,用户点击系统消息通知栏对应项进入程序时而接收到的?这个其实很简单,用下面的代码就可以解决:
1
2
3
4
5
6
7
8
9
10
11
12
|
void
application:(UIApplication*)application didReceiveRemoteNotification:NSDictionary)userInfo fetchCompletionHandler:((^)UIBackgroundFetchResult)completionHandler{
if
(application.applicationState == UIApplicationStateActive) {
NSLog(@
"active"
);
//程序当前正处于前台
}
else
if
(application.applicationState == UIApplicationStateInactive)
{
NSLog(@
"inactive"
);
//程序处于后台
}
}
|