前言:

      環(huán)信的SDK在公司的項(xiàng)目中有用到,現(xiàn)在用到的是群聊的部分,這里我們分析總結(jié)一下自己對(duì)環(huán)信給的DEMO大概的拆解一下,說說我們?cè)趺礃映浞值睦眠@個(gè)demo來寫我們所需要的業(yè)務(wù)。這個(gè)也由于篇幅的原因,實(shí)在沒辦法寫成一篇博客,我們今天先說說它的一個(gè)文件解析昵稱頭像的實(shí)現(xiàn)。寫這篇博客環(huán)信也是更新到3.0版本了,我們就按照3.0的版本分析一下,先看看這整個(gè)Demo的大概的文件;

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn)

剛開始,使用這個(gè)Demo的時(shí)候,有些人不知道自己需要的到底是什么文件,一個(gè)勁的恨不得連整個(gè)Demo全都拉進(jìn)來,建議大家千萬不要這樣子做,你花點(diǎn)時(shí)間好好研究一些,看一下整個(gè)Demo有哪些你是用的著的,有哪些你是用不著的,找有用的拉進(jìn)自己的項(xiàng)目中!給大家看看我覺得你用的著的一下文件,先看這整個(gè)大文件夾EaseUI,環(huán)信的文件我用到的全都在這里了。

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn)

我自己拉到項(xiàng)目中的就這么多,當(dāng)然這個(gè)也因需求有個(gè)具體的不同,說兩個(gè)地方:

一: 關(guān)于3rdparty這個(gè)文件,這里面是第三方的文件,有些事環(huán)信二次封裝的,你一定要看清楚,已經(jīng)在你項(xiàng)目中的,建議不要再拉進(jìn)來!!環(huán)信封裝的一些,比如圖片瀏覽三方這些,你要自己項(xiàng)目中已經(jīng)存在這樣功能的第三方就不要再重復(fù)拉進(jìn)來。保持整個(gè)項(xiàng)目代碼的整潔,避免混亂和一些不懂也沒用的代碼出現(xiàn),給以后造成困難! 

二:Resources這個(gè)文件,這里面的圖片我?guī)缀跏且呀?jīng)刪除干凈了,我們自己項(xiàng)目中的UI肯定是要自己重新寫的,不能直接連圖片就不改動(dòng)的用環(huán)信的Demo,建議這里這樣做,等你們的設(shè)計(jì)師做好相應(yīng)的UI切圖之后,你拿到圖片再找環(huán)信對(duì)應(yīng)的是那張,全局搜索這張圖片的名字,找到位置,看清楚了再把自己的UI切圖名稱換上去!

三:說說環(huán)信SDK,因?yàn)樽约旱捻?xiàng)目中還是有網(wǎng)易云直播SDK和支付寶微信的SDK,比較的多,這時(shí)候你一定要注意靜態(tài)文件!避免這里面出現(xiàn)沖突!其實(shí)只要仔細(xì)點(diǎn),集成環(huán)信這一步我相信大部分人都沒啥問題,集成這個(gè)也不是我們今天說的重點(diǎn),我們把重點(diǎn)放在功能解析Demo上面!

重點(diǎn)是這兩個(gè)文件:Class 和 EaseUI 

      恩,是的,重點(diǎn)就是這個(gè)文件,重點(diǎn)都在這個(gè)文件夾當(dāng)中,我們先看看Class這個(gè)文件夾當(dāng)中的內(nèi)容:

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn)

    說這么幾點(diǎn),先看到這里的話,我的給大家說一下,

一:這里的三個(gè)文件CoreData文件就是本地化的一些存儲(chǔ),ChatGroup是關(guān)于群聊的一些文件,剩下的幾乎都在Chat這個(gè)文件夾當(dāng)中了。

二:APPDelegate的幾個(gè)類別,寫的還是不錯(cuò)的,這說的不是說代碼多精簡(jiǎn),看著這里我也真的是學(xué)習(xí)到了,以后這樣的話我們的支付,聊天,推送等等都可以一個(gè)功能一個(gè)功能的區(qū)分開了,簡(jiǎn)單,明了??!看看下面我們項(xiàng)目中的真實(shí)按照這思路寫的,希望大家看了都可以學(xué)到思路,具體怎么寫的,你可以看看Demo里面的代碼,有問題也可以來找我!我盡我所能!

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn)

 

