iOS--环信的在线推送和离线推送
iOS--环信的在线推送和离线推送
指尖流年 发表于3个月前
iOS--环信的在线推送和离线推送
  • 发表于 3个月前
  • 阅读 58
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云实验室 1小时搭建人工智能应用,让技术更容易入门 免费体验 >>>   

今天做了环信的推送,有一些无名的bug着实让人头痛!快看看有没有和我掉进相同的坑里

-、推送前的准备工作

环信SDK的导入和配置上次说过了这次就直接跳过,证书也直接先过

1.进入环信管理后台,找到所创建的项目如图

选择 推送证书

结果:

二、回到工程代码中:

1初始化环信SDK

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //AppKey:注册的AppKey,详细见下面注释。
    //apnsCertName:推送证书名(不需要加后缀),详细见下面注释。
    NSString *apnsCertName = nil;
    
#if DEBUG
    apnsCertName = @"kaifa";
#else
    apnsCertName = @"shengchan";
#endif
    EMOptions *options = [EMOptions optionsWithAppkey:@"douser#istore"];
    options.apnsCertName =apnsCertNam;
    [[EMClient sharedClient] initializeSDKWithOptions:options];
    
    //登录环信
    EMError *error1 = [[EMClient sharedClient] loginWithUsername:[[NSUserDefaults standardUserDefaults] objectForKey:@"uuid"]  password:[[NSUserDefaults standardUserDefaults] objectForKey:@"password"]];
    
     NSLog(@"ppppppperror1:%d",error1.code);
//自动登录
    [[EMClient sharedClient].options setIsAutoLogin:YES];

//**********环信推送
  //添加监听在线推送消息
    
    [[EMClient sharedClient].chatManager addDelegate:self delegateQueue:nil];
//iOS8以上 注册APNS
    if ([application respondsToSelector:@selector(registerForRemoteNotifications)]) {
        [application registerForRemoteNotifications];
        UIUserNotificationType notificationTypes = UIUserNotificationTypeBadge |
        UIUserNotificationTypeSound |
        UIUserNotificationTypeAlert;

        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:notificationTypes categories:nil];
        [application registerUserNotificationSettings:settings];
    }
    else{
        UIRemoteNotificationType notificationTypes = UIRemoteNotificationTypeBadge |
        UIRemoteNotificationTypeSound |
        UIRemoteNotificationTypeAlert;
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:notificationTypes];
    }
    return YES;
}
//将得到的deviceToken传给SDK
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken{
    
    //极光推送
    [JPUSHService registerDeviceToken:deviceToken];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //环信推送
        [[EMClient sharedClient] bindDeviceToken:deviceToken];
        
        NSLog(@"环信推送deviceToken:%@",deviceToken);
        
       // 7a7c8847b366d8cb4cc4c13681b7e9ec99a9c10d31780f57cd7e43745e0cdc23
    });
    
}

//注册deviceToken失败

- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error{
    
    NSLog(@"deviceToken-----error -- %@",error);
    
}

// APP进入后台

- (void)applicationDidEnterBackground:(UIApplication*)application

{
    
    [[EMClient sharedClient]applicationDidEnterBackground:application];
    
}

// APP将要从后台返回

- (void)applicationWillEnterForeground:(UIApplication*)application

{
    
    [[EMClient sharedClient]applicationWillEnterForeground:application];
    
}

 

本地推送,主要在- (void)messagesDidReceive:(NSArray*)aMessages这个方法中

//监听环信在线推送消息

