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

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

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

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

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

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

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

苹果推送证书申请

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

  1. 注册APPID
    填写APPID描述和BundleID
    ![注册APPID]
    iOS-集成小米推送流程(新)_第1张图片
    注册APPID.png

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

iOS-集成小米推送流程(新)_第2张图片
注册APPID2.png

  1. 注册推送证书

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


iOS-集成小米推送流程(新)_第3张图片
钥匙串颁发证书.png

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


iOS-集成小米推送流程(新)_第4张图片
钥匙串颁发证书1.png

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

iOS-集成小米推送流程(新)_第5张图片
开发推送证书3.png

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

iOS-集成小米推送流程(新)_第6张图片
推送证书1.png

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

iOS-集成小米推送流程(新)_第7张图片
开发推送证书.png

选择之前创建的App ID,

iOS-集成小米推送流程(新)_第8张图片
开发推送证书1.png

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

iOS-集成小米推送流程(新)_第9张图片
开发推送证书2.png

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

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

iOS-集成小米推送流程(新)_第10张图片
生产推送证书.png

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

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

iOS-集成小米推送流程(新)_第11张图片
导出推送证书.png

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

姿势一

iOS-集成小米推送流程(新)_第12张图片
导出证书姿势1.png

姿势二

iOS-集成小米推送流程(新)_第13张图片
导出证书姿势2.png

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

iOS-集成小米推送流程(新)_第14张图片
导出证书错误姿势.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选项,具体如下图:

iOS-集成小米推送流程(新)_第15张图片
引入依赖库并打开推送开关.png

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

添加参数

iOS-集成小米推送流程(新)_第16张图片
infoplist中配置变量.png

添加User-Defined Setting变量

iOS-集成小米推送流程(新)_第17张图片
添加变量.png

变量展示如下

iOS-集成小米推送流程(新)_第18张图片
变量.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之前的版本,如有不同,可以告诉我下,我会做下补充),在系统收到推送和点击推送消息响应方法的区别:

iOS-集成小米推送流程(新)_第19张图片
方法调用.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-集成小米推送流程(新))