在說說這個(gè) EaseUI,這么說吧,只要和界面相關(guān)的東西都在這個(gè)文件夾里面??!EaseUI這里面最重要的是ViewController這個(gè)文件夾了:iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn)

 

箭頭標(biāo)注出來的地方,大家注意這個(gè)繼承關(guān)系!

仔細(xì)說說下面的功能:

一:頭像和昵稱

       給大家看看下面的效果圖,這是自己我們項(xiàng)目中的界面截圖:

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn)

好,我們說說這個(gè)昵稱和頭像,官方有給出這兩個(gè)方法來處理頭像;

方法一 從APP服務(wù)器獲取昵稱和頭像

  • 昵稱和頭像的獲?。寒?dāng)收到一條消息(群消息)時(shí),得到發(fā)送者的用戶ID,然后查找手機(jī)本地?cái)?shù)據(jù)庫是否有此用戶ID的昵稱和頭像,如沒有則調(diào)用APP服務(wù)器接口通過用戶ID查詢出昵稱和頭像,然后保存到本地?cái)?shù)據(jù)庫和緩存,下次此用戶發(fā)來信息即可直接查詢緩存或者本地?cái)?shù)據(jù)庫,不需要再次向APP服務(wù)器發(fā)起請(qǐng)求

  • 昵稱和頭像的更新:當(dāng)點(diǎn)擊發(fā)送者頭像時(shí)加載用戶詳情時(shí)從APP服務(wù)器查詢此用戶的具體信息然后更新本地?cái)?shù)據(jù)庫和緩存。當(dāng)用戶自己更新昵稱或頭像時(shí),也可以發(fā)送一條透?jìng)飨⒌狡渌脩艉陀脩羲诘娜海瑏砀略撚脩舻年欠Q和頭像。

方法二 從消息擴(kuò)展中獲取昵稱和頭像

  • 昵稱和頭像的獲?。喊延脩艋镜年欠Q和頭像的URL放到消息的擴(kuò)展中,通過消息傳遞給接收方,當(dāng)收到一條消息時(shí),則能通過消息的擴(kuò)展得到發(fā)送者的昵稱和頭像URL,然后保存到本地?cái)?shù)據(jù)庫和緩存。當(dāng)顯示昵稱和頭像時(shí),請(qǐng)從本地或者緩存中讀取,不要直接從消息中把賦值拿給界面(否則當(dāng)用戶昵稱改變后,同一個(gè)人會(huì)顯示不同的昵稱)。

  • 昵稱和頭像的更新:當(dāng)擴(kuò)展消息中的昵稱和頭像URI與當(dāng)前本地?cái)?shù)據(jù)庫和緩存中的相應(yīng)數(shù)據(jù)不同的時(shí)候,需要把新的昵稱保存到本地?cái)?shù)據(jù)庫和緩存,并下載新的頭像并保存到本地?cái)?shù)據(jù)庫和緩存。

       這里項(xiàng)目采用的是方法二,通過擴(kuò)展消息來添加頭像和昵稱:我們一句一句的實(shí)現(xiàn)上面的話,先實(shí)現(xiàn)這一條:當(dāng)收到一條消息時(shí),則能通過消息的擴(kuò)展得到發(fā)送者的昵稱和頭像URL,然后保存到本地?cái)?shù)據(jù)庫和緩存。

     下面的兩個(gè)文件是通過FMDB緩存的,通過CoreData肯定也是沒有問題的,下面是緩存文件的源碼文件ChatUserDataManagerHelper.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#import <Foundation/Foundation.h>
#import "UserInfoModel.h"
#import "FMDB.h"
 
@interface ChatUserDataManagerHelper : NSObject
 
/**
 保存用戶數(shù)據(jù),登錄創(chuàng)建Model保存
  
 @param userinfoDic 用戶數(shù)據(jù)字典
 */
+(void)saveUserInfoModel:(UserInfoModel*)userInfo;
 
/**
 保存用戶數(shù)據(jù),收到消息的擴(kuò)展是字典類型,用這個(gè)方法直接保存。
  
 @param userinfoDic 用戶數(shù)據(jù)字典
 */
