版本記錄
版本號(hào) | 時(shí)間 |
---|---|
V1.0 | 2017.06.25 |
前言
很多app種都集成環(huán)信做第三方信息通訊工具,這里我們就看一下環(huán)信的主要功能和集成方法窑邦。先給出環(huán)信3.0的地址爷速。
感興趣的可以參考:
1. 環(huán)信ios客戶端的集成(一)
2. 環(huán)信ios客戶端的集成(二)
3. 環(huán)信ios客戶端的集成(三)
4. 環(huán)信ios客戶端的集成(四)
5. 環(huán)信ios客戶端的集成(五)
6. 環(huán)信ios客戶端的集成(六)
7. 環(huán)信ios客戶端的集成(七)
8. 環(huán)信ios客戶端的集成(八)
9. 環(huán)信ios客戶端的集成(九)
10. 環(huán)信ios客戶端的集成(十)
11. 環(huán)信ios客戶端的集成(十一)
12. 環(huán)信ios客戶端的集成(十二)
13. 環(huán)信ios客戶端的集成(十三)
這一篇主要說(shuō)一下環(huán)信的 基于環(huán)信3.0的及時(shí)通訊在具體工程上的應(yīng)用
一、環(huán)信的集成
工程里我使用的是pod進(jìn)行集成的持搜,環(huán)信有兩個(gè)版本吉殃,一個(gè)版本是帶語(yǔ)音功能的辞居,另外一個(gè)版本是不帶語(yǔ)音功能的,我集成的是帶語(yǔ)音功能的蛋勺,方便以后項(xiàng)目需求有所擴(kuò)展瓦灶,目前的項(xiàng)目還是用不到語(yǔ)音的。
pod 'Hyphenate'
下面看一下集成后的環(huán)信文檔組織結(jié)構(gòu)抱完。
二贼陶、環(huán)信的使用
下面就以具體工程為例進(jìn)行具體說(shuō)一下環(huán)信的集成。
單例類管理環(huán)信狀態(tài)
下面新建立一個(gè)環(huán)信單例類乾蛤,在這個(gè)類里的方法主要就是管理登錄狀態(tài)每界,以及幾個(gè)代理的回調(diào)捅僵,包括是否登錄的代理回調(diào)家卖、是否收到消息的代理回調(diào)以及消息是否送達(dá)和讀取的回調(diào)等。
下面看代碼庙楚。
//這個(gè)頭文件繼承自NSObject
#import "JJBaseModel.h"
@interface JJMessageDataTool : NSObject <EMClientDelegate, EMChatManagerDelegate>
//單例
+ (instancetype)shareMessageTool;
//登錄
- (void) loginEMClient;
//退出登陸
- (void) layoutEMClient;
//獲取登陸狀態(tài)
- (BOOL) getLoginStatus;
@end
這里的頭文件上荡,沒(méi)有暴露出是否讀取和有消息的回調(diào)接口,后面會(huì)加上該接口。
#import "JJMessageDataTool.h"
@interface JJMessageDataTool () <EMClientDelegate, EMChatManagerDelegate>
@property (nonatomic, strong) EMClient *client;
@end
@implementation JJMessageDataTool
#pragma mark - Class Public Function
+ (instancetype)shareMessageTool
{
static JJMessageDataTool *tool = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
tool = [[JJMessageDataTool alloc] init];
EMOptions *options = [EMOptions optionsWithAppkey:@"你的環(huán)信appKey"];
[[EMClient sharedClient] initializeSDKWithOptions:options];
[[EMClient sharedClient] addDelegate:tool delegateQueue:nil]; //回調(diào)代理
[[EMClient sharedClient].chatManager addDelegate:tool delegateQueue:nil];
});
return tool;
}
//自動(dòng)登錄回調(diào)
- (void)connectionStateDidChange:(EMConnectionState)aConnectionState
{
if (aConnectionState == EMConnectionConnected) {
NSLog(@"環(huán)信已連接");
}
else {
NSLog(@" 環(huán)信連接斷開(kāi)");
}
}
//會(huì)話列表發(fā)生變化
- (void)conversationListDidUpdate:(NSArray *)aConversationList
{
[[NSNotificationCenter defaultCenter] postNotificationName:kJJPrivateMessageListChat object:aConversationList];
}
//收到消息
- (void)messagesDidReceive:(NSArray *)aMessages
{
[[NSNotificationCenter defaultCenter] postNotificationName:kJJPrivateMessageChat object:aMessages];
}
//消息已讀
- (void)messagesDidRead:(NSArray *)aMessages
{
}
//消息已送達(dá)
- (void)messagesDidDeliver:(NSArray *)aMessages
{
}
//登錄
- (void) loginEMClient
{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
if ([JJConfig getOwnID]) {
//登錄
EMError *loginError = [[EMClient sharedClient] loginWithUsername:[JJConfig getOwnID] password:[JJConfig getEasePassword]];
if (!loginError) {
[[EMClient sharedClient].options setIsAutoLogin:YES];
NSLog(@"環(huán)信登錄成功!!!");
}
else {
NSLog(@"環(huán)信登錄失敗,失敗原因是%@",loginError.errorDescription);
}
}
});
}
//退出登陸
- (void) layoutEMClient
{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[[EMClient sharedClient] logout:YES completion:^(EMError *aError) {
NSLog(@"環(huán)信已退出登陸");
}];
});
}
//獲取登陸狀態(tài)
- (BOOL) getLoginStatus
{
if ([EMClient sharedClient].currentUsername && [EMClient sharedClient].currentUsername.length > 0) {
return YES;
}
return NO;
}
@end
這個(gè)是個(gè)工具在appDidFinishLaunching的時(shí)候就要初始化酪捡,與app生命周期相同叁征,全局進(jìn)行監(jiān)控和管理。
服務(wù)端和客戶端的分工
我們這里繼承環(huán)信需要服務(wù)端的參與逛薇,但是參與的不是很多捺疼,主要如下:
- 服務(wù)端負(fù)責(zé)返回給我們環(huán)信的密碼,注冊(cè)是在服務(wù)端做的永罚;
- 客戶端進(jìn)行其他方面的UI以及邏輯控制啤呼。
我們客戶端向自己的服務(wù)器請(qǐng)求,獲取環(huán)信的密碼呢袱。
這里客戶端有幾點(diǎn)要主要注意:
- 我們這邊是登錄的時(shí)候官扣,服務(wù)器會(huì)返回給我們環(huán)信密碼,而我們登錄分為三方以及手機(jī)號(hào)登錄羞福,因此惕蹄,要在這兩個(gè)地方保存返回的環(huán)信密碼,保存在沙盒治专。
userInfo.easePasswordStr = [dataDict objectForKey:@"easemobPassword"];
//環(huán)信登錄卖陵,在本app登錄成功后登錄環(huán)信
[[ZBMessageDataTool shareMessageTool] loginEMClient];
將這個(gè)字典在兩處登錄成功以后保存,然后以字典的形式保存在偏好設(shè)置里面看靠。
但是app在啟動(dòng)方法里面- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
也要判斷登錄狀態(tài)赶促,如果沒(méi)有登錄,要進(jìn)行登錄挟炬,同樣是用上面的單例進(jìn)行登錄管理工作鸥滨。
1. AppDelegate.m
if ([[JMessageDataTool shareMessageTool] getLoginStatus]) {
//已自動(dòng)登錄
NSLog(@"環(huán)信自動(dòng)登錄");
}
else {
[[JJMessageDataTool shareMessageTool] loginEMClient];
}
登錄好了,下面就是客戶端的工作了谤祖。
客戶端的實(shí)現(xiàn)
下面就是我們的重頭戲婿滓,那就是客戶端的實(shí)現(xiàn)了,前面登錄邏輯以及其他的集成管理都做好了粥喜,下面就是客戶端的事了凸主。我們點(diǎn)擊用戶頭像,然后在點(diǎn)擊發(fā)消息的按鈕额湘,就可以發(fā)送消息了卿吐。
下面先準(zhǔn)備下數(shù)據(jù)。
- (void)contactChatButtonDidClick:(JJUIButton *)button
{
NSLog(@"發(fā)送消息的按鈕被點(diǎn)擊了");
JJChatViewController *chatVC = [[JJChatViewController alloc] init];
JJMessageModel *messageModel = [[JJMessageModel alloc] init];
messageModel.toUserName = self.userModel.userNickname?:@"";
messageModel.uname = [JJConfig getOwnNicename]?:@"";
messageModel.uhead = [JJConfig myProfile].avatar?:@"";
messageModel.toUserHead = self.userModel.userAvatar?:@"";
chatVC.conversationId = [NSString stringWithFormat:@"%ld", self.userModel.userId];
chatVC.messageModel = messageModel;
chatVC.title = self.userModel.userNickname;
[self.navigationController pushViewController:chatVC animated:YES];
}
這里JJChatViewController
是聊天室锋华,JJMessageModel
這個(gè)是聊天數(shù)據(jù)模型嗡官。下面看一下數(shù)據(jù)模型。
#import <Foundation/Foundation.h>
#import "JJMessageChatModel.h"
//私信模型
@interface JJMessageModel : JJBaseModel
@property (nonatomic, copy) NSString *lastMessage; //最后一條消息
@property (nonatomic, copy) NSString *uname; //發(fā)送者昵稱
@property (nonatomic, copy) NSString *uhead; //發(fā)送者頭像
@property (nonatomic, copy) NSString *toUserName; //接受者名稱
@property (nonatomic, copy) NSString *toUserHead; //接受者頭像
@property (nonatomic, copy) NSString *un_read_num; //未讀數(shù)量
@property (nonatomic, copy) NSString *imgPath;
@property (nonatomic, copy) NSString *conversationId;
+ (instancetype)shareMessageModel;
@end
下面我們看一下聊天室JJChatViewController
毯焕。
1. JJChatViewController.h
#import "JJBaseVC.h"
@class JJMessageModel;
//聊天界面
@interface JJChatViewController : JJBaseVC
@property (nonatomic, strong) JJMessageModel *messageModel;
@property (nonatomic, copy) NSString *conversationId;
@end
2. JJChatViewController.m
#import "JJChatViewController.h"
#import "JJMessageChatCell.h"
#import "JJMessageModel.h"
#import "JJMessageDataTool.h"
#import "JJPersonCenterContainVC.h"
@interface JJChatViewController () <UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate, EMChatManagerDelegate, UIImagePickerControllerDelegate, JJMessageChatCellDelegate, JJChatSendCollectionDelegate>
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) NSMutableArray <JJChatModelFrame *>*chatArray;
@property (nonatomic, strong) UITextField *textField;
@property (nonatomic, strong) UIView *sendView;
@property (nonatomic, assign) long long lastTime;
@property (nonatomic, assign) CGFloat kbHeight;
@property (nonatomic, strong) JJUIView *backView;
@property (nonatomic, strong) UIImage *sendImage;
@end
@implementation JJChatViewController
static NSString * const JJMessageChatCellID = @"JJMessageChatCellID";
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
if (![[JJMessageDataTool shareMessageTool] getLoginStatus]) {
[[JJMessageDataTool shareMessageTool] loginEMClient];
}
self.view.backgroundColor = [UIColor colorWithHexString:@"#F1F2F3"];
self.chatArray = [NSMutableArray array];
//創(chuàng)建回話
[self creatSession];
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, kJJCommonScreenWidth, kJJCommonScreenHeight - 50) style:UITableViewStylePlain];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_tableView.backgroundColor = [UIColor colorWithHexString:@"#F1F2F3"];
[self.view addSubview:_tableView];
_tableView.delegate = self;
_tableView.dataSource = self;
[_tableView registerClass:[JMessageChatCell class] forCellReuseIdentifier:JJMessageChatCellID];
self.sendView.frame = CGRectMake(0, kJJCommonScreenHeight - 50, kJJCommonScreenWidth, 50);
self.sendView.backgroundColor = [UIColor whiteColor];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceivedMessages:) name:kJJPrivateMessageChat object:nil];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.navigationController.navigationBarHidden = NO;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
NSLog(@"%s",__FUNCTION__);
}
#pragma mark - Object Private Function
- (UIView *)sendView
{
if (!_sendView) {
_sendView = [[UIView alloc] init];
[self.view addSubview:_sendView];
_textField = [[UITextField alloc] initWithFrame:CGRectMake(10, 5, kJJCommonScreenWidth - 70, 40)];
[_sendView addSubview:_textField];
_textField.borderStyle = UITextBorderStyleRoundedRect;
_textField.placeholder = @"輸入新消息";
_textField.returnKeyType = UIReturnKeyDone;
_textField.delegate = self;
//加號(hào)按鈕
JJUIButton *moreButton = [JJUIButton buttonWithType:UIButtonTypeCustom];
[moreButton setImage:[UIImage imageNamed:@"chat_more"] forState:UIControlStateNormal];
[moreButton addTarget:self action:@selector(moreButtonDidClick:) forControlEvents:UIControlEventTouchUpInside];
[_sendView addSubview:moreButton];
[moreButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(_textField);
make.left.equalTo(_textField.mas_right).offset(10.0);
make.width.height.equalTo(@(CGRectGetHeight(_textField.frame)));
}];
}
return _sendView;
}
- (void)endEdit
{
if (self.textField.text.length == 0) {
return;
}
//發(fā)送出去
[self sendMessageWithMessage:self.textField.text andType:nil];
self.textField.text = @"";
}
- (void)keyboardWillShow:(NSNotification *)notification
{
CGFloat kbHeight = [[notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
self.kbHeight = kbHeight;
// 取得鍵盤的動(dòng)畫時(shí)間衍腥,這樣可以在視圖上移的時(shí)候更連貫
NSTimeInterval duration = [[notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView animateWithDuration:duration animations:^{
//按鈕上移
self.tableView.frame = CGRectMake(0, 0, kJJCommonScreenWidth, kJJCommonScreenHeight - 50 - kbHeight);
self.sendView.frame = CGRectMake(0, kJJCommonScreenHeight - 50 - kbHeight, kJJCommonScreenWidth, 50);
if (self.tableView.contentSize.height > self.tableView.height) {
[self.tableView scrollToBottom];
}
} completion:^(BOOL finished) {
}];
}
- (void)keyboardWillHide:(NSNotification *)notification
{
// 取得鍵盤的動(dòng)畫時(shí)間,這樣可以在視圖上移的時(shí)候更連貫
NSTimeInterval duration = [[notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView animateWithDuration:duration animations:^{
self.tableView.frame = CGRectMake(0, 0, kJJCommonScreenWidth, kJCommonScreenHeight - 50);
self.sendView.frame = CGRectMake(0, kJJCommonScreenHeight - 50, kJJCommonScreenWidth, 50);
if (self.tableView.contentSize.height > self.tableView.height) {
[self.tableView scrollToBottom];
}
} completion:^(BOOL finished) {
}];
}
//判斷前后時(shí)間是否一致
- (BOOL)timeIsEqualInOneHour:(long long )comStrTime
{
NSString *current = [self exchangeTimeFrom:comStrTime];
JJChatModelFrame *chatModelFrame = [self.chatArray lastObject];
NSString *last = [self exchangeTimeFrom:chatModelFrame.messageModel.timestamp];
if ([current isEqualToString:last]) {
return YES;
}
return NO;
}
- (NSString*)exchangeTimeFrom:(long long)timeStamp
{
NSDate *timeDate = [[NSDate alloc]initWithTimeIntervalSince1970:timeStamp/1000];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = @"yyyy年MM月dd日 HH";
NSString *timeStr = [dateFormatter stringFromDate:timeDate];
return timeStr;
}
//創(chuàng)建會(huì)話,讀取歷史消息
- (void)creatSession
{
if (self.chatArray.count > 0) {
[self.chatArray removeAllObjects];
}
EMConversation *conversation = [[EMClient sharedClient].chatManager getConversation:self.conversationId type:EMConversationTypeChat createIfNotExist:YES];
long long timestamp = 0;//拿來(lái)所有聊天記錄
long long toTimeStamp = [NSDate getDateTimeTOMilliSeconds:[NSDate dateWithTimeIntervalSinceNow:0]];
int MAX_ITEM = 1000;
[conversation loadMessagesFrom:timestamp to:toTimeStamp count:MAX_ITEM completion:^(NSArray *aMessages, EMError *aError) {
if (!aError) {
{
for (EMMessage *message in aMessages) {
EMMessageBody *msgBody = message.body;
switch (msgBody.type) {
case EMMessageBodyTypeText://目前只支持文字聊天
{
// 收到的文字消息
EMTextMessageBody *textBody = (EMTextMessageBody *)msgBody;
NSString *chatContent_text = textBody.text;
JJMessageChatModel *messageModel = [[JJMessageChatModel alloc]init];
if (message.direction == EMMessageDirectionSend) {
messageModel.messageDirection = MessageDirectionSend;
}
else {
messageModel.messageDirection = MessageDirectionReceive;
}
messageModel.avatar = @"";
messageModel.messageId = message.messageId;
messageModel.timestamp = message.timestamp;
messageModel.messageContent = chatContent_text;
messageModel.remoteImageUrl = nil;
messageModel.image = nil;
messageModel.type = [[message.ext valueForKey:@"type"] intValue];
if (messageModel.type == 2) {
messageModel.liveModel = [JJLiveModel modelWithDictionary:message.ext];
} else if (messageModel.type == 1){
messageModel.videoModel = [JJShortVideoModel modelWithDictionary:message.ext];
}
BOOL isEqual = NO;
if (self.chatArray) {
isEqual = [self timeIsEqualInOneHour:messageModel.timestamp];
}
JJChatModelFrame *chatModelFrame = [[JJChatModelFrame alloc] initWithFrameModel:messageModel timestamp:self.lastTime];
chatModelFrame.type = [[message.ext valueForKey:@"type"] intValue];
self.lastTime = message.timestamp;
if (chatModelFrame.messageDirection == MessageDirectionSend) {
chatModelFrame.messageModel.avatar = self.messageModel.toUserHead;
} else {
chatModelFrame.messageModel.avatar = self.messageModel.uhead;
}
[self.chatArray addObject:chatModelFrame];
}
break;
case EMMessageBodyTypeImage:{
// 收到的圖片消息
EMImageMessageBody *imageBody = (EMImageMessageBody *)msgBody;
JJMessageChatModel *messageModel = [[JJMessageChatModel alloc]init];
if (message.direction == EMMessageDirectionSend) {
messageModel.messageDirection = MessageDirectionSend;
}
else {
messageModel.messageDirection = MessageDirectionReceive;
}
messageModel.avatar = @"";
messageModel.messageId = message.messageId;
messageModel.messageContent = nil;
messageModel.localImageUrl = imageBody.localPath;
messageModel.remoteImageUrl = imageBody.remotePath;
messageModel.timestamp = message.timestamp;
messageModel.imaageSize = imageBody.size;
messageModel.type = 3;
BOOL isEqual = NO;
if (self.chatArray) {
isEqual = [self timeIsEqualInOneHour:messageModel.timestamp];
}
JJChatModelFrame *chatModelFrame = [[JJChatModelFrame alloc] initWithFrameModel:messageModel timestamp:self.lastTime];
chatModelFrame.type = 3;
self.lastTime = message.timestamp;
if (chatModelFrame.messageDirection == MessageDirectionSend) {
chatModelFrame.messageModel.avatar = self.messageModel.toUserHead;
} else {
chatModelFrame.messageModel.avatar = self.messageModel.uhead;
}
[self.chatArray addObject:chatModelFrame];
}
break;
default:
break;
}
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
if (self.tableView.contentSize.height > self.tableView.height) {
[self.tableView scrollToBottom];
}
});
}
}
}];
}
//文本消息的發(fā)送
- (void)sendMessageWithMessage:(NSString *)messageStr andType:(NSMutableDictionary *)param;
{
if (messageStr.length > 0 || param.count > 0) {
if (!param) {
param = [[NSMutableDictionary alloc] init];
}
[param setObject:[JJConfig getOwnNicename]?:@"" forKey:@"uname"];
[param setObject:[JJConfig myProfile].avatar?:@"" forKey:@"uhead"];
if (messageStr && messageStr.length > 0) {
[param setObject:@"0" forKey:@"type"];
}
if (_messageModel) {
[param setObject:_messageModel.toUserHead?:@"" forKey:@"toUserHead"];
[param setObject:_messageModel.toUserName?:@"" forKey:@"toUserName"];
}
EMTextMessageBody *messageBody = [[EMTextMessageBody alloc] initWithText:messageStr];
EMMessage *message = [[EMMessage alloc] initWithConversationID:self.conversationId from:[JJConfig getOwnID] to:self.conversationId body:messageBody ext:param];
message.chatType = EMChatTypeChat;
message.direction = EMMessageDirectionSend;
NSLog(@"%@", message.ext);
//發(fā)送消息
[[EMClient sharedClient].chatManager sendMessage:message progress:^(int progress) {
} completion:^(EMMessage *message, EMError *error) {
message.chatType = EMChatTypeChat;
EMMessageBody *msgBody = message.body;
if (!error) {
//發(fā)送的是文字消息
EMTextMessageBody *textBody = (EMTextMessageBody *)msgBody;
JJMessageChatModel *messageModel = [[JJMessageChatModel alloc] init];
if (message.direction == EMMessageDirectionSend) {
messageModel.messageDirection = MessageDirectionSend;
}
else {
messageModel.messageDirection = MessageDirectionReceive;
}
messageModel.avatar = @"";
messageModel.messageId = message.messageId;
messageModel.messageContent = textBody.text;
messageModel.timestamp = message.timestamp;
messageModel.type = [[message.ext valueForKey:@"type"] intValue];
if (messageModel.type == 2) {
messageModel.liveModel = [JJLiveModel modelWithDictionary:message.ext];
} else if (messageModel.type == 1){
messageModel.videoModel = [JJShortVideoModel modelWithDictionary:message.ext];
}
DDLogVerbose(@"發(fā)送==%@",messageModel.messageContent);
DDLogVerbose(@"發(fā)送給對(duì)方ID==%@",self.conversationId);
BOOL isEqual = NO;
if (self.chatArray) {
isEqual = [self timeIsEqualInOneHour:messageModel.timestamp];
}
JJChatModelFrame *chatModelFrame = [[JJChatModelFrame alloc] initWithFrameModel:messageModel timestamp:self.lastTime];
self.lastTime = message.timestamp;
chatModelFrame.type = [[message.ext valueForKey:@"type"] intValue];
if (chatModelFrame.messageDirection == MessageDirectionSend) {
chatModelFrame.messageModel.avatar = self.messageModel.toUserHead;
} else {
chatModelFrame.messageModel.avatar = self.messageModel.uhead;
}
[self.chatArray addObject:chatModelFrame];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
[self.tableView scrollToRow:self.chatArray.count - 1 inSection:0 atScrollPosition:UITableViewScrollPositionBottom animated:YES];
});
}
else {
DDLogVerbose(@"錯(cuò)誤描述==%@",error.errorDescription);
}
}];
}
}
//對(duì)象轉(zhuǎn)換為字典的方法
- (NSMutableDictionary *)returnToDictionaryWithModel:(JJMessageModel *)model
{
NSMutableDictionary *userDic = [NSMutableDictionary dictionary];
unsigned int count = 0;
objc_property_t *properties = class_copyPropertyList([JJMessageModel class], &count);
for (int i = 0; i < count; i++) {
const char *name = property_getName(properties[i]);
NSString *propertyName = [NSString stringWithUTF8String:name];
id propertyValue = [model valueForKey:propertyName];
if (propertyValue) {
[userDic setObject:propertyValue forKey:propertyName];
}
}
free(properties);
return userDic;
}
//圖片消息的發(fā)送
- (void)sendImageMessage
{
if (self.sendImage) {
NSMutableDictionary *param = [[NSMutableDictionary alloc] init];
[param setObject:[JJConfig getOwnNicename]?:@"" forKey:@"uname"];
[param setObject:[JJConfig myProfile].avatar?:@"" forKey:@"uhead"];
[param setObject:@"3" forKey:@"type"];
if (_messageModel) {
[param setObject:_messageModel.toUserHead?:@"" forKey:@"toUserHead"];
[param setObject:_messageModel.toUserName?:@"" forKey:@"toUserName"];
}
NSData *imageData = UIImageJPEGRepresentation(self.sendImage, 1);
EMImageMessageBody *imageMessageBody = [[EMImageMessageBody alloc] initWithData:imageData displayName:nil];
EMMessage *imageMessage = [[EMMessage alloc] initWithConversationID:self.conversationId from:[JJConfig getOwnID] to:self.conversationId body:imageMessageBody ext:param];
imageMessage.chatType = EMChatTypeChat;
imageMessage.direction = EMMessageDirectionSend;
[[EMClient sharedClient].chatManager sendMessage:imageMessage progress:^(int progress) {
} completion:^(EMMessage *message, EMError *error) {
if (!error) {
NSLog(@"發(fā)送圖片消息");
JJMessageChatModel *messageModel = [[JJMessageChatModel alloc] init];
if (message.direction == EMMessageDirectionSend) {
messageModel.messageDirection = MessageDirectionSend;
}
else {
messageModel.messageDirection = MessageDirectionReceive;
}
messageModel.avatar = @"";
messageModel.messageId = message.messageId;
messageModel.timestamp = message.timestamp;
messageModel.type = 3;
messageModel.imaageSize = self.sendImage.size;
messageModel.image = self.sendImage;
DDLogVerbose(@"發(fā)送==%@",messageModel.messageContent);
DDLogVerbose(@"發(fā)送給對(duì)方ID==%@",self.conversationId);
BOOL isEqual = NO;
if (self.chatArray) {
isEqual = [self timeIsEqualInOneHour:messageModel.timestamp];
}
JJChatModelFrame *chatModelFrame = [[JJChatModelFrame alloc] initWithFrameModel:messageModel timestamp:self.lastTime];
chatModelFrame.type = 3;
self.lastTime = message.timestamp;
if (chatModelFrame.messageDirection == MessageDirectionSend) {
chatModelFrame.messageModel.avatar = self.messageModel.toUserHead;
} else {
chatModelFrame.messageModel.avatar = self.messageModel.uhead;
}
[self.chatArray addObject:chatModelFrame];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
[self.tableView scrollToRow:self.chatArray.count - 1 inSection:0 atScrollPosition:UITableViewScrollPositionBottom animated:YES];
});
}
}];
}
}
//加載接收的消息
- (void)loadReceivedMessageWithArray:(NSArray *)messageArr
{
if (messageArr.count > 0) {
for (EMMessage *message in messageArr) {
if (![message.conversationId isEqualToString:_conversationId]) {
return;
}
EMMessageBody *msgBody = message.body;
self.messageModel.toUserHead = [message.ext objectForKey:@"toUserHead"];
self.messageModel.toUserName = [message.ext objectForKey:@"toUserName"];
self.messageModel.uhead = [message.ext objectForKey:@"uhead"];
self.messageModel.uname = [message.ext objectForKey:@"uname"];
switch (msgBody.type) {
//文字
case EMMessageBodyTypeText:
{
// 收到的文字消息
EMTextMessageBody *textBody = (EMTextMessageBody *)msgBody;
NSString *chatDetailtext = textBody.text;
JJMessageChatModel *messageModel = [[JJMessageChatModel alloc] init];
if (message.direction == EMMessageDirectionSend) {
messageModel.messageDirection = MessageDirectionSend;
}
else {
messageModel.messageDirection = MessageDirectionReceive;
}
messageModel.avatar = @"";
messageModel.messageId = message.messageId;
messageModel.messageContent = chatDetailtext;
messageModel.timestamp = message.timestamp;
messageModel.type = [[message.ext valueForKey:@"type"] intValue];
messageModel.image = nil;
messageModel.remoteImageUrl = nil;
messageModel.localImageUrl = nil;
if (messageModel.type == 2) {
messageModel.liveModel = [JJLiveModel modelWithDictionary:message.ext];
} else if (messageModel.type == 1){
messageModel.videoModel = [JJShortVideoModel modelWithDictionary:message.ext];
}
BOOL isEqual = NO;
if (self.chatArray) {
isEqual = [self timeIsEqualInOneHour:messageModel.timestamp];
}
JJChatModelFrame *chatModelFrame = [[JJChatModelFrame alloc] initWithFrameModel:messageModel timestamp:self.lastTime];
chatModelFrame.type = [[message.ext valueForKey:@"type"] intValue];
self.lastTime = message.timestamp;
if (chatModelFrame.messageDirection == MessageDirectionSend) {
chatModelFrame.messageModel.avatar = self.messageModel.toUserHead;
} else {
chatModelFrame.messageModel.avatar = self.messageModel.uhead;
}
[self.chatArray addObject:chatModelFrame];
[self.tableView reloadData];
[self.tableView scrollToRow:self.chatArray.count - 1 inSection:0 atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
break;
//圖片
case EMMessageBodyTypeImage:
{
[self performSelector:@selector(loadImageMessage:) withObject:message afterDelay:2.0f];
// [self loadImageMessage:message];
}
break;
default:
break;
}
}
}
}
- (void) loadImageMessage:(EMMessage *)message {
EMMessageBody *msgBody = message.body;
EMImageMessageBody *imageBody = (EMImageMessageBody *)msgBody;
JJMessageChatModel *messageModel = [[JJMessageChatModel alloc] init];
if (message.direction == EMMessageDirectionSend) {
messageModel.messageDirection = MessageDirectionSend;
}
else {
messageModel.messageDirection = MessageDirectionReceive;
}
messageModel.avatar = @"";
messageModel.messageId = message.messageId;
messageModel.timestamp = message.timestamp;
messageModel.localImageUrl = imageBody.localPath;
messageModel.remoteImageUrl = imageBody.remotePath;
messageModel.imaageSize = imageBody.size;
messageModel.messageContent = nil;
messageModel.type = 3;
BOOL isEqual = NO;
if (self.chatArray) {
isEqual = [self timeIsEqualInOneHour:messageModel.timestamp];
}
JJChatModelFrame *chatModelFrame = [[JJChatModelFrame alloc] initWithFrameModel:messageModel timestamp:self.lastTime];
chatModelFrame.type = 3;
self.lastTime = message.timestamp;
if (chatModelFrame.messageDirection == MessageDirectionSend) {
chatModelFrame.messageModel.avatar = self.messageModel.toUserHead;
} else {
chatModelFrame.messageModel.avatar = self.messageModel.uhead;
}
[self.chatArray addObject:chatModelFrame];
[self.tableView reloadData];
[self.tableView scrollToRow:self.chatArray.count - 1 inSection:0 atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
- (void)loadMoreView
{
[UIView animateWithDuration:0.25 animations:^{
//背景View
JJUIView *backView = [[JJUIView alloc] initWithFrame:CGRectMake(0.0, kJJCommonScreenHeight - 432.0/2, kJJCommonScreenWidth, 432.0/2)];
self.tableView.frame = CGRectMake(0, 0, kJJCommonScreenWidth, kJJCommonScreenHeight - 50 - 432.0/2);
backView.backgroundColor = [UIColor lightTextColor];
self.backView = backView;
[self.view addSubview:backView];
//圖片圖片
JJUIButton *pictureButton = [JJUIButton buttonWithType:UIButtonTypeCustom];
[pictureButton setImage:[UIImage imageNamed:@"chat_image"] forState:UIControlStateNormal];
[pictureButton addTarget:self action:@selector(pictureButtonDidClick:) forControlEvents:UIControlEventTouchUpInside];
[self.backView addSubview:pictureButton];
[pictureButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.backView).offset(44/2);
make.top.equalTo(self.backView).offset(39.0f/2);
make.width.height.equalTo(@50);
}];
//圖片文字
JJUILabel *pictureLabel = [[JJUILabel alloc] init];
pictureLabel.text = @"圖片";
pictureLabel.textColor = [UIColor colorWithHexString:@"999999"];
pictureLabel.font = [UIFont fontWithName:kPingFangSC_Regular size:24/2];
[self.backView addSubview:pictureLabel];
[pictureLabel sizeToFit];
[pictureLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(pictureButton.mas_bottom).offset(10.0);
make.centerX.equalTo(pictureButton);
}];
//收藏圖片
JJUIButton *storeButton = [JJUIButton buttonWithType:UIButtonTypeCustom];
[storeButton setImage:[UIImage imageNamed:@"chat_collection"] forState:UIControlStateNormal];
[storeButton addTarget:self action:@selector(storeButtonDidClick:) forControlEvents:UIControlEventTouchUpInside];
[self.backView addSubview:storeButton];
[storeButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(pictureButton.mas_right).offset(88/2);
make.top.equalTo(pictureButton);
make.width.height.equalTo(@50);
}];
//收藏文字
JJUILabel *storeLabel = [[JJUILabel alloc] init];
storeLabel.text = @"收藏";
storeLabel.textColor = [UIColor colorWithHexString:@"999999"];
storeLabel.font = [UIFont fontWithName:kPingFangSC_Regular size:24/2];
[self.backView addSubview:storeLabel];
[storeLabel sizeToFit];
[storeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(pictureLabel);
make.centerX.equalTo(storeButton);
}];
} completion:^(BOOL finished) {
}];
}
#pragma mark - Action && Notification
- (void)didReceivedMessages:(NSNotification *)noti
{
NSArray *messageArr = (NSArray *)noti.object;
[self loadReceivedMessageWithArray:messageArr];
}
- (void)storeButtonDidClick:(JJUIButton *)storeButton
{
NSLog(@"收藏按鈕被點(diǎn)擊了");
JJPersonCenterContainVC *nextVC = [[JJPersonCenterContainVC alloc] init];
nextVC.isChat = YES;
nextVC.delegate = self;
[self.navigationController pushViewController:nextVC animated:YES];
}
- (void)pictureButtonDidClick:(JJUIButton *)pictureButton
{
NSLog(@"圖片按鈕被點(diǎn)擊了");
UIImagePickerController *imagePickerVC = [[UIImagePickerController alloc] init];
imagePickerVC.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePickerVC.allowsEditing = YES;
imagePickerVC.delegate = self;
[self presentViewController:imagePickerVC animated:YES completion:nil];
}
- (void)moreButtonDidClick:(JJUIButton *)moreButton
{
[self.textField resignFirstResponder];
if (self.backView) {
[self.backView removeFromSuperview];
}
[UIView animateWithDuration:0.25 animations:^{
//按鈕上移
self.tableView.frame = CGRectMake(0, 0, kJJCommonScreenWidth, kJJCommonScreenHeight - 50 - 432/2);
self.sendView.frame = CGRectMake(0, kJJCommonScreenHeight - 50 - 432/2, kJJCommonScreenWidth, 50);
if (self.tableView.contentSize.height > self.tableView.height) {
[self.tableView scrollToBottom];
}
} completion:^(BOOL finished) {
}];
[self loadMoreView];
}
#pragma mark - UITableViewDelegate, UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.chatArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
JJMessageChatCell *cell = [tableView dequeueReusableCellWithIdentifier:JJMessageChatCellID forIndexPath:indexPath];
cell.delegate = self;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.chatModelFrame = self.chatArray[indexPath.row];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
JJChatModelFrame *chatModelFrame = self.chatArray[indexPath.row];
return chatModelFrame.cellHeight;
}
- (void)didClickImagePlusImage:(UIImage *)image{
if (image) {
UIButton *btn = [[UIButton alloc] initWithFrame:self.view.frame];
[btn setBackgroundColor:[UIColor blackColor]];
[btn setImage:image forState:UIControlStateNormal];
btn.alpha = 0;
[btn addTarget:self action:@selector(didClickHiddenImageView:) forControlEvents:UIControlEventTouchUpInside];
[[UIApplication sharedApplication].keyWindow addSubview:btn];
[UIView animateWithDuration:0.25 animations:^{
btn.alpha = 1;
}];
}
}
- (void) didClickHiddenImageView:(UIButton *)sender {
[UIView animateWithDuration:0.25 animations:^{
sender.alpha = 0;
} completion:^(BOOL finished) {
[sender removeFromSuperview];
}];
}
#pragma mark - UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[self endEdit];
return YES;
}
#pragma mark - UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
[picker dismissViewControllerAnimated:YES completion:nil];
self.sendImage = info[UIImagePickerControllerOriginalImage];
//發(fā)送圖片消息
[self sendImageMessage];
}
@end
這里還有幾個(gè)類需要說(shuō)明一下婆咸。
首先要說(shuō)的是JJMessageChatModel
這個(gè)類竹捉,這個(gè)類的作用就是存放聊天室每個(gè)cell里面的數(shù)據(jù)模型。
#import <Foundation/Foundation.h>
#import "JJLiveModel.h"
#import "JJShortVideoModel.h"
typedef NS_ENUM(NSInteger ,MessageDirection)
{
MessageDirectionSend = 1, //發(fā)送消息
MessageDirectionReceive //接受消息
};
//聊天模型
@interface JJMessageChatModel : JJBaseModel
@property (nonatomic, copy) NSString *avatar; //頭像
@property (nonatomic, assign) MessageDirection messageDirection; //消息來(lái)源類型
@property (nonatomic, copy) NSString *messageId; //消息id;
@property (nonatomic, copy) NSString *messageContent; //文本消息尚骄;
@property (nonatomic, assign) long long timestamp; //消息時(shí)間戳
@property (nonatomic, copy) NSString *verify_info; //認(rèn)證信息
@property (nonatomic, copy) NSString *cornerMark; //頭像角標(biāo)
@property (nonatomic, copy) NSString *message; //消息
@property (nonatomic, copy) NSString *remoteImageUrl; //圖片網(wǎng)絡(luò)地址
@property (nonatomic, copy) NSString *localImageUrl; //圖片沙盒地址
@property (nonatomic, copy) UIImage *image; //圖片
@property (nonatomic, assign) CGSize imaageSize;
@property (nonatomic, strong) JJShortVideoModel *videoModel;
@property (nonatomic, strong) JJLiveModel *liveModel;
@property (nonatomic, assign) int type;
@end
下面還有個(gè)類就是JJChatModelFrame
块差,這個(gè)類的作用就是負(fù)責(zé)給每一個(gè)cell賦值并調(diào)整每一個(gè)cell的大小,如下所示:
1. JJChatModelFrame.h
#import <Foundation/Foundation.h>
#import "JJMessageViewController.h"
#import "JJMessageChatModel.h"
#define ChatHeadImage_height 42.0f
#define TimeLabel_height 20.0f
@interface JJChatModelFrame : NSObject
/** 時(shí)間的Frame */
@property (nonatomic,assign)CGRect timeLabelFrame;
/** 頭像的Frame */
@property (nonatomic,assign)CGRect headImageFrame;
/** 聊天內(nèi)容的Frame */
@property (nonatomic,assign)CGRect contentFrame;
/** 認(rèn)證標(biāo)志的Frame */
@property (nonatomic,assign)CGRect verifyBadgeFrame;
/** 消息來(lái)源類型 */
@property (nonatomic,assign) MessageDirection messageDirection;
/** 模型數(shù)據(jù) */
@property (nonatomic,strong) JJMessageChatModel *messageModel;
/*cell的高度 */
@property (nonatomic,assign)CGFloat cellHeight;
@property (nonatomic, assign) int type; //1. 文字倔丈,2. 節(jié)目 3. 創(chuàng)意視頻 4. 圖片
/** 通過(guò)模型數(shù)據(jù)計(jì)算出對(duì)應(yīng)的Frame,并且返回出modelFrame自己這個(gè)對(duì)象 */
- (instancetype)initWithFrameModel:model timestamp:(NSTimeInterval)timestamp;
//和上面同理
+ (instancetype)modelFrame:(JJMessageChatModel *)messageModel timestamp:(NSTimeInterval)timestamp;
@end
2. JJChatModelFrame.m
#import "JJChatModelFrame.h"
#define contentFont [UIFont systemFontOfSize:15.0]//聊天消息字體的大小
#define distance 8 //邊距
@implementation JJChatModelFrame
#pragma mark - Object Public Function
- (instancetype)initWithFrameModel:(JJMessageChatModel *)messageModel timestamp:(NSTimeInterval)timestamp
{
self = [super init];
if (self) {
_messageModel = messageModel;
NSString *timeStr = [self exchangeTimeFrom:messageModel.timestamp];
NSString *lastStr = [self exchangeTimeFrom:timestamp];
BOOL timeBool = [timeStr isEqualToString:lastStr];
CGSize timeSize=[timeStr sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:12.0f]}]; //通過(guò)時(shí)間NSString計(jì)算出寬度
if(!timeBool){//前后時(shí)間不相等 不相等顯示憾儒,相等不顯示
self.timeLabelFrame=CGRectMake(kJJCommonScreenWidth/2.0-(timeSize.width+20)/2.0, 2, timeSize.width+20, TimeLabel_height);//顯示時(shí)間的Frame
}
else{
self.timeLabelFrame=CGRectZero;
}
float width, height;
if (_messageModel.type == 0) {
CGRect btnRect=[_messageModel.messageContent boundingRectWithSize:CGSizeMake(kJJCommonScreenWidth*0.6, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:contentFont}
context:nil];
width = btnRect.size.width+20*2;
height = btnRect.size.height+10*2;
} else if (_messageModel.type == 1) {
width = 150;
height = _messageModel.videoModel.picHeight*150/_messageModel.videoModel.picWidth;
_messageModel.messageContent = @"這是一個(gè)短視頻";
} else if (_messageModel.type == 2) {
width = 389.0f/2;
height = 320/2;
_messageModel.messageContent = @"這是一個(gè)節(jié)目";
} else {
width = 150;
height = _messageModel.imaageSize.height*150/_messageModel.imaageSize.width;
}
if (_messageModel.messageDirection == MessageDirectionSend) {
self.headImageFrame = CGRectMake(kJJCommonScreenWidth-distance-ChatHeadImage_height, CGRectGetMaxY(self.timeLabelFrame)+distance, ChatHeadImage_height, ChatHeadImage_height);
self.contentFrame = CGRectMake(kJJCommonScreenWidth-distance-ChatHeadImage_height-distance-width, CGRectGetMaxY(self.timeLabelFrame)+15, width, height);
}else if (_messageModel.messageDirection == MessageDirectionReceive){
self.headImageFrame=CGRectMake(distance, CGRectGetMaxY(self.timeLabelFrame)+distance,ChatHeadImage_height, ChatHeadImage_height);
self.contentFrame=CGRectMake(distance+ChatHeadImage_height+distance, CGRectGetMaxY(self.timeLabelFrame)+15, width, height);
}
_messageDirection = messageModel.messageDirection;
if (messageModel.verify_info == nil) {
_verifyBadgeFrame = CGRectZero;
}else if (messageModel.verify_info && messageModel.verify_info.length!=0){
_verifyBadgeFrame = CGRectMake(CGRectGetMaxX(self.headImageFrame)-13, CGRectGetMaxY(self.headImageFrame)-13, 13, 13);
}
CGFloat cellH=MAX(CGRectGetMaxY(self.contentFrame), CGRectGetMaxY(self.headImageFrame));//比較輸入的內(nèi)容和頭像的Y值哪個(gè)大
if (cellH == NAN) {
return 0;
}
self.cellHeight=cellH+distance;//返回Cell的高度
}
return self;
}
#pragma mark - Class Public Function
+ (instancetype)modelFrame:(JJMessageChatModel *)messageModel timestamp:(NSTimeInterval)timestamp{
return [[self alloc]initWithFrameModel:messageModel timestamp:timestamp];
}
#pragma mark - Object Private Function
- (NSString*)exchangeTimeFrom:(long long)timeStamp
{
NSDate *timeDate = [[NSDate alloc]initWithTimeIntervalSince1970:timeStamp/1000];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = @"yyyy年MM月dd日 HH:mm";
NSString *timeStr = [dateFormatter stringFromDate:timeDate];
return timeStr;
}
@end
還有一個(gè)界面需要說(shuō)的就是,我們聊天室前一個(gè)界面乃沙,那就是消息列表頁(yè)起趾,這個(gè)頁(yè)面主要就是記錄系統(tǒng)消息,以及其他都誰(shuí)給發(fā)過(guò)了消息警儒,方便用戶點(diǎn)擊進(jìn)入聊天室進(jìn)行聊天训裆。下面直接給出代碼了。
//聊天消息列表頁(yè)
1. JJMessageViewController.m
#import "JJMessageViewController.h"
#import "JJFabulousVC.h"
#import "JJChatViewController.h"
#import "JJMessageCommentVC.h"
#import "JJMessageCell.h"
#import "JJMessageModel.h"
#import "JJMessageDataTool.h"
//消息界面
@interface JJMessageViewController () <UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) NSMutableArray <JJMessageModel *>*messageArray;
@property (nonatomic, copy) NSString *conversationId;
@property (nonatomic,strong) NSMutableArray *conversationIdArrM;
@property (nonatomic, strong) NSMutableArray *sessionArray;
@end
@implementation JJMessageViewController
static NSString *JJMessgaeCellID = @"JJMessgaeCellID";
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *array = @[@{@"uname":@"評(píng)論我的", @"imgPath":@"personCenter_comment"},
@{@"uname":@"贊我的", @"imgPath":@"personCenter_admire"},
@{@"uname":@"客服", @"imgPath":@"personCenter_kefu"},
];
if (![[JJMessageDataTool shareMessageTool] getLoginStatus]) {
[[JJMessageDataTool shareMessageTool] loginEMClient];
}
self.messageArray = [NSMutableArray array];
self.conversationIdArrM = [NSMutableArray array];
for (NSDictionary *dic in array) {
JJMessageModel *model = [JJMessageModel modelWithDictionary:dic];
[self.messageArray addObject:model];
}
self.tableView = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain];
[self.view addSubview:self.tableView];
[self.tableView registerClass:[JJMessageCell class] forCellReuseIdentifier:JJMessgaeCellID];
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.tableFooterView = [[UIView alloc] init];
[self getAllSessions];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark - Object Private Function
- (void)loadMessageDataWithArr:(NSArray *)messageArr
{
if (messageArr.count > 0) {
for (EMMessage *message in messageArr) {
JJMessageModel *model = [[JJMessageModel alloc] init];
model.uname = [JJConfig getOwnNicename];
self.conversationId = message.conversationId;
[self.messageArray addObject:model];
}
[self.tableView reloadData];
}
}
#pragma mark - Action && Notification
- (void)didReceivedMessages:(NSNotification *)noti
{
NSDictionary *messageDict = noti.userInfo;
NSArray *messageArr = [messageDict objectForKey:@"receivedMessage"];
if (messageArr.count > 0) {
for (EMMessage *message in messageArr) {
JJMessageModel *model = [[JJMessageModel alloc] init];
self.conversationId = message.conversationId;
[self.conversationIdArrM addObject:self.conversationId];
[self.messageArray addObject:model];
}
[self.tableView reloadData];
}
}
#pragma mark - UITableViewDelegate, UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.messageArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
JJMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:JJMessgaeCellID forIndexPath:indexPath];
cell.indexPath = indexPath;
cell.model = self.messageArray[indexPath.row];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.row) {
case 0:
{
NSLog(@"跳轉(zhuǎn)評(píng)論頁(yè)");
JJMessageCommentVC *commentVC = [[JJMessageCommentVC alloc] init];
[self.navigationController pushViewController:commentVC animated:YES];
}
break;
case 1:
{
NSLog(@"跳轉(zhuǎn)贊我的頁(yè)");
JJFabulousVC *nextVC = [[JJFabulousVC alloc] init];
nextVC.title = @"贊";
[self.navigationController pushViewController:nextVC animated:YES];
}
break;
case 2:
{
NSLog(@"跳轉(zhuǎn)客服頁(yè)");
}
break;
default:
{
NSLog(@"跳轉(zhuǎn)聊天頁(yè)");
JJChatViewController *nextVC = [[JJChatViewController alloc] init];
nextVC.messageModel = self.messageArray[indexPath.row];
nextVC.conversationId = self.messageArray[indexPath.row].conversationId;
nextVC.title = [nextVC.messageModel.uname isEqualToString:[JJConfig getOwnNicename]]?nextVC.messageModel.toUserName:nextVC.messageModel.uname;
[self.navigationController pushViewController:nextVC animated:YES];
}
break;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 70;
}
-(void)getAllSessions
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSArray *conversations = [[EMClient sharedClient].chatManager getAllConversations];
_sessionArray = (NSMutableArray*)conversations;
dispatch_async(dispatch_get_main_queue(), ^{
if(_sessionArray.count){
for (EMConversation *conversation in _sessionArray) {
// [[EMClient sharedClient].chatManager deleteConversation:conversation.conversationId isDeleteMessages:YES completion:nil];
JJMessageModel *messageModel = [JJMessageModel modelWithDictionary:conversation.latestMessage.ext];
messageModel.conversationId = conversation.conversationId;
if (conversation.latestMessage.body.type == EMMessageBodyTypeText) {
EMTextMessageBody *textBody = (EMTextMessageBody *)conversation.latestMessage.body;
NSNumber *type = [conversation.latestMessage.ext valueForKey:@"type"];
if (type.integerValue == 0) {
messageModel.lastMessage = textBody.text;
} else if (type.integerValue == 2) {
messageModel.lastMessage = @"[收到一個(gè)節(jié)目]";
} else if (type.integerValue == 1) {
messageModel.lastMessage = @"[收到一個(gè)短視頻]";
}
} else {
messageModel.lastMessage = @"[收到一張圖片]";
}
[self.messageArray addObject:messageModel];
}
}
[self.tableView reloadData];
});
});
}
@end
后記
未完蜀铲,待續(xù)~~~