零.环信小结,以备后用
一. Cocoapods 集成
不包含实时语音版本 SDK(HyphenateLite),引用时 #import <HyphenateLite/HyphenateLite.h>
pod 'HyphenateLite'
包含实时语音版本 SDK(Hyphenate),引用时 #import <Hyphenate/Hyphenate.h>
pod 'Hyphenate'
二.依赖库相关
忘了,第一步集成完成后编译下,编译如果成功的话,那就忽略这一步,如果编译失败,去环信官网瞅瞅吧!
三.初始化
1.在全局文件中导入相关文件,或者是需要使用的文件中导入
//Lite版本
#import <HyphenateLite/HyphenateLite.h>
//Full版本
#import <Hyphenate/Hyphenate.h>
2.在 AppDelegate 中调用SDK方法
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// 环信
EMOptions *options = [EMOptions optionsWithAppkey:@"1155170XXXXXXX37#xiubei"];
options.apnsCertName = @"xXXXXei_push";
[[EMClient sharedClient] initializeSDKWithOptions:options];
[[EaseSDKHelper shareHelper] hyphenateApplication:application
didFinishLaunchingWithOptions:launchOptions
appkey:@"115517092XXXX37#xiubei"
apnsCertName:@"xXXXXei_push"
otherConfig:@{kSDKConfigEnableConsoleLogger:[NSNumber numberWithBool:YES]}];
}
// APP进入后台
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[[EMClient sharedClient] applicationDidEnterBackground:application];
}
// APP将要从后台返回
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[[EMClient sharedClient] applicationWillEnterForeground:application];
}
四.登陆且注册环信相关方法
EMError *error1 = [[EMClient sharedClient] loginWithUsername:_loginView.phoneTF.text password:_loginView.pwdTF.text];
if (!error1) {
NSLog(@"登录成功");
[[EMClient sharedClient].options setIsAutoLogin:YES];
}else{
NSLog(@"登录失败 : error = %@",error1.errorDescription);
EMError *error = [[EMClient sharedClient] registerWithUsername:_loginView.phoneTF.text password:pwd];
if (error == nil) {
NSLog(@"注册成功");
}else{
NSLog(@"注册失败 : error = %@",error.errorDescription);
}
}
** 五.导入EaseUI**
下载官方demo,导入整个EaseUI目录,[ 环信下载地址 ](http://www.easemob.com/download/im)
615D47FCF21652DD5C8E64843F754B80.jpg
六.导入 ChatDemoHelper 类
七.新建 MSUMessageController 和 MSUMessageChatController两个类,分别继承于 EaseConversationListViewController 和 EaseMessageViewController,相关代码拷贝放入其中
1. MSUMessageController.h 内容
#import <UIKit/UIKit.h>
@interface MSUMessageController : EaseConversationListViewController
@property (strong, nonatomic) NSMutableArray *conversationsArray;
- (void)refresh;
- (void)refreshDataSource;
- (void)isConnect:(BOOL)isConnect;
- (void)networkChanged:(EMConnectionState)connectionState;
@end
2. MSUMessageController.m 内容 (其他具体内容视情况而定)
/// 环信
#import "MSUMessageChatController.h"
#import "UserProfileManager.h"
@interface MSUMessageController ()<EaseConversationListViewControllerDelegate,EaseConversationListViewControllerDataSource>
@end
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// 环信
sender.userInteractionEnabled = YES;
_messageView.scrollView.contentOffset = CGPointMake(WIDTH*3, 0);
// self.chatView.hidden = NO;
self.tableView.frame = CGRectMake(WIDTH*3, 10, WIDTH, HEIGHT-60-37-50);
self.tableView.backgroundColor = HEXCOLOR(0xf2f2f2);
[self.messageView.scrollView addSubview:self.tableView];
self.tableView.hidden = NO;
self.showRefreshHeader = YES;
[self tableViewDidTriggerHeaderRefresh];
self.delegate = self;
self.dataSource = self;
[self networkStateView];
// [self removeEmptyConversationsFromDB];
}
#pragma mark - 环信相关
//- (void)removeEmptyConversationsFromDB
//{
// NSArray *conversations = [[EMClient sharedClient].chatManager getAllConversations];
// for (EMConversation *conver in conversations) {
// NSLog(@"--%@",conver.conversationId);
// }
// NSMutableArray *needRemoveConversations;
// for (EMConversation *conversation in conversations) {
// if (!conversation.latestMessage || (conversation.type == EMConversationTypeChatRoom)) {
// if (!needRemoveConversations) {
// needRemoveConversations = [[NSMutableArray alloc] initWithCapacity:0];
// }
//
// [needRemoveConversations addObject:conversation];
// } else{
//
// }
// }
//
// if (needRemoveConversations && needRemoveConversations.count > 0) {
// [[EMClient sharedClient].chatManager deleteConversations:needRemoveConversations isDeleteMessages:YES completion:nil];
// }
//}
- (UIView *)networkStateView
{
if (_networkStateView == nil) {
_networkStateView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 44)];
_networkStateView.backgroundColor = [UIColor colorWithRed:255 / 255.0 green:199 / 255.0 blue:199 / 255.0 alpha:0.5];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, (_networkStateView.frame.size.height - 20) / 2, 20, 20)];
imageView.image = [UIImage imageNamed:@"messageSendFail"];
[_networkStateView addSubview:imageView];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(imageView.frame) + 5, 0, _networkStateView.frame.size.width - (CGRectGetMaxX(imageView.frame) + 15), _networkStateView.frame.size.height)];
label.font = [UIFont systemFontOfSize:15.0];
label.textColor = [UIColor grayColor];
label.backgroundColor = [UIColor clearColor];
label.text = NSLocalizedString(@"network.disconnection", @"Network disconnection");
[_networkStateView addSubview:label];
}
return _networkStateView;
}
#pragma mark - EaseConversationListViewControllerDelegate
- (void)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
didSelectConversationModel:(id<IConversationModel>)conversationModel
{
if (conversationModel) {
EMConversation *conversation = conversationModel.conversation;
if (conversation) {
// UIViewController *chatController = nil;
self.hidesBottomBarWhenPushed = YES;
MSUMessageChatController *chatController = [[MSUMessageChatController alloc] initWithConversationChatter:conversation.conversationId conversationType:conversation.type];
chatController.titStr = conversationModel.title;
chatController.sellerIconUrl = conversationModel.avatarURLPath;
chatController.sellerNickName = conversationModel.title;
[self.navigationController pushViewController:chatController animated:YES];
self.hidesBottomBarWhenPushed = NO;
}
[[NSNotificationCenter defaultCenter] postNotificationName:@"setupUnreadMessageCount" object:nil];
[self.tableView reloadData];
}
}
#pragma mark - EaseConversationListViewControllerDataSource
- (id<IConversationModel>)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
modelForConversation:(EMConversation *)conversation
{
NSLog(@"------ %@",conversation);
EaseConversationModel *model = [[EaseConversationModel alloc] initWithConversation:conversation];
NSLog(@"------1 %@",model);
if (model.conversation.type == EMConversationTypeChat) {
UserProfileEntity *profileEntity = [[UserProfileManager sharedInstance] getUserProfileByUsername:conversation.conversationId];
if (profileEntity) {
model.title = profileEntity.nickname == nil ? profileEntity.username : profileEntity.nickname;
model.avatarURLPath = profileEntity.imageUrl;
}
}
return model;
}
- (NSAttributedString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
latestMessageTitleForConversationModel:(id<IConversationModel>)conversationModel
{
NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:@""];
EMMessage *lastMessage = [conversationModel.conversation latestMessage];
if (lastMessage) {
NSString *latestMessageTitle = @"";
EMMessageBody *messageBody = lastMessage.body;
switch (messageBody.type) {
case EMMessageBodyTypeImage:{
latestMessageTitle = NSLocalizedString(@"message.image1", @"[image]");
} break;
case EMMessageBodyTypeText:{
// 表情映射。
NSString *didReceiveText = [EaseConvertToCommonEmoticonsHelper
convertToSystemEmoticons:((EMTextMessageBody *)messageBody).text];
latestMessageTitle = didReceiveText;
if ([lastMessage.ext objectForKey:MESSAGE_ATTR_IS_BIG_EXPRESSION]) {
latestMessageTitle = @"[动画表情]";
}
} break;
case EMMessageBodyTypeVoice:{
latestMessageTitle = NSLocalizedString(@"message.voice1", @"[voice]");
} break;
case EMMessageBodyTypeLocation: {
latestMessageTitle = NSLocalizedString(@"message.location1", @"[location]");
} break;
case EMMessageBodyTypeVideo: {
latestMessageTitle = NSLocalizedString(@"message.video1", @"[video]");
} break;
case EMMessageBodyTypeFile: {
latestMessageTitle = NSLocalizedString(@"message.file1", @"[file]");
} break;
default: {
} break;
}
if (lastMessage.direction == EMMessageDirectionReceive) {
NSString *from = lastMessage.from;
if (conversationModel) {
from = conversationModel.title;
}
latestMessageTitle = [NSString stringWithFormat:@"%@: %@", from, latestMessageTitle];
}
NSDictionary *ext = conversationModel.conversation.ext;
if (ext && [ext[kHaveUnreadAtMessage] intValue] == kAtAllMessage) {
latestMessageTitle = [NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"group.atAll", nil), latestMessageTitle];
attributedStr = [[NSMutableAttributedString alloc] initWithString:latestMessageTitle];
[attributedStr setAttributes:@{NSForegroundColorAttributeName : [UIColor colorWithRed:1.0 green:.0 blue:.0 alpha:0.5]} range:NSMakeRange(0, NSLocalizedString(@"group.atAll", nil).length)];
}
else if (ext && [ext[kHaveUnreadAtMessage] intValue] == kAtYouMessage) {
latestMessageTitle = [NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"group.atMe", @"[Somebody @ me]"), latestMessageTitle];
attributedStr = [[NSMutableAttributedString alloc] initWithString:latestMessageTitle];
[attributedStr setAttributes:@{NSForegroundColorAttributeName : [UIColor colorWithRed:1.0 green:.0 blue:.0 alpha:0.5]} range:NSMakeRange(0, NSLocalizedString(@"group.atMe", @"[Somebody @ me]").length)];
}
else {
attributedStr = [[NSMutableAttributedString alloc] initWithString:latestMessageTitle];
}
}
return attributedStr;
}
- (NSString *)conversationListViewController:(EaseConversationListViewController *)conversationListViewController
latestMessageTimeForConversationModel:(id<IConversationModel>)conversationModel
{
NSString *latestMessageTime = @"";
EMMessage *lastMessage = [conversationModel.conversation latestMessage];;
if (lastMessage) {
latestMessageTime = [NSDate formattedTimeFromTimeInterval:lastMessage.timestamp];
}
return latestMessageTime;
}
#pragma mark - public
-(void)refresh
{
[self refreshAndSortView];
}
-(void)refreshDataSource
{
[self tableViewDidTriggerHeaderRefresh];
}
- (void)isConnect:(BOOL)isConnect{
if (!isConnect) {
self.tableView.tableHeaderView = _networkStateView;
}
else{
self.tableView.tableHeaderView = nil;
}
}
- (void)networkChanged:(EMConnectionState)connectionState
{
if (connectionState == EMConnectionDisconnected) {
self.tableView.tableHeaderView = _networkStateView;
}
else{
self.tableView.tableHeaderView = nil;
}
}
3. MSUMessageChatController.h 中的内容
#import "EaseMessageViewController.h"
@interface MSUMessageChatController : EaseMessageViewController<EaseMessageViewControllerDelegate, EaseMessageViewControllerDataSource>
/// 返回箭头按钮
@property (nonatomic , strong) UIButton *arrowBtn;
/// 相册按钮
@property (nonatomic , strong) UIButton *photoBtn;
/// 对方昵称
@property (nonatomic , copy) NSString *sellerNickName;
/// 对方用户id
@property (nonatomic , copy) NSString *userId;
/// 对方头像
@property (nonatomic , copy) NSString *sellerIconUrl;
/// 发送方头像
@property (nonatomic , copy) NSString *myselfIcon;
/// 发送方昵称
@property (nonatomic , copy) NSString *myselfNickName;
@property (nonatomic , copy) NSString *titStr;
- (void)showMenuViewController:(UIView *)showInView
andIndexPath:(NSIndexPath *)indexPath
messageType:(EMMessageBodyType)messageType;
@end
4. MSUMessageChatController.m 中的内容
#import "MSUMessageChatController.h"
#import "MSUPersonInfoController.h" // 可删除
#import "ChatDemoHelper.h"
#import "UserProfileManager.h"
#import "MSUHomeNavView.h"// 可删除
#import "MSUPrefixHeader.pch"// 可删除
#import "MSUPathTools.h"// 可删除
#define KNOTIFICATION_LOGINCHANGE @"loginStateChange"
#define KNOTIFICATIONNAME_DELETEALLMESSAGE @"RemoveAllMessages"
@interface MSUMessageChatController ()<UIAlertViewDelegate,EMClientDelegate>//, EMChooseViewDelegate
{
UIMenuItem *_copyMenuItem;
UIMenuItem *_deleteMenuItem;
UIMenuItem *_transpondMenuItem;
UIMenuItem *_recallItem;
}
@property (nonatomic) BOOL isPlayingAudio;
@property (nonatomic) NSMutableDictionary *emotionDic;
@property (nonatomic, copy) EaseSelectAtTargetCallback selectedCallback;
@end
@implementation MSUMessageChatController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = BlackColor;
// UIView *bgView = [[UIView alloc] init];
// bgView.frame = CGRectMake(0, 60, WIDTH, HEIGHT-60);
// bgView.backgroundColor = HEXCOLOR(0xffffff);
// [self.view addSubview:bgView];
self.showRefreshHeader = YES;
self.delegate = self;
self.dataSource = self;
[self _setupBarButtonItem];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deleteAllMessages:) name:KNOTIFICATIONNAME_DELETEALLMESSAGE object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exitChat) name:@"ExitChat" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(insertCallMessage:) name:@"insertCallMessage" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleCallNotification:) name:@"callOutWithChatter" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleCallNotification:) name:@"callControllerClose" object:nil];
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(KeyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
}
//- (void)KeyboardWillChangeFrame:(NSNotification *)note{
// [UIView animateWithDuration:0.25 animations:^{
// self.tableView.frame = CGRectMake(0, 60, WIDTH, HEIGHT-60);
// }];
//}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
if (self.conversation.type == EMConversationTypeChatRoom) {
//退出聊天室,删除会话
if (self.isJoinedChatroom) {
NSString *chatter = [self.conversation.conversationId copy];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
EMError *error = nil;
[[EMClient sharedClient].roomManager leaveChatroom:chatter error:&error];
if (error !=nil) {
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:[NSString stringWithFormat:@"Leave chatroom '%@' failed [%@]", chatter, error.errorDescription] delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
[alertView show];
});
}
});
}
else {
[[EMClient sharedClient].chatManager deleteConversation:self.conversation.conversationId isDeleteMessages:YES completion:nil];
}
}
[[EMClient sharedClient] removeDelegate:self];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (self.conversation.type == EMConversationTypeGroupChat) {
NSDictionary *ext = self.conversation.ext;
if ([[ext objectForKey:@"subject"] length])
{
self.title = [ext objectForKey:@"subject"];
}
if (ext && ext[kHaveUnreadAtMessage] != nil)
{
NSMutableDictionary *newExt = [ext mutableCopy];
[newExt removeObjectForKey:kHaveUnreadAtMessage];
self.conversation.ext = newExt;
}
}
}
- (void)tableViewDidTriggerHeaderRefresh {
if ([[ChatDemoHelper shareHelper] isFetchHistoryChange]) {
NSString *startMessageId = nil;
if ([self.messsagesSource count] > 0) {
startMessageId = [(EMMessage *)self.messsagesSource.firstObject messageId];
}
NSLog(@"startMessageID ------- %@",startMessageId);
[EMClient.sharedClient.chatManager asyncFetchHistoryMessagesFromServer:self.conversation.conversationId
conversationType:self.conversation.type
startMessageId:startMessageId
pageSize:10
complation:^(EMCursorResult *aResult, EMError *aError)
{
[super tableViewDidTriggerHeaderRefresh];
}];
} else {
[super tableViewDidTriggerHeaderRefresh];
}
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
// [self.view endEditing:YES];
}
- (void)_setupBarButtonItem{
// 左箭头
self.arrowBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[_arrowBtn setImage:[MSUPathTools showImageWithContentOfFileByName:@"back"] forState:UIControlStateNormal];
// _arrowBtn.backgroundColor = [UIColor blueColor];
[self.view addSubview:_arrowBtn];
[_arrowBtn makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view.top).offset(27);
make.left.equalTo(self.view.left).offset(15);
make.width.equalTo(20);
make.height.equalTo(30);
}];
[self.arrowBtn addTarget:self action:@selector(arrowBtnClick:) forControlEvents:UIControlEventTouchUpInside];
if (self.sellerNickName.length > 0) {
self.titStr = self.sellerNickName;
}
// 扫描二维码
UILabel *scanLab = [[UILabel alloc] init];
scanLab.text = self.titStr;
scanLab.font = [UIFont systemFontOfSize:20];
scanLab.textAlignment = NSTextAlignmentCenter;
[scanLab setTextColor:WHITECOLOR];
[self.view addSubview:scanLab];
[scanLab makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view.top).offset(25);
make.left.equalTo(self.view.left).offset(WIDTH * 0.5 - 100);
make.width.equalTo(200);
make.height.equalTo(34);
}];
// 相册
self.photoBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[_photoBtn setImage:[MSUPathTools showImageWithContentOfFileByName:@"delete"] forState:UIControlStateNormal];
[self.view addSubview:_photoBtn];
[_photoBtn makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view.top).offset(27);
make.right.equalTo(self.view.right).offset(-15);
make.width.equalTo(40);
make.height.equalTo(30);
}];
[self.photoBtn addTarget:self action:@selector(deleteBtnClick:) forControlEvents:UIControlEventTouchUpInside];
self.tableView.frame = CGRectMake(0, 60, WIDTH, HEIGHT-60-49);
}
#pragma mark - UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView.cancelButtonIndex != buttonIndex) {
self.messageTimeIntervalTag = -1;
[self.conversation deleteAllMessages:nil];
[self.dataArray removeAllObjects];
[self.messsagesSource removeAllObjects];
[self.tableView reloadData];
}
}
#pragma mark - EaseMessageViewControllerDelegate
- (UITableViewCell *)messageViewController:(UITableView *)tableView
cellForMessageModel:(id<IMessageModel>)messageModel
{
NSDictionary *ext = messageModel.message.ext;
if ([ext objectForKey:@"em_recall"]) {
NSString *TimeCellIdentifier = [EaseMessageTimeCell cellIdentifier];
EaseMessageTimeCell *recallCell = (EaseMessageTimeCell *)[tableView dequeueReusableCellWithIdentifier:TimeCellIdentifier];
if (recallCell == nil) {
recallCell = [[EaseMessageTimeCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TimeCellIdentifier];
recallCell.selectionStyle = UITableViewCellSelectionStyleNone;
}
EMTextMessageBody *body = (EMTextMessageBody*)messageModel.message.body;
recallCell.title = body.text;
return recallCell;
}
return nil;
}
- (CGFloat)messageViewController:(EaseMessageViewController *)viewController
heightForMessageModel:(id<IMessageModel>)messageModel
withCellWidth:(CGFloat)cellWidth
{
NSDictionary *ext = messageModel.message.ext;
if ([ext objectForKey:@"em_recall"]) {
return self.timeCellHeight;
}
return 0;
}
- (BOOL)messageViewController:(EaseMessageViewController *)viewController
canLongPressRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (BOOL)messageViewController:(EaseMessageViewController *)viewController
didLongPressRowAtIndexPath:(NSIndexPath *)indexPath
{
id object = [self.dataArray objectAtIndex:indexPath.row];
if (![object isKindOfClass:[NSString class]]) {
EaseMessageCell *cell = (EaseMessageCell *)[self.tableView cellForRowAtIndexPath:indexPath];
if ([cell isKindOfClass:[EaseMessageCell class]]) {
[cell becomeFirstResponder];
self.menuIndexPath = indexPath;
[self showMenuViewController:cell.bubbleView andIndexPath:indexPath messageType:cell.model.bodyType];
}
}
return YES;
}
- (void)messageViewController:(EaseMessageViewController *)viewController
didSelectAvatarMessageModel:(id<IMessageModel>)messageModel
{
// self.hidesBottomBarWhenPushed = YES;
// MSUPersonInfoController *userprofile = [[MSUPersonInfoController alloc] init];
// userprofile.userID = self.userId;
// [self.navigationController pushViewController:userprofile animated:YES];
}
- (void)messageViewController:(EaseMessageViewController *)viewController
selectAtTarget:(EaseSelectAtTargetCallback)selectedCallback
{
_selectedCallback = selectedCallback;
EMGroup *chatGroup = nil;
NSArray *groupArray = [[EMClient sharedClient].groupManager getJoinedGroups];
for (EMGroup *group in groupArray) {
if ([group.groupId isEqualToString:self.conversation.conversationId]) {
chatGroup = group;
break;
}
}
if (chatGroup == nil) {
chatGroup = [EMGroup groupWithId:self.conversation.conversationId];
}
if (chatGroup) {
if (!chatGroup.occupants) {
__weak MSUMessageChatController* weakSelf = self;
[self showHudInView:self.view hint:@"Fetching group members..."];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
EMError *error = nil;
EMGroup *group = [[EMClient sharedClient].groupManager getGroupSpecificationFromServerWithId:chatGroup.groupId error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
__strong MSUMessageChatController *strongSelf = weakSelf;
if (strongSelf) {
[strongSelf hideHud];
if (error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:[NSString stringWithFormat:@"Fetching group members failed [%@]", error.errorDescription] delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
[alertView show];
}
else {
NSMutableArray *members = [group.occupants mutableCopy];
NSString *loginUser = [EMClient sharedClient].currentUsername;
if (loginUser) {
[members removeObject:loginUser];
}
if (![members count]) {
if (strongSelf.selectedCallback) {
strongSelf.selectedCallback(nil);
}
return;
}
// ContactSelectionViewController *selectController = [[ContactSelectionViewController alloc] initWithContacts:members];
// selectController.mulChoice = NO;
// selectController.delegate = self;
// [self.navigationController pushViewController:selectController animated:YES];
}
}
});
});
}
else {
NSMutableArray *members = [chatGroup.occupants mutableCopy];
NSString *loginUser = [EMClient sharedClient].currentUsername;
if (loginUser) {
[members removeObject:loginUser];
}
if (![members count]) {
if (_selectedCallback) {
_selectedCallback(nil);
}
return;
}
// ContactSelectionViewController *selectController = [[ContactSelectionViewController alloc] initWithContacts:members];
// selectController.mulChoice = NO;
// selectController.delegate = self;
// [self.navigationController pushViewController:selectController animated:YES];
}
}
}
#pragma mark - EaseMessageViewControllerDataSource
- (id<IMessageModel>)messageViewController:(EaseMessageViewController *)viewController
modelForMessage:(EMMessage *)message
{
id<IMessageModel> model = nil;
model = [[EaseMessageModel alloc] initWithMessage:message];
if (model.isSender) {
model.nickname = @"我";
if (self.myselfIcon.length > 0) {
model.avatarImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://psource.showbuy100.com%@",self.myselfIcon]]]];
} else{
model.avatarImage = [UIImage imageNamed:@"search-headbig"];
}
} else{
if (self.sellerIconUrl.length > 0) {
model.avatarImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://psource.showbuy100.com%@",self.sellerIconUrl]]]];
} else{
model.avatarImage = [UIImage imageNamed:@"search-headbig"];
}
model.nickname = self.sellerNickName.length > 0 ? self.sellerNickName : @"对方";
// UserProfileEntity *profileEntity = [[UserProfileManager sharedInstance] getUserProfileByUsername:model.nickname];
// if (profileEntity) {
// model.avatarURLPath = [NSString stringWithFormat:@"http://psource.showbuy100.com%@",self.sellerIconUrl];
// model.nickname = self.sellerNickName;
// }
}
model.failImageName = @"imageDownloadFail";
return model;
}
- (NSArray*)emotionFormessageViewController:(EaseMessageViewController *)viewController
{
NSMutableArray *emotions = [NSMutableArray array];
for (NSString *name in [EaseEmoji allEmoji]) {
EaseEmotion *emotion = [[EaseEmotion alloc] initWithName:@"" emotionId:name emotionThumbnail:name emotionOriginal:name emotionOriginalURL:@"" emotionType:EMEmotionDefault];
[emotions addObject:emotion];
}
EaseEmotion *temp = [emotions objectAtIndex:0];
EaseEmotionManager *managerDefault = [[EaseEmotionManager alloc] initWithType:EMEmotionDefault emotionRow:3 emotionCol:7 emotions:emotions tagImage:[UIImage imageNamed:temp.emotionId]];
NSMutableArray *emotionGifs = [NSMutableArray array];
_emotionDic = [NSMutableDictionary dictionary];
NSArray *names = @[@"icon_002",@"icon_007",@"icon_010",@"icon_012",@"icon_013",@"icon_018",@"icon_019",@"icon_020",@"icon_021",@"icon_022",@"icon_024",@"icon_027",@"icon_029",@"icon_030",@"icon_035",@"icon_040"];
int index = 0;
for (NSString *name in names) {
index++;
EaseEmotion *emotion = [[EaseEmotion alloc] initWithName:[NSString stringWithFormat:@"[示例%d]",index] emotionId:[NSString stringWithFormat:@"em%d",(1000 + index)] emotionThumbnail:[NSString stringWithFormat:@"%@_cover",name] emotionOriginal:[NSString stringWithFormat:@"%@",name] emotionOriginalURL:@"" emotionType:EMEmotionGif];
[emotionGifs addObject:emotion];
[_emotionDic setObject:emotion forKey:[NSString stringWithFormat:@"em%d",(1000 + index)]];
}
EaseEmotionManager *managerGif= [[EaseEmotionManager alloc] initWithType:EMEmotionGif emotionRow:2 emotionCol:4 emotions:emotionGifs tagImage:[UIImage imageNamed:@"icon_002_cover"]];
return @[managerDefault,managerGif];
}
- (BOOL)isEmotionMessageFormessageViewController:(EaseMessageViewController *)viewController
messageModel:(id<IMessageModel>)messageModel
{
BOOL flag = NO;
if ([messageModel.message.ext objectForKey:MESSAGE_ATTR_IS_BIG_EXPRESSION]) {
return YES;
}
return flag;
}
- (EaseEmotion*)emotionURLFormessageViewController:(EaseMessageViewController *)viewController
messageModel:(id<IMessageModel>)messageModel
{
NSString *emotionId = [messageModel.message.ext objectForKey:MESSAGE_ATTR_EXPRESSION_ID];
EaseEmotion *emotion = [_emotionDic objectForKey:emotionId];
if (emotion == nil) {
emotion = [[EaseEmotion alloc] initWithName:@"" emotionId:emotionId emotionThumbnail:@"" emotionOriginal:@"" emotionOriginalURL:@"" emotionType:EMEmotionGif];
}
return emotion;
}
- (NSDictionary*)emotionExtFormessageViewController:(EaseMessageViewController *)viewController
easeEmotion:(EaseEmotion*)easeEmotion
{
return @{MESSAGE_ATTR_EXPRESSION_ID:easeEmotion.emotionId,MESSAGE_ATTR_IS_BIG_EXPRESSION:@(YES)};
}
- (void)messageViewControllerMarkAllMessagesAsRead:(EaseMessageViewController *)viewController
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"setupUnreadMessageCount" object:nil];
}
#pragma mark - EaseMob
#pragma mark - EMClientDelegate
- (void)userAccountDidLoginFromOtherDevice
{
if ([self.imagePicker.mediaTypes count] > 0 && [[self.imagePicker.mediaTypes objectAtIndex:0] isEqualToString:(NSString *)kUTTypeMovie]) {
[self.imagePicker stopVideoCapture];
}
}
- (void)userAccountDidRemoveFromServer
{
if ([self.imagePicker.mediaTypes count] > 0 && [[self.imagePicker.mediaTypes objectAtIndex:0] isEqualToString:(NSString *)kUTTypeMovie]) {
[self.imagePicker stopVideoCapture];
}
}
- (void)userDidForbidByServer
{
if ([self.imagePicker.mediaTypes count] > 0 && [[self.imagePicker.mediaTypes objectAtIndex:0] isEqualToString:(NSString *)kUTTypeMovie]) {
[self.imagePicker stopVideoCapture];
}
}
#pragma mark - EMChatManagerDelegate
- (void)messagesDidRecall:(NSArray *)aMessages
{
for (EMMessage *msg in aMessages) {
if (![self.conversation.conversationId isEqualToString:msg.conversationId]){
continue;
}
NSString *text;
if ([msg.from isEqualToString:[EMClient sharedClient].currentUsername]) {
text = [NSString stringWithFormat:NSLocalizedString(@"message.recall", @"You recall a message")];
} else {
text = [NSString stringWithFormat:NSLocalizedString(@"message.recallByOthers", @"%@ recall a message"),msg.from];
}
[self _recallWithMessage:msg text:text isSave:NO];
}
}
- (void)arrowBtnClick:(UIButton *)sender{
[[EMClient sharedClient].chatManager removeDelegate:self];
[[EMClient sharedClient].roomManager removeDelegate:self];
[[ChatDemoHelper shareHelper] setChatVC:nil];
if (self.deleteConversationIfNull) {
//判断当前会话是否为空,若符合则删除该会话
EMMessage *message = [self.conversation latestMessage];
if (message == nil) {
[[EMClient sharedClient].chatManager deleteConversation:self.conversation.conversationId isDeleteMessages:NO completion:nil];
}
}
[self.navigationController popViewControllerAnimated:YES];
}
- (void)deleteBtnClick:(UIButton *)sender{
if (self.dataArray.count == 0) {
// [self showHint:NSLocalizedString(@"message.noMessage", @"no messages")];
[self showHint:@"暂无任何消息"];
return;
}
if ([sender isKindOfClass:[NSNotification class]]) {
NSString *groupId = (NSString *)[(NSNotification *)sender object];
BOOL isDelete = [groupId isEqualToString:self.conversation.conversationId];
if (self.conversation.type != EMConversationTypeChat && isDelete) {
self.messageTimeIntervalTag = -1;
[self.conversation deleteAllMessages:nil];
[self.messsagesSource removeAllObjects];
[self.dataArray removeAllObjects];
[self.tableView reloadData];
[self showHint:NSLocalizedString(@"message.noMessage", @"no messages")];
}
}
else if ([sender isKindOfClass:[UIButton class]]){
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"prompt", @"Prompt") message:NSLocalizedString(@"sureToDelete", @"please make sure to delete") delegate:self cancelButtonTitle:NSLocalizedString(@"cancel", @"Cancel") otherButtonTitles:NSLocalizedString(@"sure", @"确定"), nil];
[alertView show];
}
}
- (void)recallMenuAction:(id)sender
{
if (self.menuIndexPath && self.menuIndexPath.row > 0) {
__weak typeof(self) weakSelf = self;
id<IMessageModel> model = [self.dataArray objectAtIndex:self.menuIndexPath.row];
[[EMClient sharedClient].chatManager recallMessage:model.message
completion:^(EMMessage *aMessage, EMError *aError) {
if (!aError) {
[weakSelf _recallWithMessage:aMessage text:NSLocalizedString(@"message.recall", @"You recall a message") isSave:YES];
} else {
[weakSelf showHint:[NSString stringWithFormat:NSLocalizedString(@"recallFailed", @"Recall failed:%@"), aError.errorDescription]];
}
weakSelf.menuIndexPath = nil;
}];
}
}
//- (void)transpondMenuAction:(id)sender
//{
// if (self.menuIndexPath && self.menuIndexPath.row > 0) {
// id<IMessageModel> model = [self.dataArray objectAtIndex:self.menuIndexPath.row];
//// ContactListSelectViewController *listViewController = [[ContactListSelectViewController alloc] initWithNibName:nil bundle:nil];
//// listViewController.messageModel = model;
//// [listViewController tableViewDidTriggerHeaderRefresh];
//// [self.navigationController pushViewController:listViewController animated:YES];
// }
// self.menuIndexPath = nil;
//}
- (void)copyMenuAction:(id)sender
{
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
if (self.menuIndexPath && self.menuIndexPath.row > 0) {
id<IMessageModel> model = [self.dataArray objectAtIndex:self.menuIndexPath.row];
pasteboard.string = model.text;
}
self.menuIndexPath = nil;
}
- (void)deleteMenuAction:(id)sender
{
if (self.menuIndexPath && self.menuIndexPath.row > 0) {
id<IMessageModel> model = [self.dataArray objectAtIndex:self.menuIndexPath.row];
NSMutableIndexSet *indexs = [NSMutableIndexSet indexSetWithIndex:self.menuIndexPath.row];
NSMutableArray *indexPaths = [NSMutableArray arrayWithObjects:self.menuIndexPath, nil];
[self.conversation deleteMessageWithId:model.message.messageId error:nil];
[self.messsagesSource removeObject:model.message];
if (self.menuIndexPath.row - 1 >= 0) {
id nextMessage = nil;
id prevMessage = [self.dataArray objectAtIndex:(self.menuIndexPath.row - 1)];
if (self.menuIndexPath.row + 1 < [self.dataArray count]) {
nextMessage = [self.dataArray objectAtIndex:(self.menuIndexPath.row + 1)];
}
if ((!nextMessage || [nextMessage isKindOfClass:[NSString class]]) && [prevMessage isKindOfClass:[NSString class]]) {
[indexs addIndex:self.menuIndexPath.row - 1];
[indexPaths addObject:[NSIndexPath indexPathForRow:(self.menuIndexPath.row - 1) inSection:0]];
}
}
[self.dataArray removeObjectsAtIndexes:indexs];
[self.tableView beginUpdates];
[self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
if ([self.dataArray count] == 0) {
self.messageTimeIntervalTag = -1;
}
}
self.menuIndexPath = nil;
}
#pragma mark - notification
- (void)exitChat
{
[self.navigationController popToViewController:self animated:NO];
[self.navigationController popViewControllerAnimated:YES];
}
- (void)insertCallMessage:(NSNotification *)notification
{
id object = notification.object;
if (object) {
EMMessage *message = (EMMessage *)object;
[self addMessageToDataSource:message progress:nil];
[[EMClient sharedClient].chatManager importMessages:@[message] completion:nil];
}
}
- (void)handleCallNotification:(NSNotification *)notification
{
id object = notification.object;
if ([object isKindOfClass:[NSDictionary class]]) {
//开始call
self.isViewDidAppear = NO;
} else {
//结束call
self.isViewDidAppear = YES;
}
}
#pragma mark - private
- (void)showMenuViewController:(UIView *)showInView
andIndexPath:(NSIndexPath *)indexPath
messageType:(EMMessageBodyType)messageType
{
if (self.menuController == nil) {
self.menuController = [UIMenuController sharedMenuController];
}
if (_deleteMenuItem == nil) {
_deleteMenuItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"delete", @"Delete") action:@selector(deleteMenuAction:)];
}
if (_copyMenuItem == nil) {
_copyMenuItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"copy", @"Copy") action:@selector(copyMenuAction:)];
}
// if (_transpondMenuItem == nil) {
// _transpondMenuItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"transpond", @"Transpond") action:@selector(transpondMenuAction:)];
// }
if (_recallItem == nil) {
_recallItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"recall", @"Recall") action:@selector(recallMenuAction:)];
}
NSMutableArray *items = [NSMutableArray array];
if (messageType == EMMessageBodyTypeText) {
[items addObject:_copyMenuItem];
// [items addObject:_transpondMenuItem];
[items addObject:_deleteMenuItem];
} else if (messageType == EMMessageBodyTypeImage || messageType == EMMessageBodyTypeVideo) {
// [items addObject:_transpondMenuItem];
[items addObject:_deleteMenuItem];
} else {
[items addObject:_deleteMenuItem];
}
id<IMessageModel> model = [self.dataArray objectAtIndex:self.menuIndexPath.row];
if (model.isSender) {
[items addObject:_recallItem];
}
[self.menuController setMenuItems:items];
[self.menuController setTargetRect:showInView.frame inView:showInView.superview];
[self.menuController setMenuVisible:YES animated:YES];
}
- (void)_recallWithMessage:(EMMessage *)msg text:(NSString *)text isSave:(BOOL)isSave
{
EMMessage *message = [EaseSDKHelper sendTextMessage:text to:msg.conversationId messageType:msg.chatType messageExt:@{@"em_recall":@(YES)}];
message.isRead = YES;
[message setTimestamp:msg.timestamp];
[message setLocalTime:msg.localTime];
id<IMessageModel> newModel = [[EaseMessageModel alloc] initWithMessage:message];
__block NSUInteger index = NSNotFound;
[self.dataArray enumerateObjectsUsingBlock:^(EaseMessageModel *model, NSUInteger idx, BOOL *stop){
if ([model conformsToProtocol:@protocol(IMessageModel)]) {
if ([msg.messageId isEqualToString:model.message.messageId])
{
index = idx;
*stop = YES;
}
}
}];
if (index != NSNotFound)
{
__block NSUInteger sourceIndex = NSNotFound;
[self.messsagesSource enumerateObjectsUsingBlock:^(EMMessage *message, NSUInteger idx, BOOL *stop){
if ([message isKindOfClass:[EMMessage class]]) {
if ([msg.messageId isEqualToString:message.messageId])
{
sourceIndex = idx;
*stop = YES;
}
}
}];
if (sourceIndex != NSNotFound) {
[self.messsagesSource replaceObjectAtIndex:sourceIndex withObject:newModel.message];
}
[self.dataArray replaceObjectAtIndex:index withObject:newModel];
[self.tableView reloadData];
}
if (isSave) {
[self.conversation insertMessage:message error:nil];
}
}
#pragma mark - EMChooseViewDelegate
//- (BOOL)viewController:(EMChooseViewController *)viewController didFinishSelectedSources:(NSArray *)selectedSources
//{
// if ([selectedSources count]) {
// EaseAtTarget *target = [[EaseAtTarget alloc] init];
// target.userId = selectedSources.firstObject;
// UserProfileEntity *profileEntity = [[UserProfileManager sharedInstance] getUserProfileByUsername:target.userId];
// if (profileEntity) {
// target.nickname = profileEntity.nickname == nil ? profileEntity.username : profileEntity.nickname;
// }
// if (_selectedCallback) {
// _selectedCallback(target);
// }
// }
// else {
// if (_selectedCallback) {
// _selectedCallback(nil);
// }
// }
// return YES;
//}
//
//- (void)viewControllerDidSelectBack:(EMChooseViewController *)viewController
//{
// if (_selectedCallback) {
// _selectedCallback(nil);
// }
//}
八.环信消息推送
1.[ 开发者账号证书配置 ](http://www.jianshu.com/p/eb8d9493bc9d)
2.[ 上传推送证书到环信 ](http://docs.easemob.com/im/300iosclientintegration/apns)
3.在 didFinishLaunchingWithOptions 中 初始化环信及环信推送
/* EM 环信 */
- (void)setUpEMSomething{
EMOptions *options = [EMOptions optionsWithAppkey:@"115517XXXX115537#xiubei"];
options.apnsCertName = @"xiubei_develop";
[[EMClient sharedClient] initializeSDKWithOptions:options];
EMPushOptions *emoptions = [[EMClient sharedClient] pushOptions];
emoptions.displayStyle = EMPushDisplayStyleMessageSummary;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[EMClient sharedClient] updatePushOptionsToServer];
});
[[EaseSDKHelper shareHelper] hyphenateApplication:application
didFinishLaunchingWithOptions:launchOptions
appkey:@"115517XXXX115537#xiubei"
apnsCertName:@"xiubei_develop"
otherConfig:@{kSDKConfigEnableConsoleLogger:[NSNumber numberWithBool:YES]}];
[[EMClient sharedClient].chatManager addDelegate:self delegateQueue:nil];
}
4.注意点
1)未上线前,通过更改 options.apnsCertName ,来进行上线和未上线的区别(证书名字在请看第2步 - 环信证书上传步骤)
2)推送显示消息内容 是 "一条新消息"还是消息详情内容,设置属性 emoptions.displayStyle
EMPushOptions *emoptions = [[EMClient sharedClient] pushOptions];
emoptions.displayStyle = EMPushDisplayStyleMessageSummary;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[EMClient sharedClient] updatePushOptionsToServer];
});
九.问题小结
1. 自定义 列表视图的 tableview 高度,根据自己需求调整!
方法:- (void)chatToolbarDidChangeFrameToHeight:(CGFloat)toHeight
BB7AE49930F859B4C63B1BDA7D9B29AB.jpg
2.messageChatController 即私信对话框页面,不能实现 scrollView代理隐藏键盘,不然聊天记录超过半屏后会造成屏幕卡住,私聊页面无法使用情况!
3.在 tableViewDidTriggerHeaderRefresh 方法里面,对接服务器,获取聊天列表头像和昵称!
4.在 EaseConversationListViewController 中的 tableViewDidTriggerHeaderRefresh 方法中请求服务器,获取会话列表相关信息!
网友评论