+(void)saveUserInfoDictionary:(NSDictionary *)userinfoDic;
 
/**
 根據(jù)一個(gè)userID 查詢一個(gè)用戶數(shù)據(jù)
  
 @param  userid         用戶id
 @return UserInfoModel  返回一個(gè)用戶Model
 */
+(UserInfoModel *)queryByuserEaseMobId:(NSString *)userid;
 
@end

 還有就是ChatUserDataManagerHelper.m文件了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#import "ChatUserDataManagerHelper.h"
 
#define DBNAME @"cache_data.db"
 
@implementation ChatUserDataManagerHelper
 
/**
 類方法創(chuàng)建一張表單
  
 @param FMDBTable FMDBTable表
 */
 
+(void)createTable:(FMDatabase *)Database
{
    // 打開
    if ([Database open]) {
         
        // 要是不存在UserInfo表單
        if (![Database tableExists :@"userinfo"]) {
             
            // 創(chuàng)建這張表單,參數(shù)(用戶ID,用戶名稱,用戶頭像)
            if ([Database executeUpdate:@"create table userinfo (userid text, username text, userimage text)"]) {
                 
                // NSLog(@"create table success");
                 
            }else{
                 
               // NSLog(@"fail to create table");
            }
             
        }else {
             
               // NSLog(@"table is already exist");
        }
         
    // 打開失敗
    }else{
         
      // NSLog(@"fail to open");
    }
}
  
/**
 從userinfo清除所有信息
 
 @param FMDBTable FMDBTable表
 */
+ (void)clearTableData:(FMDatabase *)Database
{
    if ([Database executeUpdate:@"DELETE FROM userinfo"]) {
         
        //NSLog(@"clear successed");
         
    }else{
         
        // NSLog(@"fail to clear");
    }
}
  
/**
 獲取FMDatabase
  
 @return FMDatabase
 */
+(FMDatabase*)getFMDB{
     
    NSString   *  docsPath   = NSSearchPathForDirectoriesInDomains(NSDocumentDirectoryNSUserDomainMaskYES)[0];
    NSString   *  FMDBPath   = [docsPath stringByAppendingPathComponent:DBNAME];
    FMDatabase *  Database   = [FMDatabase databaseWithPath:FMDBPath];
    [self createTable:Database];
    return Database;
}
  
/**
 保存用戶Model
 
 @param userInfo userInfo description
 */
+(void)saveUserInfoModel:(UserInfoModel*)userInfo{
     
    [ChatUserDataManagerHelper SaveUserInfoWithUserEaseMobId:userInfo.userEaseMobId andUserHeaderImageUrl:userInfo.userHeaderImageUrl andUserNickName:userInfo.usernickName];
}
  
/**
 根據(jù)創(chuàng)建的用戶數(shù)據(jù)Model,保存用戶信息
 
 @param easeMobId 用戶ID
 @param imageUrl  用戶頭像
 @param nickName  用戶昵稱
 */
 
+(void)SaveUserInfoWithUserEaseMobId:(NSString *)easeMobId andUserHeaderImageUrl:(NSString*)imageUrl andUserNickName:(NSString*)nickName{
          
    NSMutableDictionary * userDic = [NSMutableDictionary dictionary];
     
    [userDic setValue:easeMobId forKey:CHATUSERID];
    [userDic setValue:imageUrl  forKey:CHATUSRTHEADIMAGE];
    [userDic setValue:nickName  forKey:CHATUSERNICK];
     
    [ChatUserDataManagerHelper saveUserInfoDictionary:userDic];
}
  
/**
 保存用戶數(shù)據(jù)
 
 @param userinfoDic 用戶數(shù)據(jù)字典
 */
