====== iOS 推送集成 ======
本文档为IM SDK中关于推送功能的集成说明。
===== iOS SDK 使用须知 =====
使用 SDK 之前,你需先创建应用,获取应用的唯一标识 App Key,请参见[[https://docs-im.easemob.com/im/quickstart/guide/experience|注册并创建应用]]。
环信推送分为在线推送和远程推送,远程推送时通过 APNS 下发,所以你需要配置应用对应的证书,请参见[[https://docs-im.easemob.com/im/ios/apns/deploy|APNS 推送配置]]。
===== 集成 SDK =====
环信 SDK 支持 pod 方式导入和手动导入两种方式,任选其一即可,下面分别介绍这两种导入方式。
**注意**
自 3.8.7 版本开始,SDK 只支持 iOS 10 及以上版本。
==== Pod 导入 SDK ====
推荐使用 Cocoapods 集成环信 SDK。Cocoapods 提供了一个简单的依赖管理系统,避免手动导入产生的错误(首先需要确认已经安装了 Cocoapods,如果没有安装过 Cocoapods,请参考[[https://www.cnblogs.com/wangluochong/p/5567082.html|安装使用指南]]。
sudo gem install cocoapods
pod setup
在 Xcode 项目的根目录下,新建一个空文件,命名为 ''%%Podfile%%'',向此文件添加以下行:
pod 'HyphenateChat'
在 ''%%Podfile%%'' 目录下,执行以下指令:
pod install --repo-update
执行 ''%%pod install%%'' 后,打开工程目录,找到 ''%%.xcworkspace%%'' 文件运行即可。
==== 手动导入 ====
[[https://www.easemob.com/download/im|下载环信 demo]]
开发者最开始集成,如果选择手动导入文件集成的方式,只需要向工程中添 HyphenateChat 就可以,下面会介绍具体的集成方式。
demo 中的 SDK 文件夹为 **Hyphenate SDK**,将 SDK 文件夹拖入到工程中,并勾选截图中标注的三项。
{{https://docs-im.easemob.com/_media/im/ios/sdk/%E9%80%89%E9%A1%B9.png}}
\
设置工程属性
在 Xcode 中,向 **General > Embedded Binaries** 中添加依赖库\
**注意**
将**Do Not Embed** 改成**Embed & Sign**。
{{https://docs-im.easemob.com/_media/im/ios/sdk/04380a97-8a50-4e50-bcb0-5c9d6d4d9818.png?cache=}}
===== SDK 基础功能 =====
环信推送和环信 IM 使用相同的 SDK,使用功能都需要初始化 SDK 并进行登录操作。
==== 初始化 SDK ====
第 1 步:引入相关头文件 ''%%#import %%''。
第 2 步:在工程的 AppDelegate 中的以下方法中,调用 SDK 对应方法。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//AppKey:注册的 AppKey,详细见下面注释。
//apnsCertName:推送证书名(不需要加后缀),详细见下面注释。
EMOptions *options = [EMOptions optionsWithAppkey:@"easemob-demo#easeim"];
options.apnsCertName = @"EaseIM_APNS_Developer";
[[EMClient sharedClient] initializeSDKWithOptions:options];
return YES;
}
// APP 进入后台。
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[[EMClient sharedClient] applicationDidEnterBackground:application];
}
// APP 将要从后台返回。
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[[EMClient sharedClient] applicationWillEnterForeground:application];
}
调用的 SDK 接口参数解释如下:\
App Key: 区别 APP 的标识,请参考[[https://docs-im.easemob.com/im/quickstart/guide/experience#%E6%B3%A8%E5%86%8C%E5%B9%B6%E5%88%9B%E5%BB%BA%E5%BA%94%E7%94%A8|开发者注册及管理后台]]。 \
apnsCertName: iOS 中推送证书名称,请参考[[https://docs-im.easemob.com/im/ios/apns/deploy|制作与上传推送证书]]。
==== SDK 登录流程 ====
登录:调用 SDK 的登录接口进行的操作。\
建议使用异步登录方法,防止网络不好的情况下,出现卡 UI 主线程的情况出现。
[[EMClient sharedClient] loginWithUsername:@"8001" password:@"111111" completion:^(NSString *aUsername, EMError *aError) {
if (!aError) {
NSLog(@"登录成功");
} else {
NSLog(@"登录失败的原因---%@", aError.errorDescription);
}
}];
有关更多注册登录等基础功能,请参考[[https://docs-im.easemob.com/im/ios/sdk/basic|iOS SDK基础功能]]。
===== SDK 推送集成 =====
== 1.注册开启推送通知 ==
if (NSClassFromString(@"UNUserNotificationCenter")) {
//注册推送,用于 iOS 10 及以上版本。
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert completionHandler:^(BOOL granted, NSError *error) {
if (granted) {
dispatch_async(dispatch_get_main_queue(), ^{
[application registerForRemoteNotifications];
});
}
}];
return;
}
if([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
//iOS 8 至 iOS 10 推送样式设置。
UIUserNotificationType notificationTypes = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:notificationTypes categories:nil];
[application registerUserNotificationSettings:settings];
}
if ([application respondsToSelector:@selector(registerForRemoteNotifications)]) {
//注册推送,用于 iOS 8 及以上版本。
[application registerForRemoteNotifications];
} else {
//注册推送,用于 iOS 8 之前版本。
UIRemoteNotificationType notificationTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:notificationTypes];
}
== 2.将获得的 deviceToken 传到 SDK ==
**注意**
如果是 iOS 13 及以上的系统,请将 SDK 更新至 v3.6.4 或以上版本。
// 将获得的 deviceToken 传给 SDK。
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[EMClient sharedClient] bindDeviceToken:deviceToken];
});
}
3.开启环信推送处理
[[EMLocalNotificationManager sharedManager] launchWithDelegate:self];
== 4.处理代理 ==
如果你需要推送相关信息,可以通过实现代理获取,环信提供的代理如下:
方式一
实现以下两个代理,通过 completionHandler 您可以更改通知方式:
- (void)emuserNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
NSDictionary *userInfo = notification.request.content.userInfo;
if ([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
NSLog(@"APNS userInfo : %@ ",userInfo);
}else{
NSLog(@"EaseMob userInfo : %@ \n ext : %@",userInfo,userInfo[@"ext"]);
}
completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert);//通知方式 可选 badge,sound,alert 如果实现了这个代理方法,则必须有 completionHandler 回调。
}
- (void)emuserNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler
{
NSDictionary *userInfo = response.notification.request.content.userInfo;
if ([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
NSLog(@"APNS userInfo : %@ \n ",userInfo);
}else{
NSLog(@"EaseMob userInfo : %@ \n ext : %@",userInfo,userInfo[@"ext"]);
}
completionHandler();//如果实现了这个代理方法 ,则必须有 ''%%completionHandler%%'' 回调。
}
方式二
通过下面代理获取推送相关信息:
//如果需要获取数据,只实现这一个代理方法即可。
- (void)emGetNotificationMessage:(UNNotification *)notification state:(EMNotificationState)state
{
NSDictionary *userInfo = notification.request.content.userInfo;
if ([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
//APNS 推送。
NSLog(@"APNS userInfo : %@ \n ",userInfo);
}else{
//本地推送。
NSLog(@"userInfo : %@ \n ext : %@",userInfo,userInfo[@"ext"]);
}
if (state == EMDidReceiveNotificationResponse) {
//打开通知 可通过扩展字段自己实现跳转。
}else{
//展示通知。
}
}
推送通知透传消息获取
//当应用收到环信推送透传消息时,此方法会被调用。
- (void)emDidRecivePushSilentMessage:(NSDictionary *)messageDic
{
NSLog(@"emDidRecivePushSilentMessage : %@",messageDic);
}
== 5.进阶 ==
iOS 的本地通知管理模块 ''%%UNUserNotificationCenter%%'' 是单例,一个 App 中只能有一个实例。如果在启用 SDK 在线推送后,App 又重写了 ''%%[UNUserNotificationCenter currentNotificationCenter].delegate%%'',会将 SDK 中的 delegate 覆盖,此时,需要在 App 实现的 ''%%UNUserNotificationCenterDelegate%%'' 中调用 SDK 的相关处理,过程如下:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
[[EMLocalNotificationManager sharedManager] userNotificationCenter:center willPresentNotification:notification withCompletionHandler:completionHandler];
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler
{
[[EMLocalNotificationManager sharedManager] userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
}
环信推送和 IM 使用相同的 SDK,可以查看 IMSDK [[https://docs-im.easemob.com/im/ios/apns/offline|[更多推送功能]]|。