ios推送_ios推送通知 - CSDN
  • ios中的推送功能实现

    2018-07-31 18:15:24
    图中,Provider是指某个iPhone软件的Push服务器,这篇文章我将使用百度云推送服务作为Provider。 APNS 是Apple Push Notification Service(Apple Push服务器)的缩写,是苹果的服务器。 上图可以分为三个阶段。 ...

    转载自:https://www.jianshu.com/p/fda61af94d09

     

    一.推送原理

    • 图中,Provider是指某个iPhone软件的Push服务器,这篇文章我将使用百度云推送服务作为Provider。
      APNS 是Apple Push Notification Service(Apple Push服务器)的缩写,是苹果的服务器。
      上图可以分为三个阶段。
      第一阶段:Push服务器应用程序把要发送的消息、目的iPhone的标识打包,发给APNS。
      第二阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPhone,并把消息发到iPhone。
      第三阶段:iPhone把发来的消息传递给相应的应用程序, 并且按照设定弹出Push通知。
    • 从上图我们可以看到。
      1、首先是应用程序注册消息推送。
      2、 IOS跟APNS Server要deviceToken。应用程序接受deviceToken。
      3、应用程序将deviceToken发送给PUSH服务端程序。
      4、 服务端程序向APNS服务发送消息。
      5、APNS服务将消息发送给iPhone应用程序。
      无论是iPhone客户端跟APNS,还是Provider和APNS都需要通过证书进行连接的。下面我介绍一下几种用到的证书。

    二.创建本地请求证书文件--CertificateSigningRequest

    • 打开钥匙串-证书助理-从证书颁发机构请求证书

    • 填写邮箱和名称(无特殊要求可随意填写)-选择存储到磁盘
    • 选择继续-保存至桌面即可(此文件可长期重复使用,只作为本机器的一个识别作用)

    三.进入苹果开发者网站:https://developer.apple.com/

    • 依次选择Member Center - Certificates, Identifiers &Profiles - Certificates

    • 选择当前要设置通知的APP IDs
      PS:这里我以新建一个APP IDs为例,若公司已有项目APP IDs,则略过此步

    • 选择右上角"+"号创建一个APPID

    • 填写name以及Bundle ID

    • Bundle ID需要与Xcode里项目Bundle ID一致

    • 勾选push notification 并完成提交

    • 找到刚创建好的APP IDs,可以看到下面的通知选项处提示Configurable,表示证书还没配置,点击Edit进行编辑

    • 这里看到推送证书分为2个版本,一个开发模式,一个生产模式,即我们在开发测试时使用开发模式证书,发布上线后采用生产模式证书,两个都要创建(本次只作开发模式演示,当然创建生产版证书的步骤也是一样的)

    • Choose File选择最开始创建在桌面的Request文件


    • 创建证书OK后 下载到本地

    • 开发版和生产版证书都创建好后,此时这里已经都是启用状态了

    • 打开下载好的开发模式证书,可以在钥匙串中看到,右键将该证书导出成.p12格式文件


    • 证书密码可根据需求填写(可为空)

    • 这里请输入你电脑管理员密码

    • 导出的.p12格式文件如下

    • 接下来终端进入该文件目录下使用命令把此文件转成pem格式(因为后端需要上传pem格式文件验证)
      openssl pkcs12 -in TestPush_Dev.p12 -out Push_Dev.pem -nodes

    • 推送证书创建好了,接下来回到苹果开发者官网,按以下步骤创建Provisioning Profile文件


    •  
    • 选择该项目APP ID



    •  
    • 勾选测试授权的设备

    • 注意右侧的状态要Active才是可用的,若是invalid则需要Edit并重新下载一次

    • 到此我们开发模式所需要的证书和描述文件都创建好了

    四.进入百度云推送后台,登陆验证开发者身份,并创建一个推送应用

    • 选择iOS,并上传开发版证书(当然如果你同时也创建了生产版证书也可以上传验证)
    • 保存后,我们要用到的便是右侧的API KEY

    五.项目里配置百度云推送

    • 下载最新的百度云推送SDK,导入到工程,SDK需要以下库:Foundation.framework、CoreTelephony.framework、libz.dylib、SystemConfiguration.framework,请在工程中添加


    •  
    • 再次强调要修改Bundle ID与之前创建证书时所填Bundle ID一致
    • AppDelegate中导入BPush.h,并在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中添加如下代码,并修改apiKey为刚才创建应用所得apiKey,推送模式为开发模式

    <pre><code>`// iOS8 下需要使用新的 API

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
        UIUserNotificationType myTypes = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
    
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:myTypes categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    }else {
        UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound;
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
    }
    
    #warning 测试 开发环境 时需要修改BPushMode为BPushModeDevelopment 需要修改Apikey为自己的Apikey
    
    // 在 App 启动时注册百度云推送服务,需要提供 Apikey
    [BPush registerChannel:launchOptions apiKey:<#在百度云推送官网上注册后得到的apikey#> pushMode:BPushModeDevelopment withFirstAction:nil withSecondAction:nil withCategory:nil isDebug:YES];`</code></pre>
    
    • 添加如下3个方法

    <pre><code>`// 在 iOS8 系统中,还需要添加这个方法。通过新的 API 注册推送服务

    • (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
      {
      [application registerForRemoteNotifications];
      }
      `</code></pre>

    <pre><code>- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSLog(@"test:%@",deviceToken); [BPush registerDeviceToken:deviceToken]; [BPush bindChannelWithCompleteHandler:nil]; }</code></pre>

    <pre><code>`// 当 DeviceToken 获取失败时,系统会回调此方法

    • (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
      {
      NSLog(@"DeviceToken 获取失败,原因:%@",error);
      }`</code></pre>

    六.配置证书测试

    • 双击之前创建好的的TestPush_ProvisioningDev.mobileprovision描述文件,并在Xcode-Targets配置好证书


    • 这一步编译的时候容易failed,通常检查之前配置的provisioning文件状态是否为Active,若状态为Invalid,则需删除本地provisioning文件,clean,再次重新下载配置
    • 真机运行成功后,可看到控制端打印出获得到Device Token,以及APP提示时候开启通知


    •  

    七.创建通知测试

    • 在百度云推送后台创建一个通知测试,请选择开发模式

    • 现在我们就接收到刚才创建的通知了



     

    展开全文
  • 1.本地推送 关于本地推送的作用及意义:【后期完善】 实现步骤 大致4步:1创建通知、2注册通知、3实现函数、4删除通知 注意! 下面的内容中没有提到:在使用通知的时候,为了避免重复注册:最好在生命周期的函数...

    1.本地通知【这里只是讲的一种传值方式,本地推送可以在网上搜索 简书里面有很多好文章】

    关于本地推送的作用及意义:【后期完善】

    实现步骤
    大致4步:1创建通知、2注册通知、3实现函数、4删除通知
    注意! 下面的内容中没有提到:在使用通知的时候,为了避免重复注册:最好在生命周期的函数中进行 注册 和 删除通知
    如下:
    //注册通知
    - (void)viewWillAppear:(BOOL)animated
    {
        、、、、、
    }
    //在这里删除通知 不然会导致 多次触发通知方法
    - (void)viewWillDisappear:(BOOL)animated
    {
        //删除通知
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }

    在A类中创建通知,并设置要传递的参数,和通知哪个方法使用这个参数。这里传递的是一个字典,方法名是: tongzhi


    然后在需要获取通知的控制器类的viewDidLoad方法中注册通知


    接着在这个类中实现A类中描述的方法,就可以获取到通知的信息了


    最后在不使用通知的时候,需要删除通知




    2.远程推送

    下面两篇文件是兼容IOS的推送。 如果是使用三方【比如极光推送】的话,可以直接看三方的最新文档即可。

    iOS开发 iOS10推送讲解(基础篇):http://www.jianshu.com/p/f5337e8f336d

    :iOS开发 iOS10推送讲解(高阶1):http://www.jianshu.com/p/3d602a60ca4f



    参考来自: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.项目名称如下图



    3、在运行程序之前在build setting中的Code Signing的参数设置[如下图]



    第一部分、先来看一张苹果官方对其推送做出解释的概要图。

    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.建立推送项目

    1. //  
    2. //  AppDelegate.m  
    3. //  TestPushNotifiy  
    4. //  
    5. //  Created by silicon on 14-10-30.  
    6. //  Copyright (c) 2014年 silicon. All rights reserved.  
    7. //  
    8.   
    9. #import "AppDelegate.h"  
    10.   
    11. @implementation AppDelegate  
    12. @synthesize mainView = _mainView;  
    13.   
    14. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions  
    15. {  
    16.     if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)])  
    17.     {  
    18.         //IOS8  
    19.         //创建UIUserNotificationSettings,并设置消息的显示类类型  
    20.         UIUserNotificationSettings *notiSettings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIRemoteNotificationTypeSound) categories:nil];  
    21.           
    22.         [application registerUserNotificationSettings:notiSettings];  
    23.           
    24.     } else// ios7  
    25.         [application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge                                       |UIRemoteNotificationTypeSound                                      |UIRemoteNotificationTypeAlert)];  
    26.     }  
    27.       
    28.     self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];  
    29.     // Override point for customization after application launch.  
    30.     self.window.backgroundColor = [UIColor whiteColor];  
    31.     [self.window makeKeyAndVisible];  
    32.       
    33.     self.mainView = [[MainViewController alloc] initWithNibName:@"MainViewController" bundle:nil];  
    34.     self.window.rootViewController = self.mainView;  
    35.     return YES;  
    36. }  
    37.   
    38. - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)pToken{  
    39.     NSLog(@"---Token--%@", pToken);  
    40. }  
    41.   
    42. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{  
    43.       
    44.     NSLog(@"userInfo == %@",userInfo);  
    45.     NSString *message = [[userInfo objectForKey:@"aps"]objectForKey:@"alert"];  
    46.       
    47.     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:message delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil nil];  
    48.       
    49.     [alert show];  
    50. }  
    51.   
    52. - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{  
    53.   
    54.     NSLog(@"Regist fail%@",error);  
    55. }  

    56.   
    57. @end  


    在appdelegate.m中加入以上代码,

    1. if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)])  
    2.     {  
    3.         //IOS8  
    4.         //创建UIUserNotificationSettings,并设置消息的显示类类型  
    5.         UIUserNotificationSettings *notiSettings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIRemoteNotificationTypeSound) categories:nil];  
    6.           
    7.         [application registerUserNotificationSettings:notiSettings];  
    8.           
    9.     } else// ios7  
    10.         [application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge                                       |UIRemoteNotificationTypeSound                                      |UIRemoteNotificationTypeAlert)];  
    11.     }  

    由于ios8的推送跟ios7及以下的不一样,所以需要加判断来注册消息推送。

    函数:

    1. - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)pToken{  
    2.     NSLog(@"---Token--%@", pToken);  
    3. }  

    会接收来自苹果服务器给你返回的deviceToken,然后你需要将它添加到你本地的推送服务器上。(很重要,决定你的设备能不能接收到推送消息)。

    1. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{  
    2.       
    3.     NSLog(@"userInfo == %@",userInfo);  
    4.     NSString *message = [[userInfo objectForKey:@"aps"]objectForKey:@"alert"];  
    5.       
    6.     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:message delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil nil];  
    7.       
    8.     [alert show];  
    9. }  


    这个函数则是当设备接收到来自苹果推送服务器的消息时触发的,用来显示推送消息。

    1. - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{  
    2.   
    3.     NSLog(@"Regist fail%@",error);  
    4. }  

    当注册失败时,触发此函数。


    2.PHP服务端

    将simplepush.php这个推送脚本也放在push文件夹中

    1. <?php  
    2.   
    3. // ??????????deviceToken???????????????  
    4. $deviceToken = 'c95f661371b085e2517b4c12cc76293522775e5fd9bb1dea17dd80fe85583b41';  
    5.   
    6. // Put your private key's passphrase here:  
    7. $passphrase = 'abc123';  
    8.   
    9. // Put your alert message here:  
    10. $message = 'My first push test!';  
    11.   
    12. ////////////////////////////////////////////////////////////////////////////////  
    13.   
    14. $ctx = stream_context_create();  
    15. stream_context_set_option($ctx'ssl''local_cert''ck.pem');  
    16. stream_context_set_option($ctx'ssl''passphrase'$passphrase);  
    17.   
    18. // Open a connection to the APNS server  
    19. //??????????  
    20.  //$fp = stream_socket_client(?ssl://gateway.push.apple.com:2195?, $err, $errstr, 60, //STREAM_CLIENT_CONNECT, $ctx);  
    21. //?????????????appstore??????  
    22. $fp = stream_socket_client(  
    23. 'ssl://gateway.sandbox.push.apple.com:2195'$err,  
    24. $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);  
    25.   
    26. if (!$fp)  
    27. exit("Failed to connect: $err $errstr" . PHP_EOL);  
    28.   
    29. echo 'Connected to APNS' . PHP_EOL;  
    30.   
    31. // Create the payload body  
    32. $body['aps'] = array(  
    33. 'alert' => $message,  
    34. 'sound' => 'default'  
    35. );  
    36.   
    37. // Encode the payload as JSON  
    38. $payload = json_encode($body);  
    39.   
    40. // Build the binary notification  
    41. $msg = chr(0) . pack('n', 32) . pack('H*'$deviceToken) . pack('n', strlen($payload)) . $payload;  
    42.   
    43. // Send it to the server  
    44. $result = fwrite($fp$msg, strlen($msg));  
    45.   
    46. if (!$result)  
    47. echo 'Message not delivered' . PHP_EOL;  
    48. else  
    49. echo 'Message successfully delivered' . PHP_EOL;  
    50.   
    51. // Close the connection to the server  
    52. fclose($fp);  
    53. ?>  

    deviceToken填写你接收到的token,passPhrase则填写你的ck.pem设置的密码。

    此刻就是见证奇迹的时候了

    使用终端进入到push文件夹,在终端输入 php simplepush.php


    若显示以上提示则表示推送成功了。

    附上一张成功图。


    感谢这篇博客的指导:http://blog.csdn.net/showhilllee/article/details/8631734


    最后,当成功实现远程推送之后,这里补充一下关于 应用程序是如何接受推推送的,内容参考自http://www.2cto.com/kf/201410/344169.html

    关于接受APNS推送的函数 都在 Appdelegate.m中间中。
    这里有多个函数 用于监听APNS的推送,它们有着各自的区别

    3.重要函数

    概括来说 就是 APP生命周期的 第一个函数 是在应用没有打开时用来监听并获取推送的
                           而另外的两个函数 则时在应用处于后台 或者 正在运行的时候来监听推送的(这两个函数我的项目中是使用的较短的个,且没有问题)

    本文着重叫在App端如何处理推送信息。主要涉及一下几个比较重要的函数,而这些函数都是AppDelegate类中:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

    做过iOS 开发的人对这个函数都会很熟悉,这是在程序结束启动,并即将运行时调用的,通常一些初始化的工作可以在这个函数中处理。同样的,推送的相关初始化操作也需要在这个部分完成。这一部分的工作主要分为两部分: 推送类型的注册:
    ?
    1
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound | UIRemoteNotificationAlert];
    这行代码告诉了系统,该程序注册的推送消息类型,通常包括badge、声音以及alert通知。 处理程序没有启动时的推送消息: 如果是程序正在运行或者说程序正在后台,那么这个时候处理推送消息的工作都是在:

    -(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这个字典里。具体参照如下代码:
    ?

    可以从 launchOptions  字典中 找出推送中的内容,并判断推送的需求,另外,这个字典里面的 key 和 value 是可以在服务端自定义一些值的
    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");
            //程序处于后台
             
        }
    }

    4.三方推送[极光推送]

    2016-04-21时更新(如果看的时候 距离这个时间跨度较大了,建议直接去官网查看,有不会的可以访问极光的技术论坛询问)
    之前虽然知道,但是一只没有用过三方推送。其实用三方推送是很方便的。也省去了很多客服端盒服务端的开发难度。同时三推送也做了很多性能的优化。
    好,不废话了。

    其实这部分内容相当简单,概括的说就是:
    1,去官网下载ios端的开发库,目前就是一个静态库。下载的同时会包含官方的demo和一个开发文档。
    2,根据开发文档的流程配置就行。大致是:2.1导入静态库,2.2导入支持的框架,2.3添加一个属性列表,2.4在capabilities中设置background modes勾选远程推送。如图
    然后就是在注册极光推送的账号,下载推送的开发者证书,道出p12文件 并上传到极光推送的网站上去,获取到appkey,然后就在Appdelegate.m文件中注册和接收远程推送即可。详细内容参考demo就行。比起之前的实现推送的方式来说,这是最简单的。也可以在极光的网站上直接发送推送。记得,推送只能在真机上测试。 到这里内容就全部over了。

    展开全文
  • 参考:...1.前期准备工作 (1)证书的创建 进入苹果Apple Developer -&gt; Member Center -&gt; Certificates, Identifiers &amp; Profiles – &...Identifiers - &...如上图所示,勾...

    参考:http://www.jianshu.com/p/9eae61bcc42e
    1.前期准备工作
    (1)证书的创建
    进入苹果Apple Developer -> Member Center -> Certificates, Identifiers & Profiles – >Identifiers - >App IDs–>Edit

     

    如上图所示,勾选Push Notifications,然后点击下面的Create Certificate,分别创建测试环境与生产环境的SSL推送证书。
    (2)用证书文件与私钥合成.pem文件给后台的同学
    完成第(1)步后,然后在进入苹果Apple Developer -> Member Center -> Certificates, Identifiers & Profiles – >Certificates,找到刚才的推送证书然后下载->双击安装。在钥匙串中找到这两个证书(production&developerment)。分别导出.p12文件(证书的p12与密钥的p12),如下图。

     

    得到证书的p12与密钥的p12后,打开命令行把p12文件转化为.pem文件
    假设我的证书的p12与密钥的p12分别命名为:apns-dev-cert.p12;apns-dev-key.p12
    首先cd到这两个文件的目录下,使用下面的命令分别得到apns-dev-cert.pem; apns-dev-key.pem;

    openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns-dev-cert.p12
    
    openssl pkcs12 -nocerts -out apns-dev-key.pem -in apns-dev-key.p12
    

    然后再用apns-dev-cert.pem; apns-dev-key.pem;合成最终后台可以用来推送的apns-dev.pem文件。你把apns-dev.pem文件交给后台的小伙伴就可以了。

    cat apns-dev-cert.pem apns-dev-key.pem > apns-dev.pem
    

    production环境的.pem与developerment一样。
    这篇文章 详细的介绍了.pem如何制作的。
    2.实现推送
    打开你的项目->capabilication打开push notifications与background Modes,勾选最后一个remote notifications。


    如果是iOS10以上版本还需要引入UserNotifications.framework、UserNotificationsUI.framework这两个framework
    然后再application引入头文件#import <UserNotifications/UserNotifications.h>
    (1)注册推送

     

    在application里面的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {}
    中添加代码。

    if (IOS_VERSION >= 10.0) {
    UNUserNotificationCenter * center = [UNUserNotificationCenter currentNotificationCenter];
    [center setDelegate:self];
    UNAuthorizationOptions type = UNAuthorizationOptionBadge|UNAuthorizationOptionSound|UNAuthorizationOptionAlert;
    [center requestAuthorizationWithOptions:type completionHandler:^(BOOL granted, NSError * _Nullable error) {
    if (granted) {
    DBLog(@"注册成功");
    }else{
    DBLog(@"注册失败");
    }
    }];
    }else if (IOS_VERSION >= 8.0){
    UIUserNotificationType notificationTypes = UIUserNotificationTypeBadge |
    UIUserNotificationTypeSound |
    UIUserNotificationTypeAlert;
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:notificationTypes categories:nil];
    [application registerUserNotificationSettings:settings];
    }else{//ios8一下
    UIRemoteNotificationType notificationTypes = UIRemoteNotificationTypeBadge |
    UIRemoteNotificationTypeSound |
    UIRemoteNotificationTypeAlert;
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:notificationTypes];
    }
    
    // 注册获得device Token
    
    [application registerForRemoteNotifications];
    

    (2)获取Token

    // 将得到的deviceToken传给SDK
    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
    NSString *deviceTokenStr = [[[[deviceToken description]
    stringByReplacingOccurrencesOfString:@"<" withString:@""]
    stringByReplacingOccurrencesOfString:@">" withString:@""]
    stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSLog(@"deviceTokenStr:\n%@",deviceTokenStr);
    }
    
    // 注册deviceToken失败
    - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
    NSLog(@"error -- %@",error);
    }
    

    在application里面的添加上面两个方法。然后再获取设备token成功的方法里面,我们需要把获取到的设备的token发送给后台,然后后台拿token去推送。
    (3)处理推送过来的消息
    1.iOS10以上版本的处理

    //在前台
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{
    // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置
    completionHandler(UNNotificationPresentationOptionBadge|
    UNNotificationPresentationOptionSound|
    UNNotificationPresentationOptionAlert);
    }
    

    上面的这个方法,加上completionHandler(UNNotificationPresentationOptionBadge|
    UNNotificationPresentationOptionSound|
    UNNotificationPresentationOptionAlert);
    用户即使在前台,收到推送时通知栏也会出现,有声音和角标。如果去掉应用在前台有推送时并不会收到。

    - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler{
    //处理推送过来的数据
    [self handlePushMessage:response.notification.request.content.userInfo];
    completionHandler();        
    }
    

    这个方法是在用户点击了消息栏的通知,进入app后会来到这里。我们可以业务逻辑。比如跳转到相应的页面等。
    2.iOS10以下的处理

    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary * _Nonnull)userInfo fetchCompletionHandler:(void (^ _Nonnull)(UIBackgroundFetchResult))completionHandler{
    NSLog(@"didReceiveRemoteNotification:%@",userInfo);
    /*
    UIApplicationStateActive 应用程序处于前台
    UIApplicationStateBackground 应用程序在后台,用户从通知中心点击消息将程序从后台调至前台
    UIApplicationStateInactive 用用程序处于关闭状态(不在前台也不在后台),用户通过点击通知中心的消息将客户端从关闭状态调至前台
    */
    //应用程序在前台给一个提示特别消息
    if (application.applicationState == UIApplicationStateActive) {
    //应用程序在前台
    [self createAlertViewControllerWithPushDict:userInfo];
    }else{
    //其他两种情况,一种在后台程序没有被杀死,另一种是在程序已经杀死。用户点击推送的消息进入app的情况处理。
    [self handlePushMessage:userInfo];
    }
    completionHandler(UIBackgroundFetchResultNewData);
    }
    

    在application里面的添加上面的方法,iOS10以下,应用在前台的时候,有推送来,会直接来到这个方法。但是通知栏不会有提示,角标也不会有。应用如果在后台或者在关闭状态,点击推送来的消息也会来到这个方法。我们可以在这里处理业务逻辑。
    3.测试推送是否成功
    到这里我们完成了基本的推送功能,但是是否能够成功还不知道?我们可以测试一下。这里是一个测试推送的软件 大家从github下载下来,直接运行。
    1.把你的证书路径、token以及要推送的消息放到指定的地方。
    2.点击连接服务器,这个时候会有访问钥匙串的请求,允许访问钥匙串。
    3.点击发送。
    4.iOS10推送的进阶使用
    iOS10还可以实现推送页面UI的自定义,以及添加事件,下一篇文章会介绍。
    Xcode打开项目,File-->New-->Target;


    然后分别选UNNotificationServiceExtension、UNNotificationContent创建Target;

     

    然后在UNNotificationServiceExtension的- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {}方法中添加下面的代码;

    NSMutableArray *actionMutableArr = [[NSMutableArray alloc] initWithCapacity:1];
    UNNotificationAction * actionA  =[UNNotificationAction actionWithIdentifier:@"ActionA" title:@"不感兴趣" options:UNNotificationActionOptionAuthenticationRequired];
    UNNotificationAction * actionB = [UNNotificationAction actionWithIdentifier:@"ActionB" title:@"不感兴趣" options:UNNotificationActionOptionDestructive];
    UNNotificationAction * actionC = [UNNotificationAction actionWithIdentifier:@"ActionC" title:@"进去瞅瞅" options:UNNotificationActionOptionForeground];
    UNTextInputNotificationAction * actionD = [UNTextInputNotificationAction actionWithIdentifier:@"ActionD" title:@"作出评论" options:UNNotificationActionOptionDestructive textInputButtonTitle:@"send" textInputPlaceholder:@"say some thing"];
    [actionMutableArr addObjectsFromArray:@[actionA,actionB,actionC,actionD]];
    if (actionMutableArr.count) {
    UNNotificationCategory * notficationCategory = [UNNotificationCategory categoryWithIdentifier:@"categoryNoOperationAction" actions:actionMutableArr intentIdentifiers:@[@"ActionA",@"ActionB",@"ActionC",@"ActionD"] options:UNNotificationCategoryOptionCustomDismissAction];
    [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:[NSSet setWithObject:notficationCategory]];
    }
    

    上面的方法是添加推送消息下面的事件(进入应用查看,取消查看,快捷回复)的,如果你的应用不需要可以忽略;

    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];
    self.bestAttemptContent.categoryIdentifier = @"categoryNoOperationAction";
    // Modify the notification content here...
    //    self.bestAttemptContent.title = [NSString stringWithFormat:@"点击查看更多内容"];
    NSDictionary *dict =  self.bestAttemptContent.userInfo;
    //    NSDictionary *notiDict = dict[@"aps"];
    NSString *mediaUrl = [NSString stringWithFormat:@"%@",dict[@"media"][@"url"]];
    NSLog(@"%@",mediaUrl);
    if (!mediaUrl.length) {
    self.contentHandler(self.bestAttemptContent);
    }
    [self loadAttachmentForUrlString:mediaUrl withType:dict[@"media"][@"type"] completionHandle:^(UNNotificationAttachment *attach) {
    if (attach) {
    self.bestAttemptContent.attachments = [NSArray arrayWithObject:attach];
    }
    self.contentHandler(self.bestAttemptContent);
    }];
    
    //处理视频,图片的等多媒体
    - (void)loadAttachmentForUrlString:(NSString *)urlStr
    withType:(NSString *)type
    completionHandle:(void(^)(UNNotificationAttachment *attach))completionHandler{
    __block UNNotificationAttachment *attachment = nil;
    NSURL *attachmentURL = [NSURL URLWithString:urlStr];
    NSString *fileExt = [self fileExtensionForMediaType:type];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    [[session downloadTaskWithURL:attachmentURL
    completionHandler:^(NSURL *temporaryFileLocation, NSURLResponse *response, NSError *error) {
    if (error != nil) {
    NSLog(@"%@", error.localizedDescription);
    } else {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSURL *localURL = [NSURL fileURLWithPath:[temporaryFileLocation.path stringByAppendingString:fileExt]];
    [fileManager moveItemAtURL:temporaryFileLocation toURL:localURL error:&error];
    NSError *attachmentError = nil;
    attachment = [UNNotificationAttachment attachmentWithIdentifier:@"" URL:localURL options:nil error:&attachmentError];
    if (attachmentError) {
    NSLog(@"%@", attachmentError.localizedDescription);
    }
    }
    completionHandler(attachment);
    }] resume];
    }
    - (NSString *)fileExtensionForMediaType:(NSString *)type {
    NSString *ext = type;
    if ([type isEqualToString:@"image"]) {
    ext = @"jpg";
    }
    if ([type isEqualToString:@"video"]) {
    ext = @"mp4";
    }
    if ([type isEqualToString:@"audio"]) {
    ext = @"mp3";
    }
    return [@"." stringByAppendingString:ext];
    }
    

    上面的这两段代码是当推送消息来了后,我们将mdeia下的url内的文件下载到本地,然后将路径交给系统,进而实现推送多媒体文件的目的;
    这里说一下必须注意的两个坑、个坑、坑:
    1.将UNNotificationServiceExtension中的pilst文件中添加
    (1)在Info.plist中添加NSAppTransportSecurity类型Dictionary。
    (2)在NSAppTransportSecurity下添加NSAllowsArbitraryLoads类型Boolean,值设为YES
    这是因为从iOS9开始苹果不允许直接http访问,加上这两个字段就可以访问http,如果你不添加,只有你推送https的media文件才能被下载,http则不能被下载;

     

    2.选中工程---> UNNotificationServiceExtension所对应的Target-->Deploy Target设置为iOS10,因为是从iOS10才支持推送多媒体文件,它默认是从当前Xocde支持的最高版本,比如小编的手机版本iOS10.0.2,它默认是iOS 10.2.0.刚开始小编没有修改,推送死活出不来图片,只有文字;后台检查才发现这里是从iOS 10.2.0支持的,心中一万个草泥马崩腾而过;

     

     

    忙活了这么多还是看一下效果吧,我只做了图片与视频,声音应该差别不大。

     

    自定义推送的UI
    1.在UNNotificationServiceExtension的- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler方法内为self.bestAttemptContent添加categoryIdentifier

    self.bestAttemptContent.categoryIdentifier = @"myNotificationCategory";
    

    然后将这个categoryIdentifier粘贴在UNNotificationContent的infoplist内NSExtension-->NSExtensionAttributes-->UNNotificationExtensionCategory的字段内;然后在下面在添加一个字段UNNotificationExtensionDefaultContentHidden设置bool值为YES,这里是隐藏系统的UI;

     

    1. 在上面的下载多媒体文件的- (void)loadAttachmentForUrlString:(NSString *)urlStr withType:(NSString *)type completionHandle:(void(^(UNNotificationAttachment *attach))completionHandler;方法内添加
    NSMutableDictionary * dict = [self.bestAttemptContent.userInfo mutableCopy];
    [dict setObject:[NSData dataWithContentsOfURL:localURL] forKey:@"image"];
    self.bestAttemptContent.userInfo = dict;
    

    我这里是将图片的Data数据放到推送的userInfo里面,然后在自定义UI的UNNotificationContent内获取这个Date,然后加载UI;

    1. 在UNNotificationContent的maininterface.storyboard内部将UI做好,然后在UNNotificationContent的- (void)didReceiveNotification:(UNNotification *)notification ;方法内进行UI加载。

       

       

      来看一下自定义UI的效果。

       

     

    展开全文
  • IOS的消息推送机制

    2017-08-15 13:42:28
    1、iOS推送是统一挂在苹果服务器上的,app安装的时候设备会把token分享给app,app的服务器根据这个token发消息给苹果,苹果根据token发给设备设备和苹果的连接由系统挂在流量上的tcp长连接实现,装再多app也只...

    1、iOS 的推送是统一挂在苹果服务器上的,app安装的时候设备会把token分享给app,app的服务器根据这个token发消息给苹果,苹果根据token发给设备

    设备和苹果的连接由系统挂在流量上的tcp长连接实现,装再多app也只需要挂这么一个连接就能保证推送,不像国产安卓app每个都要自己挂后台并且保持连接

    其实安卓也是有系统级的推送服务的,这个服务因为由一个不存在的服务商提供,所以没法用,你说怪谁?

    此外说到本地通知,iOS也有方案,app可以向系统请求注册本地通知,到时间了由系统自己发出来,也不需要app挂后台

    2、苹果的消息机制通俗的来讲就是这样:

    APP的厂商的消息发给苹果服务器,苹果服务器发给制定iOS设备

    所以iOS也会为信息推送留进程,但是只有iOS里的一个系统进程,APP不用留,你收到的通知和APP没有半分钱关系,这就是为什么iOS版的微信和QQ每次进入都有一段时间要收取消息。

    Android是这样:

    从APP服务器直接发给APP,APP用申请的弹窗权限给你弹出来

    所以每一个应用都得有个进程才能接收通知

    为啥会这样呢?

    其实Android也有一套系统级信息推送服务

    然而服务器是Google的,后面不用我说了吧

    3、Push的原理:
    Push 的工作机制可以简单的概括为下图
    这里写图片描述

    图中,Provider是指某个iPhone软件的Push服务器,这篇文章我将使用.net作为Provider。
    APNS 是Apple Push Notification Service(Apple Push服务器)的缩写,是苹果的服务器。
    上图可以分为三个阶段。
    第一阶段:Push服务器应用程序把要发送的消息、目的iPhone的标识打包,发给APNS。
    第二阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPhone,并把消息发到iPhone。
    第三阶段:iPhone把发来的消息传递给相应的应用程序, 并且按照设定弹出Push通知。

    这里写图片描述

    从上图我们可以看到。
    1、首先是应用程序注册消息推送。
    2、 IOS跟APNS Server要deviceToken。应用程序接受deviceToken。
    3、应用程序将deviceToken发送给PUSH服务端程序。
    4、 服务端程序向APNS服务发送消息。
    5、APNS服务将消息发送给iPhone应用程序。

    展开全文
  • iOS两种推送方式

    2019-05-06 17:08:16
    iOS两种推送方式 APNs(Apple Push Notification service =APNs)是Apple推送通知服务。2016年的WWDC,苹果上线了token验证的推送方式,通过获得一个认证密钥(APNs Auth Key)去生成服务器端token,并且token非常...

    iOS两种推送方式

    APNs(Apple Push Notification service =APNs)是Apple推送通知服务。2016年的WWDC,苹果上线了token验证的推送方式,通过获得一个认证密钥(APNs Auth Key)去生成服务器端token,并且token非常容易生成,可以使用这些token令牌代替推送证书。一个认证密钥可用于多个应用程序并且永远不过期。每一个需要推送的App都需要配置推送证书的时代过去了。而且,一些第三方推送服务商,如极光、LeanCloud(官网强烈推荐的方式)目前已经升级支持APNs Auth Key Token模式。

    1、认证方式

    TLS(是“Transport Layer Security”的缩写),中文叫做“传输层安全协议”。新的APNs协议基于HTTP/2,旧推送是使用Universal Push Notification Client SSL 证书,新推送是使用Token认证。

    1.1、基于证书的信任认证

    建立基于证书的Provider信任连接

    建立连接工作的步骤如下:

    1)Provider通过TLS向APNs发起安全请求。

    2)APNs返回一个证书给Provider。

    3)Provider验证APNs的证书,验证通过后,返回Apple提供的证书(通过苹果开发者账号创建的推送证书)给APNs。

    4)APNs验证Provider返回的证书,从而确认连接请求来自于合法的Provider并建立TLS连接。

    上述步骤完成后,信任连接建立,Provider服务器可以发送基于证书的远程推送消息请求给APNs。

    证书认证

    1.2、基于Token的信任认证

    基于Token的Provider信任连接

    建立连接工作的步骤如下:

    1)Provider通过TLS向APNs发起安全请求。

    2)APNs返回一个证书给Provider。

    以上两步完成后,信任连接建立,Provider服务器可以发送基于Token的远程推送消息请求给APNs。

    3)Provider验证APNs的证书,然后Provider发送的每个消息请求必须携带上JWT 认证的 Token。

    4)APNs验证Provider返回的证书,并返回请求的结果。

    Token认证

    2、推送服务配置过程

    2.1、配置推送证书

    1)在苹果开发者网站上创建两种 APNs 证书,有开发(Development)和生产(Production)两种。开发证书用于开发调试使用;生产证书既能用于开发调试,也可用于产品发布。选择该证书准备绑定的对应的 AppID。

    新建证书

    选择证书类型(开发或生产证书)

    选择证书需要绑定的App ID

    2)在电脑上打开系统自带的 KeychainAccess 创建 Certificate Signing Request文件。

    创建CSR文件

    3)回到浏览器中 CSR 上传页面,上传刚刚生成的后缀为 .certSigningRequest 的文件。

    上传CSR文件

    4)生成证书成功后,点击 “Download” 按钮把证书下载下来,是后缀为 .cer 的文件。

    下载后缀为 .cer的证书

    5)在电脑上双击证书后,会在“KeychainAccess”中打开,选择左侧“钥匙串”列表中“登录”,以及“种类”列表中“我的证书”,找到刚才下载的证书,并导出为 .p12 文件。

    导出.p12 文件

    6)将导出的 .p12 文件(开发和生产的)上传至第三方推送平台。

    2.2、配置认证密钥(APNs Auth Key)

    1)在苹果开发者网站上创建Keys,填写相应的名称之后,网站会生成包含APNs Auth Key的.p8密钥文件。

    创建APNs Auth Key

    2)将下载的的 .p8 密钥文件上传至第三方推送平台。

    注:.p8 密钥文件只允许下载一次,需要妥善保管。

    3、权限和使用期限

    传统的推送证书,每个App需要单独配置两个(开发环境和生产环境)证书。推送证书的有限期为1年(生产的推送证书比开发的推送证书多一个月),过期之后需要重新配置。

    新的token验证推送,一个认证密钥可用于多个App服务,而且永远不会过期。但是该密钥生成后,在网站上只允许下载一下,要保管好下载的.p8 密钥文件。

    对于一个开发者账号管理着多个App,并且部分App迭代周期大于1年,这种新的推送认证方式大大地减少了管理证书人员的工作量。

     

    展开全文
  • iOS推送流程(APNS)

    2017-12-04 14:33:15
    iOS推送流程(APNS)一、APNS(Apple Push Notification Service)苹果推送通知服务(APNs)是推送通知的网关,iPhone ipad 对于应用程序在后台运行有诸多限制,考虑到手机电池电量,应用不允许在后台进行过多的操作。...
  • 今天就由本菜鸟给大家做一个简单的IOSApp消息推送教程吧!一切从0开始,包括XCode6, IOS8, 以及苹果开发者中心最新如何注册应用,申请证书以及下载配置概要文件,相信很多刚开始接触ios的人会很想了解一下。(ps:...
  • 首先我们看一下苹果官方给出的对ios推送机制的解释。如下图   Provider就是我们自己程序的后台服务器,APNS是Apple Push Notification Service的缩写,也就是苹果的推送服务器。 上图可以分为三个阶段: 第一阶段...
  • iOS推送证书是用于推送 通知功能配置,需要配置到入极光推送、个推等推送平台。 iOS推送证书不能直接用于打包ipa,且推送证书只有p12,无关联描述文件。 iOS推送证书分为开发环境及生成环境,看下面具体申请步骤...
  • iOS APP需要推送通知,要用到iOS推送证书,分为测试调试用的iOS推送证书(开发环境)和上架到App Store的ios 推送证书!(生产环境) APP要推送通知首先要在创建APPID时勾选推送服务。 推送证书是配置上传到推...
  • iOS 推送,删除指定推送消息 远程推送经常会出现收到重复推送的问题,或者想删除某条推送消息的问题,本文将详细说明 静默推送iOS10 之后 Apple 新增了静默推送的功能,使 App 可以在收到推送之后执行一段...
  • 很多人初次接触推送通知,不知道怎么去申请ios推送证书和配置推送。很多人犯的错误就是用推送证书p12去打包ipa,推送不是用来打包的,下面详细介绍ios推证书的申请和配置使用。ios推送证书分为测试调试用的iOS推送...
  • iOS推送开关

    2016-09-08 11:36:16
    最近的项目中用到了iOS推送的开关,本来以为客户端发个请求给服务器,让服务器去控制是否控制是否推的 ,结果!哎 ,我们的服务器是一个刚转做app的,推送都不知道怎么搞的,还是以前只做后台的,搞的! 最后只能...
  • ios 推送丢失问题

    2014-09-24 10:35:29
    在采用app推送后,一度为了追求最大的推送消息量,而将ios推送的一次推送值设为500条,在使用一段时间,发现ios测试机接受到的推送消息时断时续。 例如: 服务端每天08:00 至 13:00 推送给每台装了app的ios...
  • iOS 推送证书的制作

    2014-12-15 17:19:52
    关于iOS推送证书的P12文件,并不是直接从KeyChain导出来的证书文件,而是需要经过openSSL工具制作的。(好在Mac OS 默认就有openSSL命令) 针对不同的Server平台,需要的证书是不同的,先说一下.Net框架开发的Server...
  • c#语言IOS推送服务端全程代码, windows服务全程代码, windows服务安装程序设置, 实现IOS推送服务C#语言服务端代码实现
  • ios 推送app badge 数字累加操作; 一:此数字需要后台配合: 二:大致原理:  后台发推送时,第一次 传badge 为1,往后,依次累加操作即可;  当用户打开app时,app向后台发送请求,告诉后台,用户打开了app,...
  • 本文旨在对 iOS 推送进行一个完整的剖析,如果你之前对推送一无所知,那么在你认真地阅读了全文后必将变成一个推送老手,你将会对其中的各种细节和原理有充分的理解。以下是 pikacode 使用 iOS 推送的一些经验,...
  • 教你做IOS推送 包会!

    2015-10-28 14:08:54
     APNS的推送机制首先我们看一下苹果官方给出的对iOS推送机制的解释。如下图Provider就是我们自己程序的后台服务器,APNS是Apple Push Notification Service的缩写,也就是苹果的推送服务器。 上图可以分为三个阶段...
  • React-Native-iOS推送集成

    2018-08-23 16:34:44
    首先是iOS推送流程,这篇文章有了比较详细的描述,大家可以了解一下http://www.jianshu.com/p/54ba62b2ed77iOS推送流程 而本文主要是针对的需求是在已拥有自己的推送服务器的情况下,怎么在js端获取已注册的device ...
1 2 3 4 5 ... 20
收藏数 45,823
精华内容 18,329
关键字:

ios推送