+(void)saveUserInfoDictionary:(NSDictionary *)userinfoDic{
     
    FMDatabase *  dataBase = [self getFMDB];
     
    NSString   *  userid   = [userinfoDic objectForKey:CHATUSERID];
     
    if ([dataBase executeUpdate:@"DELETE FROM userinfo where userid = ?", userid]) {
         
        debugLog(@"刪除成功");
         
    }else{
         
        debugLog(@"刪除失敗");
    }
     
    NSString *username  = [userinfoDic objectForKey:CHATUSERNICK];
    NSString *userimage = [userinfoDic objectForKey:CHATUSRTHEADIMAGE];
    if ([dataBase executeUpdate:@"INSERT INTO userinfo (userid, username, userimage) VALUES (?, ?, ?)", userid,username,userimage]) {
         
        debugLog(@"插入成功");
         
    }else{
         
        debugLog(@"插入失敗");
    }
     
    //  NSLog(@"%d: %@", [db lastErrorCode], [db lastErrorMessage]);
    FMResultSet *rs = [dataBase executeQuery:@"SELECT userid, username, userimage FROM userinfo where userid = ?",userid];
     
    if ([rs next]) {
         
        NSString * userid    = [rs stringForColumn:@"userid"];
        NSString * username  = [rs stringForColumn:@"username"];
        NSString * userimage = [rs stringForColumn:@"userimage"];
        debugLog(@"查詢一個(gè) %@ %@ %@",userid,username,userimage);
    }
     
    rs = [dataBase executeQuery:@"SELECT userid, username, userimage FROM userinfo"];
    while ([rs next]) {
        NSString * userid    = [rs stringForColumn:@"userid"];
        NSString * username  = [rs stringForColumn:@"username"];
        NSString * userimage = [rs stringForColumn:@"userimage"];
         
        debugLog(@"查詢所有 %@ %@ %@",userid,username,userimage);
    }
     
    [rs close];
     
    // NSLog(@"%d: %@", [db lastErrorCode], [db lastErrorMessage]);
    [dataBase close];
}
  
/**
 根據(jù)一個(gè)userID 查詢一個(gè)用戶數(shù)據(jù)
 
 @param  userid         用戶id
 @return UserInfoModel  返回一個(gè)用戶Model
 */
 
+(UserInfoModel *)queryByuserEaseMobId:(NSString *)userid {
     
    FMDatabase * dataBase     = [self getFMDB];
     
    if ([dataBase open]) {
         
        FMResultSet *rs = [dataBase executeQuery:@"SELECT userid, username, userimage FROM userinfo where userid = ?",userid];
         
        if ([rs next]) {
             
            UserInfoModel * userInfo = [[UserInfoModel alloc] init];
             
            userInfo.userEaseMobId      = [rs stringForColumn:@"userid"];
            userInfo.usernickName       = [rs stringForColumn:@"username"];
            userInfo.userHeaderImageUrl = [rs stringForColumn:@"userimage"];
             
            debugLog(@"查詢一個(gè) %@",userInfo);
            return userInfo;
             
        }else{
             
            return nil;
        }
    }else{
         
        return nil;
    }
}
 
@end

注意: 通過上面的代碼,你就實(shí)現(xiàn)了存儲(chǔ)的功能。不過你的記著,在登錄成功之后你得先把自己的信息存儲(chǔ)起來,在更改了個(gè)人資料之后,你要更新這里的存儲(chǔ)信息。

我們?cè)僬f這個(gè)發(fā)送消息的時(shí)候,把自己的個(gè)人信息附加在擴(kuò)展消息當(dāng)中發(fā)送出去,這里我們就用發(fā)送文本消息為例子,其他的都一樣:

你找到EaseSDKHelper.m這個(gè)文件,這里面有這個(gè)方法

+(EMMessage *)sendTextMessage:(NSString *)text  to:(NSString *)toUser  messageType:(EMChatType)messageType  messageExt:(NSDictionary *)messageExt

說說這里,這個(gè)你看看Demo的話你就可以看到,所有的信息發(fā)送都是EaseSDKHelper這個(gè)類發(fā)送的,由于這個(gè)EaseMessageViewController控制器已經(jīng)代碼行數(shù)夠多了,就不要再在這里添加了,寫在EaseSDKHelper,在EaseMessageViewController中有下面這個(gè)方法,這個(gè)方法就是發(fā)送消息的

- (void)_sendMessage:(EMMessage *)message

看看EaseSDKHelper.m中我們?cè)鯓犹砑訑U(kuò)展消息發(fā)送的,

http://www.cnblogs.com/taoxu/p/6306494.html