- (void)messagesDidReceive:(NSArray*)aMessages{

     //aMessages是一个对象,包含了发过来的所有信息,怎么提取想要的信息我会在后面贴出来.
    
    for (EMMessage *message in aMessages) {
        
       // EMConversation *conversation = [[EMClient sharedClient].chatManager getConversation:message.conversationId type:EMConversationTypeChat createIfNotExist:YES];
        
        id<IMessageModel> model = nil;
        model = [[EaseMessageModel alloc] initWithMessage:message];
        
        NSString *nickname = model.nickname;
        
        EMMessageBody *msgBody = message.body;
        switch (msgBody.type) {
            case EMMessageBodyTypeText:
            {
                // 收到的文字消息
                EMTextMessageBody *textBody = (EMTextMessageBody *)msgBody;
               // NSString *txt = [NSString stringWithFormat:@"%@给您发了一条消息:%@",nickname,textBody.text];
               
              //  NSLog(@"--------------收到的文字是 txt -- %@",txt);
                
                    UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:@"提示"message:@"您收到了一条信息" delegate:nil cancelButtonTitle:@"取消"otherButtonTitles:@"确定",nil];
                
                
                    [alertView show];
                
                
            }
                break;
            case EMMessageBodyTypeImage:
            {
                // 得到一个图片消息body
               // EMImageMessageBody *body = ((EMImageMessageBody *)msgBody);
                
                
                
                
                //                NSLog(@"大图remote路径 -- %@"   ,body.remotePath);
                //                NSLog(@"大图local路径 -- %@"    ,body.localPath); // // 需要使用sdk提供的下载方法后才会存在
                //                NSLog(@"大图的secret -- %@"    ,body.secretKey);
                //                NSLog(@"大图的W -- %f ,大图的H -- %f",body.size.width,body.size.height);
                //                NSLog(@"大图的下载状态 -- %lu",body.downloadStatus);
                //
                //
                //                // 缩略图sdk会自动下载
                //                NSLog(@"小图remote路径 -- %@"   ,body.thumbnailRemotePath);
                //                NSLog(@"小图local路径 -- %@"    ,body.thumbnailLocalPath);
                //                NSLog(@"小图的secret -- %@"    ,body.thumbnailSecretKey);
                //                NSLog(@"小图的W -- %f ,大图的H -- %f",body.thumbnailSize.width,body.thumbnailSize.height);
                //                NSLog(@"小图的下载状态 -- %lu",body.thumbnailDownloadStatus);
            }
                break;
                //            case EMMessageBodyTypeLocation:
                //            {
                //                EMLocationMessageBody *body = (EMLocationMessageBody *)msgBody;
                //                NSLog(@"纬度-- %f",body.latitude);
                //                NSLog(@"经度-- %f",body.longitude);
                //                NSLog(@"地址-- %@",body.address);
                //            }
                //                break;
                //            case EMMessageBodyTypeVoice:
                //            {
                //                // 音频sdk会自动下载
                //                EMVoiceMessageBody *body = (EMVoiceMessageBody *)msgBody;
                //                NSLog(@"音频remote路径 -- %@"      ,body.remotePath);
                //                NSLog(@"音频local路径 -- %@"       ,body.localPath); // 需要使用sdk提供的下载方法后才会存在(音频会自动调用)
                //                NSLog(@"音频的secret -- %@"        ,body.secretKey);
                //                NSLog(@"音频文件大小 -- %lld"       ,body.fileLength);
                //                NSLog(@"音频文件的下载状态 -- %lu"   ,body.downloadStatus);
                //                NSLog(@"音频的时间长度 -- %lu"      ,body.duration);
                //            }
                //                break;
                //            case EMMessageBodyTypeVideo:
                //            {
                //                EMVideoMessageBody *body = (EMVideoMessageBody *)msgBody;
                //
                //                NSLog(@"视频remote路径 -- %@"      ,body.remotePath);
                //                NSLog(@"视频local路径 -- %@"       ,body.localPath); // 需要使用sdk提供的下载方法后才会存在
                //                NSLog(@"视频的secret -- %@"        ,body.secretKey);
                //                NSLog(@"视频文件大小 -- %lld"       ,body.fileLength);
                //                NSLog(@"视频文件的下载状态 -- %lu"   ,body.downloadStatus);
                //                NSLog(@"视频的时间长度 -- %lu"      ,body.duration);
                //                NSLog(@"视频的W -- %f ,视频的H -- %f", body.thumbnailSize.width, body.thumbnailSize.height);
                //
                //                // 缩略图sdk会自动下载
                //                NSLog(@"缩略图的remote路径 -- %@"     ,body.thumbnailRemotePath);
                //                NSLog(@"缩略图的local路径 -- %@"      ,body.thumbnailLocalPath);
                //                NSLog(@"缩略图的secret -- %@"        ,body.thumbnailSecretKey);
                //                NSLog(@"缩略图的下载状态 -- %lu"      ,body.thumbnailDownloadStatus);
                //            }
                //                break;
                //            case EMMessageBodyTypeFile:
                //            {
                //                EMFileMessageBody *body = (EMFileMessageBody *)msgBody;
                //                NSLog(@"文件remote路径 -- %@"      ,body.remotePath);
                //                NSLog(@"文件local路径 -- %@"       ,body.localPath); // 需要使用sdk提供的下载方法后才会存在
                //                NSLog(@"文件的secret -- %@"        ,body.secretKey);
                //                NSLog(@"文件文件大小 -- %lld"       ,body.fileLength);
                //                NSLog(@"文件文件的下载状态 -- %lu"   ,body.downloadStatus);
                //            }
                //                break;
                
            default:
                break;
        }
    }
    
    
}

