美文网首页Swift
iOS-集成小米推送流程(新)

iOS-集成小米推送流程(新)

作者: YNTCode | 来源:发表于2016-07-01 17:26 被阅读3249次

    之前写过一篇小米推送的文章,但是流程写的不详细,内容编辑也有问题,今天再次接入小米推送,趁热更新一下之前的文章,补充一下细节,供大佬们参考。

      开始还是要吐槽一下小米开放平台的客服系统,尤其对于推送这种基础免费软件,没有人工客服,反馈问题都是靠邮件,难受的一笔。

      集成过程分为以下几部分:

    1. 小米开放平台账号及权限申请,app注册
    2. 苹果推送证书申请
    3. 在小米推送后台配置推送证书
    4. 集成小米SDK
    5. 开发环境测试
    6. 模拟线上环境测试

    小米开放平台账号及权限申请,app注册

    进入小米开放平台,注册小米账号,并认证开发者权限。这部分工作一般是由开发支持部门完成。

    苹果推送证书申请

    这部分就以图片的形式说明了,网上这种教程很多,如果有不明白的地方,可以自行百度或者google

    1. 注册APPID
      填写APPID描述和BundleID
      ![注册APPID]
      注册APPID.png

    勾选你需要的AppServices,推送功能需要勾选Push Notifications

    注册APPID2.png
    1. 注册推送证书

    打开mac钥匙串访问 -> 证书助理 -> 从证书颁发机构请求证书


    钥匙串颁发证书.png

    填写相关信息,将证书存储到磁盘,备用


    钥匙串颁发证书1.png

    接下来进入苹果开发者中心,登陆并点击Account,进入个人中心,点击Certificates,Identifiers&Profiles选项,进入证书,id,配置文件管理中心。

    开发推送证书3.png

    点击Certificates,可以看到证书管理选项,如下图:

    推送证书1.png

    选择Certificates选项下的Development选项,点击右上角+号,选择Apple Push Notification service SSL (Sandbox),添加开发推送证书

    开发推送证书.png

    选择之前创建的App ID,

    开发推送证书1.png

    接下来就需要用到之前从钥匙串中颁发的证书,找到存储钥匙串证书的位置,选中添加,

    开发推送证书2.png

    最后,点击Continue,即可创建开发推送证书,然后下载创建好的证书,双击将其添加到要是串中,开发推送证书注册完毕。

    生产推送证书的注册方式基本相同,只是在第一步选中的是Apple Push Notification service SSL (Sandbox & Production)选项,如下图:

    生产推送证书.png

    在小米推送后台配置推送证书

    在上一步,注册了开发和生产的推送证书,下载并双击运行到了钥匙串中,所以这一步首先要将推送证书从钥匙串中导出。

    导出推送证书.png

    共享证书文件需要通过导出.p12文件,导出证书姿势如下两种:

    姿势一

    导出证书姿势1.png

    姿势二

    导出证书姿势2.png

    下面再演示一种错误姿势,如果集成sdk之后,使用小米推送工具测试无法推送到APNs服务器,考虑一下是不是自己手欠,多选了一项。

    导出证书错误姿势.png

    证书导出完成之后,上传到对应app栏目下(这个就不贴图了)。

    集成小米推送SDK

    从官方文档中找到sdk下载链接,下载并将一个.a库和一个.h头文件引入项目中,记得点击copy items if need。
    添加以下依赖库: UserNotifications.framework(iOS10+), libresolv.dylib, libxml2.dylib, libz.dylib,SystemConfiguration.frameworkMobileCoreServices.frameworkCFNetwork.frameworkCoreTelephony.framework
    部分xcode版本需要在target的Capabilities选项卡中打开Push Notifications选项,具体如下图:

    引入依赖库并打开推送开关.png

    接下来,不要着急写码,还要先配置好参数, MiSDKAppID, MiSDKAppKey, MiSDKRun,前两者可以在小米开放平台注册的应用中拿到,后者是用来区分开发(debug)和生产(online)模式,这里直接建议使用User-Defined Setting参数来配置MiSDKRun的值,这样以后切换Debug和Release环境时就不用手动修改了。添加位置为工程中Info.plist文件,步骤如下图:

    添加参数

    infoplist中配置变量.png

    添加User-Defined Setting变量

    添加变量.png

    变量展示如下

    变量.png

    时隔两天(写文章好累),开始上代码:

    注册小米推送

    /** 初始化小米推送 */
    - (void)initMiPush
    {
        [MiPushSDK registerMiPush:self type:UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert connect:YES];
    }
    

    Appdelegate中实现注册推送成功/失败代理,方法如下:

    /**
     推送注册成功
     */
    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
    {
        /** 注册成功绑定设备号 */
        [MiPushSDK bindDeviceToken:deviceToken];
    }
    /**
     推送注册失败
     */
    - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
    {
        NSLog(@"小米推送注册失败");
    }
    

    实现小米sdk中异步回调代理(MiPushSDKDelegate),

     /**
      小米成功回调
      */
    - (void)miPushRequestSuccWithSelector:(NSString *)selector data:(NSDictionary *)data
     {
         if ([selector isEqualToString:@"bindDeviceToken:"]) {
           /** 如果服务端是通过regid推送,这个地方可以用全局变量或者其他方式记录一下,在某个时机上传到服务端 */  
           NSLog(@"regid = %@", data[@"regid"]);
             
         }
     }
    
     - (void)miPushRequestErrWithSelector:(NSString *)selector error:(int)error data:(NSDictionary *)data
     {
          DLog(@"小米回调失败:%d",error);
     }
    

    收到小米推送到响应小米推送信息,这个过程分为三种场景

    • 应用运行中,并处在前台
    • 应用运行中,单处在后台
    • 应用未启动

    下面列出iOS9/iOS10两个版本下(因项目支持最低版本为iOS 9.0,所以没有测试iOS 9.0之前的版本,如有不同,可以告诉我下,我会做下补充),在系统收到推送和点击推送消息响应方法的区别:

    方法调用.png

    下面分状态给出代码:

    /**
     iOS 9.0 应用处于前台,收到通知或点击通知消息,均执行该方法
     */
    - ( void )application:( UIApplication *)application didReceiveRemoteNotification:( NSDictionary *)userInfo
     {
        //使用此方法后,所有消息会进行去重,然后通过miPushReceiveNotification:回调返回给App
         [ MiPushSDK handleReceiveRemoteNotification :userInfo];
     }
    
    /**
     iOS10 应用在前台收到通知
     */
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
        NSDictionary * userInfo = notification.request.content.userInfo;
        if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
            [MiPushSDK handleReceiveRemoteNotification:userInfo];
        }
        if (@available(iOS 10.0, *)) {
            /** 如果在前台想要显示通知栏消息,需要实现该Handler */
            completionHandler(UNNotificationPresentationOptionBadge|
                              UNNotificationPresentationOptionSound|
                              UNNotificationPresentationOptionAlert);
        } else {
            // Fallback on earlier versions
        }
    }
    

    当应用处于后台或者未启动状态,因iOS 9.0收到通知和点击通知调用方法相同,所以现在只需考虑iOS 10.0之后点击通知栏消息到响应消息过程。

    由上面方法调用表可以看到,iOS 10.0之后,收到通知执行方法的顺序是方法4->方法1,如果当前app是冷启动,在执行下面方法时,window还未创建,所以在这里响应推送消息有可能无效,比如要push到指定页面,这里提供两种解决方法:

    1. 延时2s-3s,处理推送消息,但是这种方法有局限性,还是有可能无法响应消息.
    2. 在下面方法中记录该消息(NSUserDefaults或者其他方式),待window初始化之后,再响应该推送消息
    /**
     iOS 10,应用处于后台或者未启动,点击通知栏进入应用,会先执行该方法
     */
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
        NSDictionary * userInfo = response.notification.request.content.userInfo;
        if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
            [MiPushSDK handleReceiveRemoteNotification:userInfo];
            /** 记录推送消息 */
        }
        completionHandler();
    }
    

    iOS 9.0/10.0 点击推送消息并且app冷启动状态都会走的方法

    /**
     iOS 9.0/10.0,应用冷启动,点击通知栏进入应用,会执行该方法,所以为了兼容iOS 9.0,这里也要记录推送消息
     */
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        /** 注册小米推送 */
        [self initMiPush];
        /** app冷启动,记录(处理)小米推送消息 */
        NSDictionary* userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
        [self dealMiPushMessage:userInfo];
        return YES;
    }
    

    另外,如果应用处于前台,sdk内部会运行一个socket长连接到server端,来接收推送消息,这个方法中未做处理

    /**
      当app启动并运行在前台时,sdk内部会运行一个socket长连接到server端,来接收推送消息
    
      @param data 消息格式跟APNs格式一样
      */
     - ( void )miPushReceiveNotification:( NSDictionary *)data
     {
         NSLog(@"小米回调前台:%@",data);
     }
    

    至此,代码部分完结,有不明白的可以参看MipushDemodemo在文章两天内给出,包括处理推送消息的方法,在Demo中都有体现。接下来是测试部分,有些同学集成sdk完毕之后,使用小米开放平台推送工具进行测试,有可能测试环境收不到推送,或者正式环境收不到推送,或者两者都收不到推送,如有该问题,可看一下以下部分,看看是否能解决问题。

    iOS 推送环境分为两种:测试环境和正式环境

    1. 测试环境:即Dev模式,对应开发证书
    2. 正式环境:该环境可分为两种,appstore和Ad-hoc,两种推送的通道相同,所以正式环境的推送可以通过打Ad-hoc的包来测试。

    使用Ad-hoc的开发证书无法直接运行项目在真机上,因为我项目里面使用了cocoapods,这个是否有解决方法?有知道的同学告诉我下,万分感谢!!!

    所以正式环境和开发环境并不只是指修改targe中的debug和release编译模式,而是需要证书+编译模式两种齐备。测试环境对应Debug编译模式+dev打包证书,正式环境对应Release编译模式+Ad-hoc证书。

    到这里小米推送的集成过程完毕,可通过小米开放平台的推送工具来进行测试。

    相关文章

      网友评论

        本文标题:iOS-集成小米推送流程(新)

        本文链接:https://www.haomeiwen.com/subject/gvzfjttx.html