這段時間由于家里的事和工作上的項目太忙好久沒寫東西了,,,今天先說說集成環信的經驗吧,也許會很亂,我會慢慢修改的。新手一枚第一次集成環信,咱們慢慢看算是我自己的一個整理。
一、準備工作:
- 環信官網http://www.easemob.com 也可以百度環信還是很好找的。
2.蘋果賬號,因為集成即時聊天要推送證書所以必須有賬號,證書制作我就不在這里說了,可以上網查。
3.在環信創建APP上傳推送證書,這樣可以了過程很簡單的(appkey,推送證書名是有用的可以先記錄)。
二、開始集成
1.這里總的說一下
第一點環信提供兩套SDK,一套帶有實時語音(打電話)版本HyphenateFullSDK,一套沒有的HyphenateSDK,正常不是專門聊天的APP都是不用實時語音功能的。
第二點環信給了一套做好的UI叫EaseUI,可以用能減少很多時間,特別是聊天頁面自己寫比較麻煩,特別是EASYUI中的Model寫的都不錯。
第三點集成方式可以手動集成SDK,可以用pod集成,手動集成就不說了,下面給出pod命令
pod 'HyphenateSDK', :git => 'https://github.com/easemob/hyphenate-cocoapods.git'
pod 'HyphenateFullSDK', :git => 'https://github.com/easemob/hyphenate-full-cocoapods.git'
pod 'EaseUI' //這個環信官網上沒有是我在環信的git上找到的。
這里有一點注意的地方,如果你用pod集成,注意pod更新是會吧你改動的代碼刷新掉,可以不直接用EaseUI里的東西,可以寫子類,或者刷新掉了,可以用git或者svn,還原修改,這樣就能回來了。
這樣我們就把SDK集成到我們的項目了。
第四點什么改APP端做什么該服務端做,服務端做的其實很少,只有兩個,第一注冊環信,這部分一般式綁定在我們注冊當前APP用戶的要查詢服務端數據庫,所以服務端做,第二,好友關系,環信用戶之間聊天是不需要好友關系的,所以決定了好友關系這部分可以直接用我們的服務端維護。這兩點以外,其他的都是我們APP端做,,,
2.開始代碼部分(這部分代碼前提集成了HyphenateSDK和EaseUI)
首先在AppDelegate中注冊環信,直接可用EaseUI中的注冊方法
一,注冊環信
/*!
* APP啟動時注冊環信,并登陸當前用戶(如果有用戶的話)
*
* @param application application description
* @param launchOptions launchOptions description
*/
-(void)startHuanXinEasyUIUseapplication:(UIApplication *)application Options:(NSDictionary *)launchOptions{
//AppKey:注冊的AppKey,詳細見下面注釋。
//apnsCertName:推送證書名(不需要加后綴),詳細見下面注釋。
NSString *apnsCertName = nil;
#if DEBUG
apnsCertName = @"開發環境測試證書";
#else
apnsCertName = @"發布環境證書";
#endif
//環信appkey存放在UserDefaults
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
NSString *appkey = [ud stringForKey:@"identifier_appkey"];
if (!appkey) {
appkey = @"appkey";
[ud setObject:appkey forKey:@"identifier_appkey"];
}
//利用EasyUI啟動環信(這里有一個坑,下面這個注冊方法,點進去看會吧用戶是否同意被加進群組改成NO,這里會導致群組加不上,記得看看,改回來)
[[EaseSDKHelper shareHelper] easemobApplication:application
didFinishLaunchingWithOptions:launchOptions
appkey:appkey
apnsCertName:apnsCertName
otherConfig:@{kSDKConfigEnableConsoleLogger:[NSNumber numberWithBool:YES]}];
//判斷當前是否有用戶,有用戶登陸環信
if (DEF_PERSISTENT_GET_OBJECT(@"userId") != nil && DEF_PERSISTENT_GET_OBJECT(@"userPwd") != nil) {
NSString *accound = [NSString stringWithFormat:@"%@",DEF_PERSISTENT_GET_OBJECT(@"userId")];
NSString *pwd = [NSString stringWithFormat:@"%@",DEF_PERSISTENT_GET_OBJECT(@"userPwd")];
EMError *error = [[EMClient sharedClient] loginWithUsername:accound password:pwd];
[[EMClient sharedClient] addDelegate:self];
if (!error) {
NSLog(@"登錄成功");
}
}
}
二、環信好友
聊天就得有好友,剛開始總述中說過好友是咱們服務器來維護的所以不用管,走一個接口就好了,因為我們集成EasyUI所以我們從接口中請求的數據最好都變成EasyUI中用戶的Model(EaseUserModel),這樣在用環信聊天的是不會那么麻煩,也可以自己寫一個Model這樣麻煩但是不亂,
#import <Foundation/Foundation.h>
#import "IUserModel.h"
@interface EaseUserModel : NSObject<IUserModel>
@property (strong, nonatomic, readonly) NSString *buddy;//用戶名
@property (strong, nonatomic) NSString *nickname;//名字
@property (strong, nonatomic) NSString *avatarURLPath;//頭像地址
@property (strong, nonatomic) UIImage *avatarImage;//頭像圖片
- (instancetype)initWithBuddy:(NSString *)buddy;
@end
中用戶名是最有用的是直接用于創建聊天的,名字頭像用處不大,因為這些存儲都是在本地的,地方一改名字頭像你這面可能沒反應所以不用這個頭像名字,都是使用消息中的擴展字段下面說。
三、環信聊天
聊天界面我推薦直接用EasyUI的,自己寫各種消息cell實在麻煩,使用這個直接就是可以聊天的創建方法如下
EaseMessageViewController *viewController = [[EaseMessageViewController alloc] initWithConversationChatter:@"聊天對象的id,或者群組的id" conversationType:聊天的類型(單聊,群聊,聊天室)];
四、環信聊天消息重點*
在發消息過程中是不能傳遞用戶名和頭像的,所以我們要給消息添加擴展字段ext,(擴展字段可以其實就是發送消息是附帶傳遞一個json數據),我們可以吧自己的頭像和名字在每次發消息的時候發過去,這樣聊天時,當前本人可以知道自己的名字和頭像,聊天對方會在消息中發過來名字頭像,這樣兩個人都有名字頭像了,下面貼下我的擴展字段
- (void)_sendMessage:(EMMessage *)message //發消息的總方法
{
message.ext = @{@"nikeName":_myNikeName,@"headImagePath":_myHeadImagePath}; //添加消息擴展,我的名字,我的頭像
if (self.conversation.type == EMConversationTypeGroupChat){
message.chatType = EMChatTypeGroupChat;
}
else if (self.conversation.type == EMConversationTypeChatRoom){
message.chatType = EMChatTypeChatRoom;
}
[self addMessageToDataSource:message
progress:nil];
__weak typeof(self) weakself = self;
[[EMClient sharedClient].chatManager asyncSendMessage:message progress:nil completion:^(EMMessage *aMessage, EMError *aError) {
[weakself.tableView reloadData];
}];
}
五、消息列表
消息列表的獲取用環信的獲取方法
- (void)tableViewDidTriggerHeaderRefresh
{
NSArray *conversations = [[EMClient sharedClient].chatManager getAllConversations];//本地獲取消息
NSArray* sorted = [conversations sortedArrayUsingComparator:
^(EMConversation *obj1, EMConversation* obj2){
EMMessage *message1 = [obj1 latestMessage];
EMMessage *message2 = [obj2 latestMessage];
if(message1.timestamp > message2.timestamp) {
return(NSComparisonResult)NSOrderedAscending;
}else {
return(NSComparisonResult)NSOrderedDescending;
}
}];
[self.tableView endHeaderFresh];
[self.tableView reloadData];
}
這里有一個地方,再獲得會話列表的時候,有幾個數據要自己獲取一下,頭像,名字,最后一條消息內容,最后一條消息時間,消息未讀數。其中消息未讀數事環信幫我們做好的直接設置顯示未讀數就好
其中消息最后一條消息內容,最后一條消息時間。要我們獲取最后一條消息在給其賦值
//在tableView代理中寫
cell.detailLabel.attributedText = [[EaseEmotionEscape sharedInstance] attStringFromTextForChatting:[self _latestMessageTitleForConversationModel:model]textFont:cell.detailLabel.font];
cell.timeLabel.text = [self _latestMessageTimeForConversationModel:model];
//獲取最后一條消息內容
- (NSString *)_latestMessageTitleForConversationModel:(id<IConversationModel>)conversationModel
{
NSString *latestMessageTitle = @"";
EMMessage *lastMessage = [conversationModel.conversation latestMessage];
if (lastMessage) {
EMMessageBody *messageBody = lastMessage.body;
switch (messageBody.type) {
case EMMessageBodyTypeImage:{
latestMessageTitle = NSEaseLocalizedString(@"message.image1", @"[image]");
} break;
case EMMessageBodyTypeText:{
NSString *didReceiveText = [EaseConvertToCommonEmoticonsHelper
convertToSystemEmoticons:((EMTextMessageBody *)messageBody).text];
latestMessageTitle = didReceiveText;
} break;
case EMMessageBodyTypeVoice:{
latestMessageTitle = NSEaseLocalizedString(@"message.voice1", @"[voice]");
} break;
case EMMessageBodyTypeLocation: {
latestMessageTitle = NSEaseLocalizedString(@"message.location1", @"[location]");
} break;
case EMMessageBodyTypeVideo: {
latestMessageTitle = NSEaseLocalizedString(@"message.video1", @"[video]");
} break;
case EMMessageBodyTypeFile: {
latestMessageTitle = NSEaseLocalizedString(@"message.file1", @"[file]");
} break;
default: {
} break;
}
}
return latestMessageTitle;
}
//獲取最后一條消息時間
- (NSString *)_latestMessageTimeForConversationModel:(id<IConversationModel>)conversationModel
{
NSString *latestMessageTime = @"";
EMMessage *lastMessage = [conversationModel.conversation latestMessage];;
if (lastMessage) {
double timeInterval = lastMessage.timestamp ;
if(timeInterval > 140000000000) {
timeInterval = timeInterval / 1000;
}
NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:@"YYYY-MM-dd"];
latestMessageTime = [formatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:timeInterval]];
}
return latestMessageTime;
}
至于頭像名字則要我們使用我沒發消息的擴展字段,
這里我們可以獲取會話中最后一條來自對方的消息,然后取出擴展字段賦值就好,(ps:有一種情況我剛剛和一個人說話會話中沒有來自對方的最后一條消息,這個時候我們要用我們本地自己賦值這個會話的頭像和名字)
三、總結
恩,這是這個雜記的第一次寫的東西,寫了寫基本的用法,簡單的聊天功能,寫的也比較亂,,我會慢慢整理修改的。