@property (strong, nonatomic) NSDate *lastPlaySoundDate;

//在后台运行时调用 推送
- (void)didReceiveMessages:(NSArray *)aMessages
{
    for(EMMessage *message in aMessages){
        UIApplicationState state = [[UIApplication sharedApplication] applicationState];
        switch (state) {
            case UIApplicationStateBackground:
                [self showNotificationWithMessage:message];
                break;
            default:
                break;
        }
    }
}
- (void)playSoundAndVibration{
    NSTimeInterval timeInterval = [[NSDate date]
                                   timeIntervalSinceDate:self.lastPlaySoundDate];
    if (timeInterval < 3.0) {
        //如果距离上次响铃和震动时间太短, 则跳过响铃
        NSLog(@"skip ringing & vibration %@, %@", [NSDate date], self.lastPlaySoundDate);
        return;
    }
    
    //保存最后一次响铃时间
    self.lastPlaySoundDate = [NSDate date];
    
    // 收到消息时,播放音频
    [[EMCDDeviceManager sharedInstance] playNewMessageSound];
    // 收到消息时,震动
    [[EMCDDeviceManager sharedInstance] playVibration];
}

- (void)showNotificationWithMessage:(EMMessage *)message
{
 
    
    EMPushOptions *options = [[EMClient sharedClient] pushOptions];

    
    
    NSString *alertBody = nil;
    if (options.displayStyle == EMPushDisplayStyleMessageSummary) {
        EMMessageBody *messageBody = message.body;
        NSString *messageStr = nil;
        switch (messageBody.type) {
            case EMMessageBodyTypeText:
            {
                messageStr = ((EMTextMessageBody *)messageBody).text;
            }
                break;
            case EMMessageBodyTypeImage:
            {
                messageStr = NSLocalizedString(@"message.image", @"Image");
            }
                break;
            case EMMessageBodyTypeLocation:
            {
                messageStr = NSLocalizedString(@"message.location", @"Location");
            }
                break;
            case EMMessageBodyTypeVoice:
            {
                messageStr = NSLocalizedString(@"message.voice", @"Voice");
            }
                break;
            case EMMessageBodyTypeVideo:{
                messageStr = NSLocalizedString(@"message.video", @"Video");
            }
                break;
            default:
                break;
        }
        
        do {
            // NSString *title = [[UserProfileManager sharedInstance] getNickNameWithUsername:message.from];
            if (message.chatType == EMChatTypeGroupChat) {
                NSDictionary *ext = message.ext;
                if (ext && ext[kGroupMessageAtList]) {
                    id target = ext[kGroupMessageAtList];
                    if ([target isKindOfClass:[NSString class]]) {
                        if ([kGroupMessageAtAll compare:target options:NSCaseInsensitiveSearch] == NSOrderedSame) {
                            //alertBody = [NSString stringWithFormat:@"%@%@", title, NSLocalizedString(@"group.atPushTitle", @" @ me in the group")];
                            break;
                        }
                    }
                    else if ([target isKindOfClass:[NSArray class]]) {
                        NSArray *atTargets = (NSArray*)target;
                        if ([atTargets containsObject:[EMClient sharedClient].currentUsername]) {
                            // alertBody = [NSString stringWithFormat:@"%@%@", title, NSLocalizedString(@"group.atPushTitle", @" @ me in the group")];
                            break;
                        }
                    }
                }
                NSArray *groupArray = [[EMClient sharedClient].groupManager getJoinedGroups];
                for (EMGroup *group in groupArray) {
                    if ([group.groupId isEqualToString:message.conversationId]) {
                        // title = [NSString stringWithFormat:@"%@(%@)", message.from, group.subject];
                        break;
                    }
                }
            }
            else if (message.chatType == EMChatTypeChatRoom)
            {
                NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
                NSString *key = [NSString stringWithFormat:@"OnceJoinedChatrooms_%@", [[EMClient sharedClient] currentUsername]];
                NSMutableDictionary *chatrooms = [NSMutableDictionary dictionaryWithDictionary:[ud objectForKey:key]];
                NSString *chatroomName = [chatrooms objectForKey:message.conversationId];
                if (chatroomName)
                {
                    // title = [NSString stringWithFormat:@"%@(%@)", message.from, chatroomName];
                }
            }
            
            //alertBody = [NSString stringWithFormat:@"%@:%@", title, messageStr];
        } while (0);
    }
    else{
        alertBody = NSLocalizedString(@"您收到了一条消息", @"you have a new message");
    }
    
    NSTimeInterval timeInterval = [[NSDate date] timeIntervalSinceDate:self.lastPlaySoundDate];
    BOOL playSound = NO;
    if (!self.lastPlaySoundDate || timeInterval >= 3.0) {
        self.lastPlaySoundDate = [NSDate date];
        playSound = YES;
    }
    
    NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
    [userInfo setObject:[NSNumber numberWithInt:message.chatType] forKey:@"MessageType"];
    [userInfo setObject:message.conversationId forKey:@"ConversationChatter"];
    
    //发送本地推送
    if (NSClassFromString(@"UNUserNotificationCenter")) {
        UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:0.01 repeats:NO];
        UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
        if (playSound) {
            content.sound = [UNNotificationSound defaultSound];
        }
        content.body =alertBody;
        content.userInfo = userInfo;
        UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:message.messageId content:content trigger:trigger];
        [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:nil];
    }
    else {
        UILocalNotification *notification = [[UILocalNotification alloc] init];
        notification.fireDate = [NSDate date]; //触发通知的时间
        notification.alertBody = alertBody;
        notification.alertAction = NSLocalizedString(@"open", @"Open");
        notification.timeZone = [NSTimeZone defaultTimeZone];
        if (playSound) {
            notification.soundName = UILocalNotificationDefaultSoundName;
        }
        notification.userInfo = userInfo;
        
        //发送通知
        [[UIApplication sharedApplication] scheduleLocalNotification:notification];
        
        
    }
}

 

