通过环信推送,讲述远程推送和本地推送
环信推送,当App被杀死走APNS远程推送,当App在后台活跃或者App在前台,走的是长链接。 环信推送,类似微信。本质上还是聊天。无法像极光那样,给所有设备发送。极光推送,不管是App被杀死,还是App在前台或者后台都能实现远程推送。
注册SDK
EMOptions *options = [EMOptions optionsWithAppkey:HXAppKey];
// options.enableConsoleLog = YES;
options.apnsCertName = @"zp_push";
[[EMClient sharedClient] initializeSDKWithOptions:options];
环信登录
本质上是发消息,只有登录才能收到。极光可以根据DeviceToken推送,可以不登录就收到推送。
[[EMClient sharedClient] loginWithUsername:_ID password:@"123456" completion:^(NSString *aUsername, EMError *aError) {
NSLog(@"+++++++++%@+++++%d",aError.errorDescription,aError.code);
if (!aError) {
[[EMClient sharedClient].options setIsAutoLogin:YES];
EMPushOptions *options = [[EMClient sharedClient] pushOptions];
options.displayStyle = EMPushDisplayStyleMessageSummary; // 显示消息内容
// options.displayStyle = EMPushDisplayStyleSimpleBanner // 显示“您有一条新消息”
[[EMClient sharedClient] updatePushNotificationOptionsToServerWithCompletion:^(EMError *aError) {
if(!aError){
NSLog(@"更新推送设置到服务器成功");
} else {
NSLog(@"更新推送设置到服务器失败的原因 --- %@", aError.errorDescription);
}
}];
//登录成功后 获取离线消息
NSArray *conversations = [[EMClient sharedClient].chatManager getAllConversations];
for (EMConversation *conversation in conversations) {
if ([conversation unreadMessagesCount] > 0) {
[self showUnreadMessageHotView];
break;
}
}
}
}];
- options.displayStyle设置远程推送样式
- options.displayName设置你给别人发送消息,通过APNS推送给对方,对方那显示的昵称(apnsnickname).(apnsnickname也可在后端设置,这里就不用设置了)
推送设置
在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions里设置
//注册离线推送 和 本地通知
// iOS 10之后
if (NSClassFromString(@"UNUserNotificationCenter")) {
UNUserNotificationCenter.currentNotificationCenter.delegate = self; //本地通知需要实现 userNotificationCenter... 代理方法
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert completionHandler:^(BOOL granted, NSError *error) {
if (granted) {
[application registerForRemoteNotifications];
}
}];
return;
}
// iOS 8 -- iOS 10
if([application respondsToSelector:@selector(registerUserNotificationSettings:)])
{
UIUserNotificationType notificationTypes = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:notificationTypes categories:nil];
[application registerUserNotificationSettings:settings];
}
if ([application respondsToSelector:@selector(registerForRemoteNotifications)]) {
[application registerForRemoteNotifications]; // iOS 8.0 之后
}else{
// iOS 8.0 之前
UIRemoteNotificationType notificationTypes = UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound |
UIRemoteNotificationTypeAlert;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:notificationTypes];
}
注意实现本地通知,需要UNUserNotificationCenter.currentNotificationCenter.delegate = self; //本地通知需要实现 userNotificationCenter... 代理方法设置代理, 本地通知需要实现userNotificationCenter...代理方法。
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
// deviceToken传给SDK
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[EMClient sharedClient] bindDeviceToken:deviceToken];
});
/// Required - 注册 DeviceToken
// [JPUSHService registerDeviceToken:deviceToken];
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
//Optional
NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);
}
// iOS10之后 在前台收到通知 需要实现这个代理 iOS10之前在前台收不到通知
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionBadge);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
NSLog(@"---------------------------------");
// 1.打开后台模式 2.告诉系统是否有新内容的更新 3.发送的通知有固定的格式("content-available":"1")
// 2.告诉系统有新内容
completionHandler(UIBackgroundFetchResultNewData);
// Required, iOS 7 Support
// [JPUSHService handleRemoteNotification:userInfo];
// completionHandler(UIBackgroundFetchResultNewData);
}
// 收到通知处理
//- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
//
// // Required, For systems with less than or equal to iOS 6
//
// [JPUSHService handleRemoteNotification:userInfo];
//
//}
本地推送处理
在特定页面设置代理:[[EMClient sharedClient].chatManager addDelegate:self delegateQueue:nil];
代理方法,收到消息,处理本地通知
//收到消息
- (void)messagesDidReceive:(NSArray *)aMessages
{
for (EMMessage *msg in aMessages) {
UIApplicationState state = [[UIApplication sharedApplication] applicationState];
// UIViewController *vc = [PublicTool topViewControllerWithRootViewController:nil];
// (![vc isKindOfClass:[EMConversationsViewController class]] && ![vc isKindOfClass:[EMChatViewController class]])
NSLog(@"%@____%@",msg.ext,msg.messageId);
// App在后台
if (state == UIApplicationStateBackground) {
//发送本地推送
NSString *bodyContent = [self messageBodyTextWithMessage:msg];
NSDictionary *ext = msg.ext;
NSString *nickName;
if (ext) {
nickName = ext[@"nickName"];
}
if (!nickName) {
nickName = @"神秘人";
}
UIApplication *application = [UIApplication sharedApplication];
NSInteger bageNumber = application.applicationIconBadgeNumber;
if (NSClassFromString(@"UNUserNotificationCenter")) { // ios 10
// 设置触发时间
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:0.01 repeats:NO];
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.sound = [UNNotificationSound defaultSound];
// 提醒,可以根据需要进行弹出,比如显示消息详情,或者是显示“您有一条新消息”
content.body = bodyContent;
content.title = nickName;
content.badge = @(++bageNumber);
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:msg.messageId content:content trigger:trigger];
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:nil];
}else {
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = [NSDate date]; //触发通知的时间
notification.alertBody = bodyContent;
notification.alertAction = @"Open";
notification.alertTitle = nickName;
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
}
}
if (self.isViewAppear) {//LB是当前界面
if (!self.isNeedReload) {
self.isNeedReload = YES;
[self performSelector:@selector(_reSortedConversationModelsAndReloadView) withObject:nil afterDelay:0.8];
}
} else {
self.isNeedReload = YES;
// //显示小红点
// [APPDELEGATE.tabbar.tabBar showBadgeOnItemIndex:2];
}
}
-(NSString *)messageBodyTextWithMessage:(EMMessage *)msg{
NSString *content = @"";
EMMessageBody *messageBody = msg.body;
switch (messageBody.type) {
case EMMessageBodyTypeText:
{
NSString *str = [EMEmojiHelper convertEmoji:((EMTextMessageBody *)messageBody).text];
content = str;
}
break;
case EMMessageBodyTypeImage:
content = @"[图片]";
break;
case EMMessageBodyTypeVoice:
content = @"[音频]";
break;
case EMMessageBodyTypeLocation:
content = @"[位置]";
break;
case EMMessageBodyTypeVideo:
content = @"[视频]";
break;
case EMMessageBodyTypeFile:
content = @"[文件]";
break;
default:
break;
}
return content;
}