環信是一個提供聊天功能的公司,個人app裏面集成了環信,可是在使用的時候發現它給的文檔並非很完善,不少功能都寫的非常粗略,儘管Demo裏面功能很完善,可是由於代碼量比較大,看起來很是麻煩。尤爲是環信的demo使用了大量的第三方庫(並且過期了),不少跟我本地使用的都衝突了,集成起來可謂問題重重。接下來我就講一下我在集成環信的時候遇到的一些問題。app
聊天界面里老是要顯示聊天人頭像的,可是遍尋環信的文檔,竟然沒有關於這方面的隻言片語,可能有人會說demo裏面很完善啊,直接在demo裏找就行了啊,但是環信給的demo真的太大了,爲了找這個頭像設置的地方,我看源碼看了很久。後來才知道原來是使用了代理方法來設置的。async
在 ChatViewController.m中ChatViewControllerDelegate 代理有兩個方法就是分別用來設置聊天人頭像和名字的:ide
// 根據環信id獲得要顯示頭像路徑,若是返回nil,則顯示默認頭像 - (NSString *)avatarWithChatter:(NSString *)chatter; // 根據環信id獲得要顯示用戶名,若是返回nil,則默認顯示環信id - (NSString *)nickNameWithChatter:(NSString *)chatter;
設置本身頭像和名字的方法是在ChatViewController.m的工具
(NSMutableArray *)formatMessage:(EMMessage *)messageatom
方法中:
spa
//model是信息的模型 這裏判斷信息是否爲發送者全部,若是是,則設置發送者的頭像和姓名 不然設置接收者頭像和姓名 MessageModel *model = [MessageModelManager modelWithMessage:message]; if (model.isSender) {//設置發送者姓名和頭像 model.nickName = delegate.userInfoModel.userName; model.headImageURL = [NSURL URLWithString:delegate.userInfoModel.userLogo]; }else{//設置接收者姓名和頭像 model.nickName = [self.chatterInfo objectForKey:@"userName"]; model.headImageURL =[NSURL URLWithString:XZImageBaseURL([self.chatterInfo objectForKey:@"image" ])]; }
我用的時候沒有用環信的代理,而是所有直接傳過去的。3d
環信在受到消息以後能夠觸發代理來進行處理,好比刷新聊天列表或者在工具欄設置消息角標等等。代理方法是
代理
-(void)didReceiveMessage:(EMMessage *)messagecode
但是在設置這個的時候怎麼發消息都沒有觸發這個代理方法,我把demo翻了個遍,才找到了可能有用的地方:orm
#pragma mark - 環信 #pragma mark - private -(void)registerNotifications { [self unregisterNotifications]; [[EaseMob sharedInstance].chatManager addDelegate:self delegateQueue:nil]; [[EaseMob sharedInstance].callManager addDelegate:self delegateQueue:nil]; } -(void)unregisterNotifications { [[EaseMob sharedInstance].chatManager removeDelegate:self]; [[EaseMob sharedInstance].callManager removeDelegate:self]; }
這段代碼在demo中的MainViewController.m文件中。在個人代碼中添加了這段以後,收到消息時纔會觸發didReceiveMessage方法。
環信自己既支持離線推送又支持在線推送(在線推送就是在觸發了didreceivemessage以後設置的)。
離線推送:
離線推送的設置文檔裏講的其實很清楚了,但是在demo中還有更多的設置,好比免打擾羣消息等等的設置,若是這部分不作設置,離線推送是無法用的。這部分有點坑,儘管文檔中有講,但是也僅僅是列出了幾個方法而已,怎麼使用一句都沒講:
具體的設置在demo中的setting文件夾下的PushNotificationViewController.m文件裏。
- (void)savePushOptions { BOOL isUpdate = NO; EMPushNotificationOptions *options = [[EaseMob sharedInstance].chatManager pushNotificationOptions]; if (_pushDisplayStyle != options.displayStyle) { options.displayStyle = _pushDisplayStyle; isUpdate = YES; } if (_nickName && _nickName.length > 0 && ![_nickName isEqualToString:options.nickname]) { options.nickname = _nickName; isUpdate = YES; } if (options.noDisturbingStartH != _noDisturbingStart || options.noDisturbingEndH != _noDisturbingEnd){ isUpdate = YES; options.noDisturbStatus = _noDisturbingStatus; options.noDisturbingStartH = _noDisturbingStart; options.noDisturbingEndH = _noDisturbingEnd; } if (isUpdate) { [[EaseMob sharedInstance].chatManager asyncUpdatePushOptions:options]; } [self.navigationController popViewControllerAnimated:YES]; }
這裏設置的話有幾個參數,第一個是noDistrbStatus,這個參數設置的是是否設置免打擾
/*! @enum @brief 推送消息免打擾設置的狀態 @constant ePushNotificationNoDisturbStatusDay 全天免打擾 @constant ePushNotificationNoDisturbStatusCustom 自定義時間段免打擾 @constant ePushNotificationNoDisturbStatusClose 關閉免打擾模式 */ typedef NS_ENUM(NSInteger, EMPushNotificationNoDisturbStatus) { ePushNotificationNoDisturbStatusDay = 0, ePushNotificationNoDisturbStatusCustom = 1, ePushNotificationNoDisturbStatusClose = 2, };
若是第一個參數設置了關閉免打擾,那麼後兩個參數就沒有什麼卵用了,直接設置爲-1就好,但是若是設置的是自定義時間段免打擾,就須要設置時間(目前還只支持整點)這裏拿一個展開:
/*! @property @brief 推送消息免打擾模式開始時間,小時,暫時只支持整點(小時) */ @property (nonatomic) NSUInteger noDisturbingStartH;
本地推送:
本地推送就是在didReceiveMessage方法被觸發後進行設置的,在手機還在後臺的時候使用本地推送,應用徹底退出以後纔是離線推送。
設置的地方在MainViewController.m中
- (void)showNotificationWithMessage:(EMMessage *)message { EMPushNotificationOptions *options = [[EaseMob sharedInstance].chatManager pushNotificationOptions]; //發送本地推送 UILocalNotification *notification = [[UILocalNotification alloc] init]; notification.fireDate = [NSDate date]; //觸發通知的時間 if (options.displayStyle == ePushNotificationDisplayStyle_messageSummary) { id<IEMMessageBody> messageBody = [message.messageBodies firstObject]; NSString *messageStr = nil; switch (messageBody.messageBodyType) { case eMessageBodyType_Text: { messageStr = ((EMTextMessageBody *)messageBody).text; } break; case eMessageBodyType_Image: { messageStr = NSLocalizedString(@"message.image", @"Image"); } break; case eMessageBodyType_Location: { messageStr = NSLocalizedString(@"message.location", @"Location"); } break; case eMessageBodyType_Voice: { messageStr = NSLocalizedString(@"message.voice", @"Voice"); } break; case eMessageBodyType_Video:{ messageStr = NSLocalizedString(@"message.video", @"Video"); } break; default: break; } NSString *title = [[UserProfileManager sharedInstance] getNickNameWithUsername:message.from]; if (message.messageType == eMessageTypeGroupChat) { NSArray *groupArray = [[EaseMob sharedInstance].chatManager groupList]; for (EMGroup *group in groupArray) { if ([group.groupId isEqualToString:message.conversationChatter]) { title = [NSString stringWithFormat:@"%@(%@)", message.groupSenderName, group.groupSubject]; break; } } } else if (message.messageType == eMessageTypeChatRoom) { NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; NSString *key = [NSString stringWithFormat:@"OnceJoinedChatrooms_%@", [[[EaseMob sharedInstance].chatManager loginInfo] objectForKey:@"username" ]]; NSMutableDictionary *chatrooms = [NSMutableDictionary dictionaryWithDictionary:[ud objectForKey:key]]; NSString *chatroomName = [chatrooms objectForKey:message.conversationChatter]; if (chatroomName) { title = [NSString stringWithFormat:@"%@(%@)", message.groupSenderName, chatroomName]; } } notification.alertBody = [NSString stringWithFormat:@"%@:%@", title, messageStr]; } else{ notification.alertBody = NSLocalizedString(@"receiveMessage", @"you have a new message"); } #warning 去掉註釋會顯示[本地]開頭, 方便在開發中區分是否爲本地推送 //notification.alertBody = [[NSString alloc] initWithFormat:@"[本地]%@", notification.alertBody]; notification.alertAction = NSLocalizedString(@"open", @"Open"); notification.timeZone = [NSTimeZone defaultTimeZone]; NSTimeInterval timeInterval = [[NSDate date] timeIntervalSinceDate:self.lastPlaySoundDate]; if (timeInterval < kDefaultPlaySoundInterval) { NSLog(@"skip ringing & vibration %@, %@", [NSDate date], self.lastPlaySoundDate); } else { notification.soundName = UILocalNotificationDefaultSoundName; self.lastPlaySoundDate = [NSDate date]; } NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; [userInfo setObject:[NSNumber numberWithInt:message.messageType] forKey:kMessageType]; [userInfo setObject:message.conversationChatter forKey:kConversationChatter]; notification.userInfo = userInfo; //發送通知 [[UIApplication sharedApplication] scheduleLocalNotification:notification]; // UIApplication *application = [UIApplication sharedApplication]; // application.applicationIconBadgeNumber += 1; }
在-(void)didReceiveMessage:(EMMessage *)message方法中對這個方法進行調用就能夠了。