代码就这么多。这样既有本地推送又有离线推送,如果做完了这些,还是收不到离线推送(app被关闭或者进入后台三分钟之后),就要看以下方面了:

1.看看你环信后台上传的证书名称与工程中初始化SDK的证书名是否一致

2.配置证书时候填的Bundle Identifier与你工程中的Bundle Identifier是否相同

3. deviceToken有没有传给环信SDK。即查看管理后台中,对应 IM 账户下是否有您刚刚写的证书名。(这两个方法有没有实现)

//将得到的deviceToken传给SDK

- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken{

      //极光推送

    [JPUSHService registerDeviceToken:deviceToken];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        //环信推送

        [[EMClient sharedClient] bindDeviceToken:deviceToken];

             NSLog(@"环信推送deviceToken:%@",deviceToken);

    });}

 

//注册deviceToken失败

- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error{    

    NSLog(@"deviceToken-----error -- %@",error);

}

4.确认Xcode环境是否配置正确 ,Build Settings---signing,看Debug对应的是不是开发的,Release对应的是不是生产的

5.在确认xcode运行环境是否正确 (Product-->Scheme-->Edit Scheme, 开发证书选Debug,生产证书选Release)

6.证书制作上传过程是否有问题,开发环境和生产环境是否一一对应。另外可以用推送工具进行验证(Easy APNs Provider - 推送测试工具)。

7.如果以上都没有问题,可以尝试重新制作上传一下推送证书。

最后,上张图

 

 

不足之处,请留言,谢谢!

 

 

共有 人打赏支持
粉丝 4
博文 43
码字总数 15394
×
指尖流年
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: