推送

354 阅读3分钟

通过环信推送,讲述远程推送和本地推送

环信推送,当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;
    
}