如果您在集成过程中遇到任何问题,都可以添加QQ群:385428920 ,群中会有工程师解答您的问题。
小米推送iOS版提供存量用户无缝迁移方案
小米推送现已支持批量导入DeviceToken的功能,可以帮助您将IOS推送无缝迁移到小米推送服务上。
迁移方法是给我们提供所有现有设备的DeviceToken列表(CSV或TXT格式,每行一个DeviceToken),我们会为这拨设备直接生成小米推送的设备标识(regid),这样即使这批用户不升级到包含小米推送SDK的应用新版本也依然能收到通过小米推送服务发出的消息。
如有迁移需求,请在集成小米推送的应用版本正式发布前联系我们进行导入。
联系方式:
马一翔 [email protected]
赵宇斌 [email protected]
修订历史 | |
---|---|
2014年3月 草稿 | |
2014年4月 正式版 | |
2014年9月 Add 常见问题 | |
2015年5月 Add 应用内长连接 | |
在集成过程中遇到任何问题,请联系我们:[email protected] |
目录
iOS版本包括两部分。
1. 基于Apple的APNs(Apple Push Notification Service)
2.
应用内长连接(即在App启动并运行在前台时,SDK内部会运行一个Socket长连接连接到Server端,以接收消息推送。此长连接跟APNs时分开的,不经过APNs服务器)
SDK以.a动态链接库的形式提供, 开发者只需在原有编码基础上添加少许代码,来注册小米推送服务与绑定手机设备。
客户端在注册成功后,会得到服务器颁发的regId(终端唯一标示),服务端通过regId发消息给终端。
除此以外,客户端还可以通过订阅Topic、设置别名Alias、帐号Acount来收发推送消息。
这里介绍如何配置和使用小米推送服务,您也可以参照Demo来配置和使用小米推送服务。
在使用小米推送服务前,开发者需要先登录小米开发者网站http://developer.xiaomi.com。注册App,申请对应的AppID, AppKey,
AppSecret。
其中AppID和AppKey是客户端的应用标识,在客户端SDK初始化时使用;AppSecret是应用私钥,在使用服务器 SDK向客户端发送消息时使用。
APNs证书是一种扩展名为p12的文件,它是我们发送消息给APNs的证明。在开发时我们分Development环境与Distribution环境。所以p12会有两个版本:Development
与 Distribution。NOTE: 创建证书时请携带密码。
3.Save。注意文件格式
我们的libMiPushSDK库文件同时包含i386、x86_64、arm64、armv6和armv7的代码,所以libMiPushSDK将同时支持真机与模拟器。但由于Apple推送不支持模拟器,请使用真机测试功能。
运行SDK注册小米推送服务的时候,需要使用AppID,AppKey,等参数来验证使用者的合法性。
MiSDKAppID 1000888 MiSDKAppKey 500088888888 MiSDKRun Online
!--请注意MiSDKRun写法, 用buildSetting里面的宏替换--MiSDKAppID 1000888 MiSDKAppKey 500088888888 MiSDKRun ${MiSDKRun}
工作流程:
// 只启动APNs. [MiPushSDK registerMiPush:self];
// 同时启用APNs跟应用内长连接 [MiPushSDK registerMiPush:self type:0 connect:YES];
#pragma mark UIApplicationDelegate - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { // 注册APNS成功, 注册deviceToken [MiPushSDK bindDeviceToken:deviceToken]; } - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { // 注册APNS失败 // 自行处理 }
SDK中所有请求操作都是异步的。调用成功与失败都会通过MiPushSDKDelegate来通知。
其中包括:注册小米推送,绑定deviceToken,设置Alias,订阅Topic,帐号Account,App统计打点等。
#import "MiPushSDK.h" // <-- @interface MPAppDelegate : UIResponder < MiPushSDKDelegate, // <-- UIApplicationDelegate > @property (strong, nonatomic) UIWindow *window; @end
#pragma mark MiPushSDKDelegate - (void)miPushRequestSuccWithSelector:(NSString *)selector data:(NSDictionary *)data { // 请求成功 } - (void)miPushRequestErrWithSelector:(NSString *)selector error:(int)error data:(NSDictionary *)data { // 请求失败 }
当App启动并运行在前台时,SDK内部会运行一个Socket长连接连接到Server端,以接收消息推送。收到消息时回通过MiPushSDKDelegate来通知
- ( void )miPushReceiveNotification:( NSDictionary *)data { // 长连接收到的消息。消息格式跟APNs格式一样 }
- ( void )application:( UIApplication *)application didReceiveRemoteNotification:( NSDictionary *)userInfo { [ MiPushSDK handleReceiveRemoteNotification :userInfo]; // 使用此方法后,所有消息会进行去重,然后通过miPushReceiveNotification:回调返回给App }
注册推送服务,绑定手机设备成功后,即可调用以下方法
// 设置别名 [MiPushSDK setAlias:@“alias”] // 订阅内容 [MiPushSDK subscribe:@“topic”] // 设置帐号 [MiPushSDK setAccount:@“account”]
Alias可以理解为regId的别名,开发者可以将alias设置为自己应用帐号系统的帐号,或者设备标识等。然后在使用ServerSDK发送消息的时候,即可直接指定发送给特定的alias,而不是regId,避免存储regId。
主题用来做广播消息。不同手机上的同一个App可以订阅同一个主题。通过发送主题消息的API,即可同时向所有订阅该主题的客户端发送消息。比如,您有一个新闻类的App,可以自定义“财经”、“体育”、“科技“等主题;对于经常阅读财经新闻的用户,您可以帮用户订阅“财经”类主题,当有新的财经要闻发生时,直接通过主题推送该新闻给所有订阅该主题的用户。
帐号,多设备设置同一个帐号, 发送消息时多设备可以同时收到。一般在多点登陆时使用,多设备使用同一个帐号,他们可以同时收到消息。
注:当启用长连接时,不需要在进行此操作。
当App工作在前台或后台,收到推送消息后,请实现下面代码,已统计用户开启App事件。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ...... [MiPushSDK registerMiPush:self type:0 connect:YES]; NSString *messageId = [userInfo objectForKey:@"_id_"]; if (messageId!=nil) { [MiPushSDK openAppNotify:messageId]; } ...... }
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { NSString *messageId = [userInfo objectForKey:@"_id_"]; [MiPushSDK openAppNotify:messageId]; }
当iOS7
你使用RemoteNotification时,请实现下面代码
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { NSString *messageId = [userInfo objectForKey:@"_id_"]; [MiPushSDK openAppNotify:messageId]; }
当用户收到消息的时候,提供一个快速回复的按钮。具体信息可参考
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/IPhoneOSClientImp.html
#pragma mark MiPushSDKDelegate - (void)miPushRequestSuccWithSelector:(NSString *)selector data:(NSDictionary *)data { ... if ([selector isEqualToString:@"bindDeviceToken:"]) { UIMutableUserNotificationAction *action = [[UIMutableUserNotificationAction alloc] init]; action.identifier = @"action1"; //按钮的标示 action.title=@"启动"; //按钮的标题 action.activationMode = UIUserNotificationActivationModeForeground;//当点击的时候启动程序 UIMutableUserNotificationAction *action2 = [[UIMutableUserNotificationAction alloc] init]; action2.identifier = @"action2"; action2.title=@"忽略"; action2.activationMode = UIUserNotificationActivationModeBackground;//当点击的时候不启动程序,在后台处理 action.authenticationRequired = YES;//需要解锁才能处理 action.destructive = YES; UIMutableUserNotificationCategory *categorys = [[UIMutableUserNotificationCategory alloc] init]; categorys.identifier = @"category"; //这组动作的唯一标示 [categorys setActions:@[action,action2] forContext:(UIUserNotificationActionContextMinimal)]; UIUserNotificationSettings *uns = [UIUserNotificationSettings settingsForTypes: (UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound) categories:[NSSet setWithObjects:categorys, nil]]; [[UIApplication sharedApplication] registerUserNotificationSettings:uns]; } }
为了方便开发调试,除了Distribution服务器外,我们还提供Development服务器。为了避免影响已发布的App,您可以在Development服务器上开发调试,开发完毕再切换到Distribution服务器。
Apple签名APNs证书也分Development/Distribution。并且终端应用在不同环境下获得的deviceToken也不同。
开启Info.plist文件,修改MiSDKRun参数。Debug:Development服务器。Online:Distribution服务器
MiPushSDK.h 分两部分 @interface MiPushSDK ,@protocol MiPushSDKDelegate
MiPushSDK是小米推送服务在iOS平台的接入类。单实例。并提供了一系列静态方法。
表 1.
API | 功能 | 使用场景 |
---|---|---|
+ (void)registerMiPush:(id |
客户端注册设备 | 由开发者选择注册MiPushSDK时机。建议在程序启动时调用此方法 |
+ (void)registerMiPush:(id |
客户端注册设备,并设置消息类型 | 由开发者选择注册MiPushSDK时机。建议在程序启动时调用此方法 |
+ (void)registerMiPush:(id |
客户端注册设备,并设置消息类型与是否使用长连接 | 由开发者选择注册MiPushSDK时机。建议在程序启动时调用此方法 |
+ (void)unregisterMiPush | 客户端设备注销 | 当App选择停止推送功能的时候调用此方法。 |
+ (void)bindDeviceToken:(NSData *)deviceToken | 绑定 PushDeviceToken | 代码必须写在如下方法里。 – (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken |
+ (void)setAlias:(NSString *)alias | 为指定用户设置别名 | 在成功注册设备并绑定DeviceToken后调用 |
+ (void)unsetAlias:(NSString *)alias | 取消指定用户的别名 | 在成功注册设备并绑定DeviceToken后调用 |
+ (void)setAccount:(NSString *)account | 为指定用户设置帐号 | 在成功注册设备并绑定DeviceToken后调用 |
+ (void)unsetAccount:(NSString *)account | 取消指定用户的帐号 | 在成功注册设备并绑定DeviceToken后调用 |
+ (void)subscribe:(NSString *)topic | 为某个用户设置订阅主题 | 在成功注册设备并绑定DeviceToken后调用 |
+ (void)unsubscribe:(NSString *)topic | 取消某个用户的订阅主题 | 在成功注册设备并绑定DeviceToken后调用 |
+ (void)getAllAliasAsync | 获取客户端设置的别名。 | 在成功注册设备并绑定DeviceToken后调用 |
+ (void)getAllTopicAsync | 获取客户端订阅的主题。 | 在成功注册设备并绑定DeviceToken后调用 |
+ (void)getAllAccountAsync | 获取客户端订阅的帐号。 | 在成功注册设备并绑定DeviceToken后调用 |
+ (void)openAppNotify:(NSString *)messageId | 统计客户端通过推送,而开启App的行为。 | 在成功注册设备并绑定DeviceToken后调用 |
+ (NSString*)getSDKVersion | 获取SDK版本号。 |
MiPushSDKDelegate SDK的所有请求都是异步操作,用户需监听此方法。
表 2.
API | 功能 |
---|---|
- (void)miPushRequestSuccWithSelector:(NSString *)selector data:(NSDictionary *)data |
当请求成功时返回 |
- (void)miPushRequestErrWithSelector:(NSString *)selector error:(int)error data:(NSDictionary *)data |
当请求失败时返回 |
建议在程序启动时调用此方法,代码放到以下代码块中。这是因为,如果用户重装了iOS或者用户换了设备并且恢复程序备份到一个新的设备,都将导致这个token值不一样。
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
表 3.
参数列表 | 参数说明 |
---|---|
(id |
加入请求成功与失败的监听 |
建议在程序启动时调用此方法,代码放到以下代码块中。这是因为,如果用户重装了iOS或者用户换了设备并且恢复程序备份到一个新的设备,都将导致这个token值不一样。
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
表 4.
参数列表 | 参数说明 |
---|---|
(id |
加入请求成功与失败的监听 |
type:(UIRemoteNotificationType)type | 消息类型:UIRemoteNotificationTypeBadge, UIRemoteNotificationTypeSound, UIRemoteNotificationTypeAlert, UIRemoteNotificationTypeNewsstandContentAvailability |
建议在程序启动时调用此方法,代码放到以下代码块中。这是因为,如果用户重装了iOS或者用户换了设备并且恢复程序备份到一个新的设备,都将导致这个token值不一样。
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
表 5.
参数列表 | 参数说明 |
---|---|
(id |
加入请求成功与失败的监听 |
type:(UIRemoteNotificationType)type | 消息类型:UIRemoteNotificationTypeBadge, UIRemoteNotificationTypeSound, UIRemoteNotificationTypeAlert, UIRemoteNotificationTypeNewsstandContentAvailability |
connect:(BOOL)connect | 是否启动应用内长连接 |
当客户端决定关闭推送功能的时候调用此方法。并且需要注意,在下次程序启动的时候不要调用registerMiPush:。否则推送又将被开启
小米推送服务关闭后,在调用其他功能性API都将提示错误。
向MiPush注册deviceToken。为保证消息可达,必须在系统application:didRegisterForRemoteNotificationsWithDeviceToken:调用。SDK内部会处理是否重新同步上传
表 6.
参数列表 | 参数说明 |
---|---|
(NSData *)deviceToken | 设备的唯一标示,有Apple分配。 application:didRegisterForRemoteNotificationsWithDeviceToken: 返回的内容. |
开发者可以为指定用户设置别名,然后给这个别名推送消息,效果等同于给regId推送消息。注:
一个regId可以被设置多个别名,如果设置的别名已经存在,会覆盖掉之前的别名。不要超过100个
在成功注册设备并绑定DeviceToken后调用,当关闭推送功能后再调用此方法将会失败
表 7.
参数列表 | 参数说明 |
---|---|
(NSString *)alias | 为指定用户设置别名 |
开发者可以取消指定用户的某个别名,服务器就不会给这个别名推送消息了。
在成功注册设备并绑定DeviceToken后调用,当关闭推送功能后再调用此方法将会失败
表 8.
参数列表 | 参数说明 |
---|---|
(NSString *)alias | 为指定用户设置别名 |
开发者可以为指定用户设置帐号,然后给这个帐号推送消息,效果等同于给regId推送消息。注: 一个regId可以被设置多个帐号。不要超过100个
在成功注册设备并绑定DeviceToken后调用,当关闭推送功能后再调用此方法将会失败
表 9.
参数列表 | 参数说明 |
---|---|
(NSString *)account | 为指定用户设置帐号 |
开发者可以取消指定用户的某个帐号,服务器就不会给这个帐号推送消息了。
在成功注册设备并绑定DeviceToken后调用,当关闭推送功能后再调用此方法将会失败
表 10.
参数列表 | 参数说明 |
---|---|
(NSString *)account | 为指定用户设置帐号 |
为某个用户设置订阅主题;根据用户订阅的不同主题,开发者可以根据订阅的主题实现分组群发。
支持同时设置多个topic, 中间使用”,”分隔
在成功注册设备并绑定DeviceToken后调用,当关闭推送功能后再调用此方法将会失败
表 11.
参数列表 | 参数说明 |
---|---|
(NSString *)topic | 某个用户订阅的主题 |
为某个用户取消某个订阅主题。
支持同时设置多个topic, 中间使用”,”分隔
在成功注册设备并绑定DeviceToken后调用,当关闭推送功能后再调用此方法将会失败
表 12.
参数列表 | 参数说明 |
---|---|
(NSString *)topic | 某个用户取消订阅的主题 |
统计客户端,通过推送开启App行为。如果你想使用MiPush服务器帮你统计点击量 请自行调用此方法。然后登陆推送后台推送统计查看数据。
在成功注册设备并绑定DeviceToken后调用,当关闭推送功能后再调用此方法将会失败
表 13.
参数列表 | 参数说明 |
---|---|
(NSString *)messageId | 每条通知都会有一条唯一索引, 保存在Payload里面的miid。统计时需要携带此参数。以作为消息跟踪 |
获取客户端设置的别名列表。
在成功注册设备并绑定DeviceToken后调用,当关闭推送功能后再调用此方法将会失败
获取客户端设置的帐号列表。
在成功注册设备并绑定DeviceToken后调用,当关闭推送功能后再调用此方法将会失败
获取客户端订阅的主题列表。
在成功注册设备并绑定DeviceToken后调用,当关闭推送功能后再调用此方法将会失败
获取SDK版本号
当请求成功后,会回调此方法
表 14.
参数列表 | 参数说明 |
---|---|
(NSString *)selector | 请求调用方法的名称。例: “setAlias:” |
(NSDictionary *)data | 请求后下发的服务器信息。 |
当请求失败后,会回调此方法
表 15.
参数列表 | 参数说明 |
---|---|
(NSString *)selector | 请求调用方法的名称。例: “setAlias:” NOTE: 最后参数后面的冒号 |
(int)error | 错误码。参加“错误码说明” |
(NSDictionary *)data | 请求后下发的服务器信息。 |
表 16.
错误码 | 说明 |
---|---|
-1 | 访问超时,网络信号不好 |
-2 | 无网络 |
-3 | 未知错误,通常意味着MiPush服务器的业务错误 |
-4 | 操作太频繁 |
-5 | 请求无效参数 |
-6 | 返回结果无效 |
-100 | 无效的UserID |
-101 | 无效的RegID |
请检查以下几点
Error is Error Domain=NSCocoaErrorDomain Code=3000 "未找到应用程序的“aps-environment”的授权字符串" UserInfo=0x17dbf200 {NSLocalizedDescription=未找到应用程序的“aps-environment”的授权字符串}
检查事项 同4.1
清除方法:
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
如果无效请尝试,原因是,在推送时badge设置为0,这样你在app中再次设置就会失效
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:1]; [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
SDK中方法为异步操作,setAlias: subscribe:等操作必须在bindDeviceToken:返回成功后再调用。
因为bindDeviceToken成功请求后服务器才会分配账号给设备。如果setAlias操作在它前面执行,会找不到对应设备。
当App在后台,通过下面方法
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
当新App的时候,通过下面方法
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
SDK中会检查,如果此操作已经完成过,就不会重复请求服务器。
一个设备最多可以设置300个, 支持汉字。
App在后台,收到消息后,会在后台运行一段代码。并不会提示用户。比如,App内容升级,Email更新,订阅内容等等
在server端发送消息时extra加入content-available字段。同时xcode工程下激活BackgroundModes-Remote notifications。
在App运行时 ,APNs会提示用户是否接收消息,很多时候,用户会禁止此功能。导致,推送消息无法送达到用户手机。所以使用长连接功能,可以在App运行时,获取消息推送。
操作步骤:
1. 添加libMiPushSDK.a , MiPushSDK.h 到工程 2. 引入库:libresolv.dylib, libxml2.dylib, libz.dylib, SystemConfiguration.framework,MobileCoreServices.framework,CFNetwork.framework,CoreTelephony.framework (如果已经引入,请忽略) 3. 加入如下代码, 启动长连接 + (void)registerMiPush:(id)delegate type:(UIRemoteNotificationType)type connect:(BOOL)connect; 4. 加入收到消息回调,当客户端收到MiPush推送时,此方法会被调用到,data格式同 application:didReceiveRemoteNotification: - (void)miPushReceiveNotification:(NSDictionary*)data; 5. 去掉原有处理通知逻辑,使用下面代替 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { [MiPushSDK handleReceiveRemoteNotification:userInfo]; }