Commit 5666338ca2f56d07a33a9e73354f03c7c399f6a7

Authored by 王军波
1 parent 53e2f273

no message

CNLiveChatManagerSDKDemo/CNLiveChatManagerSDKDemo.xcodeproj/project.pbxproj
... ... @@ -33,6 +33,9 @@
33 33 D26C19281FD6FCE3000D74FC /* CNLiveCommentTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D26C19231FD6FCE3000D74FC /* CNLiveCommentTableViewCell.m */; };
34 34 D26C19291FD6FCE3000D74FC /* CNLiveImageTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D26C19251FD6FCE3000D74FC /* CNLiveImageTableViewCell.m */; };
35 35 D26C192A1FD6FCE3000D74FC /* CNLiveVoiceTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D26C19271FD6FCE3000D74FC /* CNLiveVoiceTableViewCell.m */; };
  36 + D26F82321FFB2B5F009762EE /* CNLiveChatManager.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D26F82311FFB2B5F009762EE /* CNLiveChatManager.framework */; };
  37 + D26F82331FFB2B62009762EE /* CNLiveChatManager.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D26F82311FFB2B5F009762EE /* CNLiveChatManager.framework */; };
  38 + D26F82341FFB2B62009762EE /* CNLiveChatManager.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D26F82311FFB2B5F009762EE /* CNLiveChatManager.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
36 39 D27212341FCD58F000CB3A2E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D27212331FCD58F000CB3A2E /* main.m */; };
37 40 D27212371FCD58F000CB3A2E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D27212361FCD58F000CB3A2E /* AppDelegate.m */; };
38 41 D272123D1FCD58F000CB3A2E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D272123B1FCD58F000CB3A2E /* Main.storyboard */; };
... ... @@ -50,8 +53,6 @@
50 53 D28FF4FF1FF4DAB600BFAF1D /* CNLiveMsgTools.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D28FF4FD1FF4DAAA00BFAF1D /* CNLiveMsgTools.framework */; };
51 54 D28FF5001FF4DAB600BFAF1D /* CNLiveMsgTools.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D28FF4FD1FF4DAAA00BFAF1D /* CNLiveMsgTools.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
52 55 D29899941FF4DB4E001CD929 /* CNLiveChatManager.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D29899931FF4DB4E001CD929 /* CNLiveChatManager.framework */; };
53   - D29899951FF4DB52001CD929 /* CNLiveChatManager.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D29899931FF4DB4E001CD929 /* CNLiveChatManager.framework */; };
54   - D29899961FF4DB52001CD929 /* CNLiveChatManager.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D29899931FF4DB4E001CD929 /* CNLiveChatManager.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
55 56 D2B6C8FA1FCE45E300A25DFD /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2B6C8F91FCE45E300A25DFD /* CoreTelephony.framework */; };
56 57 D2B6C8FC1FCE45ED00A25DFD /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2B6C8FB1FCE45ED00A25DFD /* SystemConfiguration.framework */; };
57 58 D2B6C8FE1FCE45FE00A25DFD /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D2B6C8FD1FCE45FE00A25DFD /* libsqlite3.tbd */; };
... ... @@ -68,7 +69,7 @@
68 69 dstSubfolderSpec = 10;
69 70 files = (
70 71 D28FF5001FF4DAB600BFAF1D /* CNLiveMsgTools.framework in Embed Frameworks */,
71   - D29899961FF4DB52001CD929 /* CNLiveChatManager.framework in Embed Frameworks */,
  72 + D26F82341FFB2B62009762EE /* CNLiveChatManager.framework in Embed Frameworks */,
72 73 );
73 74 name = "Embed Frameworks";
74 75 runOnlyForDeploymentPostprocessing = 0;
... ... @@ -129,6 +130,7 @@
129 130 D26C19251FD6FCE3000D74FC /* CNLiveImageTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CNLiveImageTableViewCell.m; sourceTree = "<group>"; };
130 131 D26C19261FD6FCE3000D74FC /* CNLiveVoiceTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CNLiveVoiceTableViewCell.h; sourceTree = "<group>"; };
131 132 D26C19271FD6FCE3000D74FC /* CNLiveVoiceTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CNLiveVoiceTableViewCell.m; sourceTree = "<group>"; };
  133 + D26F82311FFB2B5F009762EE /* CNLiveChatManager.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = CNLiveChatManager.framework; sourceTree = "<group>"; };
132 134 D272122F1FCD58F000CB3A2E /* CNLiveChatManagerSDKDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CNLiveChatManagerSDKDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
133 135 D27212331FCD58F000CB3A2E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
134 136 D27212351FCD58F000CB3A2E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
... ... @@ -146,7 +148,7 @@
146 148 D28625321FF0C4810074F0E9 /* libresolv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = usr/lib/libresolv.tbd; sourceTree = SDKROOT; };
147 149 D28FF4FB1FF4DAA000BFAF1D /* CNLiveChatManager.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CNLiveChatManager.framework; path = "/Users/cnlive/Desktop/Group/ChatSDK/互动SDKDemo(SDK)/CNLiveChatManagerSDKDemo/CNLiveChatManagerSDKDemo/CNLiveChatManager.framework"; sourceTree = "<absolute>"; };
148 150 D28FF4FD1FF4DAAA00BFAF1D /* CNLiveMsgTools.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = CNLiveMsgTools.framework; sourceTree = "<group>"; };
149   - D29899931FF4DB4E001CD929 /* CNLiveChatManager.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = CNLiveChatManager.framework; sourceTree = "<group>"; };
  151 + D29899931FF4DB4E001CD929 /* CNLiveChatManager.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CNLiveChatManager.framework; path = /Users/cnlive/Desktop/Group/CNLiveTIMChatSDKDemo/CNLiveChatManagerSDKDemo/CNLiveChatManagerSDKDemo/CNLiveChatManager.framework; sourceTree = "<absolute>"; };
150 152 D2B6C8F91FCE45E300A25DFD /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = System/Library/Frameworks/CoreTelephony.framework; sourceTree = SDKROOT; };
151 153 D2B6C8FB1FCE45ED00A25DFD /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
152 154 D2B6C8FD1FCE45FE00A25DFD /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; };
... ... @@ -167,6 +169,7 @@
167 169 D286252F1FF0C4640074F0E9 /* libstdc++.tbd in Frameworks */,
168 170 D29899941FF4DB4E001CD929 /* CNLiveChatManager.framework in Frameworks */,
169 171 D286252D1FF0C4570074F0E9 /* CoreGraphics.framework in Frameworks */,
  172 + D26F82331FFB2B62009762EE /* CNLiveChatManager.framework in Frameworks */,
170 173 D286252B1FF0C44E0074F0E9 /* CoreMedia.framework in Frameworks */,
171 174 D28625291FF0C4420074F0E9 /* AVFoundation.framework in Frameworks */,
172 175 D2B6C8FA1FCE45E300A25DFD /* CoreTelephony.framework in Frameworks */,
... ... @@ -178,7 +181,7 @@
178 181 D28FF4FE1FF4DAAA00BFAF1D /* CNLiveMsgTools.framework in Frameworks */,
179 182 D2B6C9021FCE461F00A25DFD /* libc++.tbd in Frameworks */,
180 183 D2B6C8FE1FCE45FE00A25DFD /* libsqlite3.tbd in Frameworks */,
181   - D29899951FF4DB52001CD929 /* CNLiveChatManager.framework in Frameworks */,
  184 + D26F82321FFB2B5F009762EE /* CNLiveChatManager.framework in Frameworks */,
182 185 );
183 186 runOnlyForDeploymentPostprocessing = 0;
184 187 };
... ... @@ -284,7 +287,7 @@
284 287 D27212311FCD58F000CB3A2E /* CNLiveChatManagerSDKDemo */ = {
285 288 isa = PBXGroup;
286 289 children = (
287   - D29899931FF4DB4E001CD929 /* CNLiveChatManager.framework */,
  290 + D26F82311FFB2B5F009762EE /* CNLiveChatManager.framework */,
288 291 D28FF4FD1FF4DAAA00BFAF1D /* CNLiveMsgTools.framework */,
289 292 D21B52441FD929C800C91ECA /* SDWebImage */,
290 293 D27212351FCD58F000CB3A2E /* AppDelegate.h */,
... ...
CNLiveChatManagerSDKDemo/CNLiveChatManagerSDKDemo/CNLiveChatManager.framework/CNLiveChatManager
No preview for this file type
CNLiveChatManagerSDKDemo/CNLiveChatManagerSDKDemo/CNLiveChatManager.framework/Headers/CNLiveChatManager.h
... ... @@ -9,11 +9,11 @@
9 9 #import <Foundation/Foundation.h>
10 10 #import "CNLiveChatUserInfo.h"
11 11 #import "CNLiveChatStatusDefine.h"
  12 +#import "CNLiveChatMessageBase.h"
12 13 #import "CNLiveChatMessage.h"
13 14 #import "CNliveChatImageMessage.h"
14 15 #import "CNLiveChatVoiceMessage.h"
15 16 #import "CNLiveChatVideoMessage.h"
16   -#import "CNLiveChatMessageBase.h"
17 17  
18 18 @protocol CNLiveChatManagerDelegate <NSObject>
19 19  
... ... @@ -38,8 +38,6 @@
38 38  
39 39 @param chatroomId 聊天室ID
40 40 @param errorCode 加入失败的错误码
41   -
42   - @discussion 如果错误码是CNLive_KICKED_FROM_CHATROOM或CNLive_CHATROOM_NOT_EXIST,则不会自动重新加入聊天室,App需要按照自己的逻辑处理。
43 41 */
44 42 - (void)onChatRoomJoinFailed:(NSString *)chatroomId
45 43 errorCode:(CNLiveChatErrorCode)errorCode;
... ... @@ -52,6 +50,14 @@
52 50 - (void)onReceived:(CNLiveChatMessageBase *)message;
53 51  
54 52  
  53 +/**
  54 + 发送消息进度监听
  55 +
  56 + @param msg 正在上传的消息
  57 + @param idx 正在上传的消息的索引
  58 + @param taskid 任务id
  59 + @param progress 上传进度
  60 + */
55 61 - (void)onUploadProgressCallback:(CNLiveChatMessageBase*)msg idx:(uint32_t)idx taskid:(uint32_t)taskid progress:(uint32_t)progress;
56 62  
57 63  
... ... @@ -127,7 +133,7 @@
127 133  
128 134  
129 135 /**
130   - 连接到视讯云服务器
  136 + 匿名连接到视讯云服务器
131 137  
132 138 @param successBlock 连接建立成功的回调。
133 139 @param errorBlock 连接建立成功的回调,返回错误码。
... ... @@ -151,6 +157,9 @@
151 157  
152 158 /**
153 159 当前用户登出服务器
  160 +
  161 + @param successBlock 登出成功的回调,返回登陆成功的用户ID。
  162 + @param errorBlock 登出失败的回调,返回错误码。
154 163 */
155 164 - (void)logoutServer:(CNLiveIMSucc)successBlock error:(CNLiveIMFail)errorBlock;
156 165  
... ... @@ -158,16 +167,18 @@
158 167 /**
159 168 断开与服务器的连接
160 169  
  170 + @param successBlock 断开成功的回调,返回登陆成功的用户ID。
  171 + @param errorBlock 断开失败的回调,返回错误码。
161 172 */
162 173 - (void)disconnectServer:(CNLiveIMSucc)successBlock error:(CNLiveIMFail)errorBlock;
163 174  
164 175  
165 176 /**
166   - 加入已经存在的聊天室(如果不存在或超限会返回聊天室不存在错误23410 或 人数超限23411)
  177 + 加入已经存在的聊天室
167 178  
168 179 @param targetId 要加入的聊天室ID
169   - @param messageCount 进入聊天室时获取历史消息的数量,-1<=messageCount<=50
170   - -1表示不获取任何历史消息,0表示不特殊设置而使用SDK默认的设置(默认为获取10条),0<messageCount<=50为具体获取的消息数量,最大值为50。
  180 + @param messageCount 进入聊天室时获取历史消息的数量,-1<=messageCount<=20
  181 + -1表示不获取任何历史消息,0表示不特殊设置而使用SDK默认的设置(默认为获取10条),0<messageCount<=20为具体获取的消息数量,最大值为20。
171 182 @param successBlock 加入聊天室成功的回调,返回成功加入的聊天室ID。
172 183 @param errorBlock 加入聊天室失败的回调,返回错误码以及加入失败的聊天室ID。
173 184 */
... ... @@ -181,8 +192,8 @@
181 192 加入聊天室,若不存在自动创建聊天室
182 193  
183 194 @param targetId 要加入的聊天室ID
184   - @param messageCount 进入聊天室时获取历史消息的数量,-1<=messageCount<=50
185   - -1表示不获取任何历史消息,0表示不特殊设置而使用SDK默认的设置(默认为获取10条),0<messageCount<=50为具体获取的消息数量,最大值为50。
  195 + @param messageCount 进入聊天室时获取历史消息的数量,-1<=messageCount<=20
  196 + -1表示不获取任何历史消息,0表示不特殊设置而使用SDK默认的设置(默认为获取10条),0<messageCount<=20为具体获取的消息数量,最大值为20。
186 197 @param successBlock 加入聊天室成功的回调,返回成功加入的聊天室ID
187 198 @param errorBlock 加入聊天室失败的回调,返回错误码以及加入失败的聊天室ID
188 199 */
... ... @@ -205,7 +216,7 @@
205 216  
206 217  
207 218 /**
208   - 发送文本或语音消息
  219 + 发送文本消息
209 220  
210 221 @param message 消息内容(文本消息 CNLiveChatMessage)
211 222 @param type 会话类型(私聊 / 聊天室)
... ... @@ -278,14 +289,14 @@
278 289  
279 290  
280 291 /**
281   - 获取某个会话中指定数量的最新消息(私聊有效)
  292 + 获取某个会话中指定数量的最新消息
282 293  
283   - @param conversationType 会话类型(私聊)
284   - @param targetId 会话目标ID(私聊:用户ID)
  294 + @param conversationType 会话类型(私聊 / 聊天室)
  295 + @param targetId 会话目标ID(私聊:用户ID / 聊天室:聊天室ID)
285 296 @param count 所要获取的消息数量
286 297  
287 298 @param successBlock 成功回调返回消息体
288   - (包括 CNLiveChatMessage文本类型 / CNliveChatImageMessage图片类型 / CNLiveChatVoiceMessage语音类型)
  299 + (包括 CNLiveChatMessage文本类型 / CNliveChatImageMessage图片类型 / CNLiveChatVoiceMessage语音类型 /CNLiveChatVideoMessage视频类型)
289 300 @param errorBlock 失败回调返回错误码
290 301 @discussion
291 302 此方法会获取该会话中指定数量的最新消息实体,返回的消息实体按照时间从新到旧排列。
... ...
CNLiveChatManagerSDKDemo/CNLiveChatManagerSDKDemo/CNLiveChatManager.framework/Headers/CNLiveChatMessageBase.h
... ... @@ -7,7 +7,9 @@
7 7 //
8 8  
9 9 #import <Foundation/Foundation.h>
10   -
  10 +/**
  11 + * 消息基类
  12 + */
11 13 @interface CNLiveChatMessageBase : NSObject
12 14  
13 15 @end
... ...
CNLiveChatManagerSDKDemo/CNLiveChatManagerSDKDemo/CNLiveChatManager.framework/Headers/CNLiveChatUserInfo.h
... ... @@ -12,7 +12,7 @@
12 12  
13 13 /*!
14 14 用户ID(一旦以一个用户ID连接到服务器,就不能再修改用户ID了,如果修改也会被忽略)
15   - 用户Id,最大长度 64 字节。是用户在 App 中的唯一标识码,必须保证在同一个 App 内不重复,重复的用户 Id 将被当作是同一用户。(必传)
  15 + 用户Id 长,度建议不超过 32 字节 。是用户在 App 中的唯一标识码,必须保证在同一个 App 内不重复,重复的用户 Id 将被当作是同一用户。(必传)
16 16 */
17 17 @property(nonatomic, copy, readonly) NSString *userId;
18 18  
... ...
CNLiveChatManagerSDKDemo/CNLiveChatManagerSDKDemo/CNLiveChatManager.framework/Headers/CNLiveChatVideoMessage.h
... ... @@ -79,7 +79,9 @@
79 79 */
80 80 @property(nonatomic,assign) int coverSize;
81 81  
82   -
  82 +/**
  83 + * 消息所属用户的Id
  84 + */
83 85 @property(nonatomic, copy) NSString *selfIdentifier;
84 86  
85 87 /**
... ...
CNLiveChatManagerSDKDemo/CNLiveChatManagerSDKDemo/CNLiveChatManager.framework/Headers/CNLiveChatVoiceMessage.h
... ... @@ -38,10 +38,16 @@
38 38 */
39 39 @property(nonatomic,retain) NSString * uuid;
40 40  
41   -@property(nonatomic,assign) int businessId;
42   -
  41 +/**
  42 + * 消息所属用户的Id
  43 + */
43 44 @property(nonatomic, copy) NSString *selfIdentifier;
44 45  
  46 +/**
  47 + * 以下3个为语音消息内部属性,开发者不必理会
  48 + */
  49 +@property(nonatomic,assign) int businessId;
  50 +
45 51 @property(nonatomic,assign) int downloadFlag;
46 52  
47 53 @property(nonatomic,strong) NSArray *soundUrls;
... ...
CNLiveChatManagerSDKDemo/CNLiveChatManagerSDKDemo/CNLiveChatManager.framework/Headers/CNliveChatImageMessage.h
... ... @@ -30,7 +30,9 @@
30 30 */
31 31 @property(nonatomic,assign) uint32_t taskId;
32 32  
33   -
  33 +/**
  34 + * 消息所属用户的Id
  35 + */
34 36 @property(nonatomic, copy) NSString *selfIdentifier;
35 37  
36 38 /**
... ...
CNLiveChatManagerSDKDemo/CNLiveChatManagerSDKDemo/ChatRoomViewController.m
... ... @@ -891,35 +891,6 @@ static NSString *videoCellId = @&quot;videoCellId&quot;;
891 891 return _videoButton;
892 892 }
893 893  
894   -//- (void)login:(UIButton *)btn {
895   -//
896   -// btn.selected = !btn.selected;
897   -//
898   -// if (btn.selected) {
899   -//
900   -// CNLiveChatUserInfo *userInfo = [[CNLiveChatUserInfo alloc] initWithUserId:@"20171214" name:@"回家" portrait:@""];
901   -// [[CNLiveChatManager sharedCNLiveChatManager] loginServer:userInfo success:^(NSString *userId) {
902   -//
903   -// NSLog(@"用户:%@ 已成功登陆",userId);
904   -// [CNLiveChatManager sharedCNLiveChatManager].currentUserInfo.name = @"XCode9"; // 更改昵称
905   -//
906   -// } error:^(CNLiveChatConnectErrorCode errors) {
907   -//
908   -// NSLog(@"登陆失败,错误码为:%ld",(long)errors);
909   -// }];
910   -// } else {
911   -//
912   -// [[CNLiveChatManager sharedCNLiveChatManager] connectServerSuccess:^{
913   -//
914   -// NSLog(@"用户:%@ 已成功登陆",[CNLiveChatManager sharedCNLiveChatManager].currentUserInfo.userId);
915   -//
916   -// } error:^(CNLiveChatConnectErrorCode errors) {
917   -//
918   -// NSLog(@"登陆失败,错误码为:%ld",(long)errors);
919   -// }];
920   -// }
921   -//}
922   -
923 894 - (UIButton *)voiceButton {
924 895 if (!_voiceButton) {
925 896 _voiceButton = [UIButton buttonWithType:UIButtonTypeCustom];
... ...
CNLiveChatManagerSDKDemo/CNLiveChatManagerSDKDemo/PrivateViewController.m
... ... @@ -7,12 +7,14 @@
7 7 //
8 8  
9 9 #import "PrivateViewController.h"
  10 +#import <MobileCoreServices/MobileCoreServices.h>
10 11  
11   -#define privateUserId @"170718"
  12 +#define privateUserId @"171229"
12 13  
13 14 static NSString *textCellId = @"textCellId";
14 15 static NSString *voiceCellId = @"voiceCellId";
15 16 static NSString *imageCellId = @"imageCellId";
  17 +static NSString *videoCellId = @"videoCellId";
16 18  
17 19 @interface PrivateViewController ()<UITextFieldDelegate, CNLiveChatManagerDelegate, UITableViewDelegate, UITableViewDataSource, AVAudioPlayerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate> {
18 20  
... ... @@ -44,6 +46,8 @@ static NSString *imageCellId = @&quot;imageCellId&quot;;
44 46  
45 47 @property (nonatomic, strong) AVAudioPlayer *player;
46 48  
  49 +@property (nonatomic, assign) int suffix;
  50 +
47 51 @end
48 52  
49 53 @implementation PrivateViewController
... ... @@ -96,57 +100,88 @@ static NSString *imageCellId = @&quot;imageCellId&quot;;
96 100 - (void)getPrivateChattingRecords {
97 101  
98 102 // 获取最新消息
99   - //***************
100   - NSArray *messageArray = nil;//[[CNLiveChatManager sharedCNLiveChatManager] getLatestMessages:CNLive_ConversationType_PRIVATE targetId:privateUserId count:20];
101   -
102   -
103   - for (id message in messageArray) {
104   -
105   - if ([message isKindOfClass:[CNLiveChatMessage class]]) {
  103 + [[CNLiveChatManager sharedCNLiveChatManager] getLatestMessages:CNLive_ConversationType_PRIVATE targetId:privateUserId count:20 successBlock:^(NSArray *msgs) {
106 104  
107   - CNLiveChatMessage *textMsg = (CNLiveChatMessage *)message;
108   - MessageModel *model = [[MessageModel alloc] init];
109   - model.message = textMsg.messageContent;
110   - model.userId = textMsg.userInfo.userId;
111   - model.name = textMsg.userInfo.name;
112   - model.portraitUri = textMsg.userInfo.portraitUri;
113   - model.type = textMsg.conversationType;
114   - if (![_messageArrayM containsObject:model]) {
115   - [_messageArrayM insertObject:model atIndex:0];
116   - }
117   -
118   - } else if ([message isKindOfClass:[CNliveChatImageMessage class]]) {
119   -
120   - CNliveChatImageMessage *imageMsg = (CNliveChatImageMessage *)message;
121   - MessageModel *model = [[MessageModel alloc] init];
122   - model.imageUrl = imageMsg.imageUrl;
123   - model.thumbnailImage = imageMsg.thumbnailImage;
124   - model.originalImage = imageMsg.originalImage;
125   - model.userId = imageMsg.userInfo.userId;
126   - model.name = imageMsg.userInfo.name;
127   - model.portraitUri = imageMsg.userInfo.portraitUri;
128   - model.type = imageMsg.conversationType;
129   - if (![_messageArrayM containsObject:model]) {
130   - [_messageArrayM insertObject:model atIndex:0];
131   - }
  105 + for (CNLiveChatMessageBase *message in msgs) {
132 106  
133   - } else if ([message isKindOfClass:[CNLiveChatVoiceMessage class]]) {
134   -
135   - CNLiveChatVoiceMessage *voiceMsg = (CNLiveChatVoiceMessage *)message;
136   - MessageModel *model = [[MessageModel alloc] init];
137   - model.duration = voiceMsg.duration;
138   - model.targetId = voiceMsg.targetId;
139   - model.userId = voiceMsg.userInfo.userId;
140   - model.name = voiceMsg.userInfo.name;
141   - model.portraitUri = voiceMsg.userInfo.portraitUri;
142   - model.type = voiceMsg.conversationType;
143   - if (![_messageArrayM containsObject:model]) {
144   - [_messageArrayM insertObject:model atIndex:0];
  107 + if ([message isKindOfClass:[CNLiveChatMessage class]]) {
  108 +
  109 + CNLiveChatMessage * msg = (CNLiveChatMessage *)message;
  110 + // 只显示本聊天室信息
  111 + if (msg.conversationType == CNLive_ConversationType_PRIVATE && [msg.targetId isEqualToString:privateUserId]) {
  112 +
  113 + [_messageArrayM addObject:msg];
  114 + }
  115 + } else if ([message isKindOfClass:[CNliveChatImageMessage class]]) {
  116 +
  117 + CNliveChatImageMessage * msg = (CNliveChatImageMessage *)message;
  118 +
  119 + int progress = [msg getUploadingProgress];
  120 + NSLog(@"%d",progress);
  121 +
  122 + // NSString *filePath = [self getTempPathType:1];
  123 + // [msg getOriginImage:filePath succ:^{
  124 + // NSLog(@"Succ");
  125 + // } fail:^(int code, NSString *msg) {
  126 + // NSLog(@"Fail");
  127 + // }];
  128 +
  129 + // [msg getThumbImage:filePath succ:^{
  130 + //
  131 + // } fail:^(int code, NSString *msg) {
  132 + //
  133 + // }];
  134 +
  135 + if (msg.conversationType == CNLive_ConversationType_PRIVATE && [msg.targetId isEqualToString:privateUserId]) {
  136 +
  137 + [_messageArrayM addObject:msg];
  138 + }
  139 +
  140 + } else if ([message isKindOfClass:[CNLiveChatVoiceMessage class]]) {
  141 + CNLiveChatVoiceMessage * msg = (CNLiveChatVoiceMessage *)message;
  142 +
  143 + // [msg getUploadingProgress]; // *************
  144 +
  145 + // NSString *filePath = [self getTempPathType:2];
  146 + // [msg getSound:filePath succ:^{
  147 + //
  148 + // } fail:^(int code, NSString *msg) {
  149 + //
  150 + // }];
  151 +
  152 + if (msg.conversationType == CNLive_ConversationType_PRIVATE && [msg.targetId isEqualToString:privateUserId]) {
  153 +
  154 + [_messageArrayM addObject:msg];
  155 + }
  156 + } else if ([message isKindOfClass:[CNLiveChatVideoMessage class]]) {
  157 + CNLiveChatVideoMessage * msg = (CNLiveChatVideoMessage *)message;
  158 +
  159 + // NSString *filePath = [self getTempPathType:3];//*************************************
  160 + // [msg getVideo:filePath succ:^{
  161 + //
  162 + // } fail:^(int code, NSString *msg) {
  163 + //
  164 + // }];
  165 +
  166 + // [msg getImage:filePath succ:^{
  167 + //
  168 + // } fail:^(int code, NSString *msg) {
  169 + //
  170 + // }];
  171 +
  172 + if (msg.conversationType == CNLive_ConversationType_PRIVATE && [msg.targetId isEqualToString:privateUserId]) {
  173 +
  174 + [_messageArrayM addObject:msg];
  175 + }
145 176 }
  177 + [self.tableView reloadData];
  178 + [self scrollToBottom];
146 179 }
147   - [self.tableView reloadData];
148   - [self scrollToBottom];
149   - }
  180 +
  181 + } errorBlock:^(int code, NSString *msg) {
  182 +
  183 + NSLog(@"获取历史消息失败");
  184 + }];
150 185 }
151 186  
152 187 #pragma mark - UITableViewDelegate,UITableViewDataSource !!!!!!!!!!!!!!!!!!!!!!!!!!
... ... @@ -157,79 +192,83 @@ static NSString *imageCellId = @&quot;imageCellId&quot;;
157 192  
158 193 - (id)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
159 194  
160   - MessageModel *model = _messageArrayM[indexPath.row];
  195 + CNLiveChatMessageBase *message = _messageArrayM[indexPath.row];
161 196  
162   - if (model.message) { // 文本消息
  197 + if ([message isKindOfClass:[CNLiveChatMessage class]]) { // 文本消息
  198 + CNLiveChatMessage *msg = (CNLiveChatMessage *)message;
163 199 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:textCellId forIndexPath:indexPath];
164   - NSMutableAttributedString *AttributedStr = [[NSMutableAttributedString alloc]initWithString:[NSString stringWithFormat:@"%@: %@",model.name,model.message]];
  200 + NSMutableAttributedString *AttributedStr = [[NSMutableAttributedString alloc]initWithString:[NSString stringWithFormat:@"%@: %@",msg.userInfo.name,msg.messageContent]];
165 201  
166   - if ([model.userId isEqualToString:[CNLiveChatManager sharedCNLiveChatManager].currentUserInfo.userId]) {
  202 + if ([msg.userInfo.userId isEqualToString:[CNLiveChatManager sharedCNLiveChatManager].currentUserInfo.userId]) {
167 203 [AttributedStr addAttribute:NSForegroundColorAttributeName
168 204 value:[UIColor redColor]
169   - range:NSMakeRange(0, model.name.length)];
  205 + range:NSMakeRange(0, msg.userInfo.name.length)];
170 206 cell.textLabel.attributedText = AttributedStr;
171 207 } else {
172 208 [AttributedStr addAttribute:NSForegroundColorAttributeName
173 209 value:[UIColor blackColor]
174   - range:NSMakeRange(0, model.name.length)];
  210 + range:NSMakeRange(0, msg.userInfo.name.length)];
175 211 cell.textLabel.attributedText = AttributedStr;
176 212 }
177 213 return cell;
178 214  
179   - } else if (model.wavAudioData) { // 语音消息
  215 + } else if ([message isKindOfClass:[CNLiveChatVoiceMessage class]]) { // 语音消息
180 216  
181 217 CNLiveVoiceTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:voiceCellId forIndexPath:indexPath];
182 218 [cell.voicePlayBtn addTarget:self action:@selector(voicePlay:) forControlEvents:UIControlEventTouchUpInside];
183 219 cell.indexPath = indexPath;
184 220 return cell;
185   - } else if (model.wavAudioData || model.thumbnailImage) { // 图片消息
  221 + } else if ([message isKindOfClass:[CNliveChatImageMessage class]]) {
186 222  
  223 + CNliveChatImageMessage *msg = (CNliveChatImageMessage *)message;
187 224 CNLiveImageTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:imageCellId forIndexPath:indexPath];
188   -// cell.model = model;
  225 + cell.message = msg;
  226 + return cell;
  227 + } else if ([message isKindOfClass:[CNLiveChatVideoMessage class]]) {
  228 +
  229 + CNLiveChatVideoMessage *msg = (CNLiveChatVideoMessage *)message;
  230 + CNLiveVideoTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:videoCellId forIndexPath:indexPath];
  231 + cell.videoMsg = msg;
  232 + return cell;
  233 + } else {
  234 +
  235 + UITableViewCell *cell = [[UITableViewCell alloc] init];
189 236 return cell;
190 237 }
191   - return nil;
192 238 }
193 239  
194 240 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
195 241  
196   - MessageModel *model = _messageArrayM[indexPath.row];
197   - if (model.wavAudioData) {
  242 + CNLiveChatMessageBase *message = _messageArrayM[indexPath.row];
  243 + if ([message isKindOfClass:[CNLiveChatVoiceMessage class]]) {
198 244 return 50;
199   - } else if (model.imageUrl || model.thumbnailImage) {
  245 + } else if ([message isKindOfClass:[CNliveChatImageMessage class]]) {
200 246 return 100;
  247 + } else if ([message isKindOfClass:[CNLiveChatVideoMessage class]])
  248 + {
  249 + return 120;
201 250 }
202 251 return 30;
203 252 }
204 253  
205   -#pragma mark - UITextFieldDelegate !!!!!!!!!!!!!!!!!!!!!!!!!!
206   -- (BOOL)textFieldShouldReturn:(UITextField *)textField { // 发送文本消息
  254 +#pragma mark - 文字发送 UITextFieldDelegate !!!!!!!!!!!!!!!!!!!!!!!!!!
  255 +- (BOOL)textFieldShouldReturn:(UITextField *)textField { // 发送消息
207 256  
208   - [[CNLiveChatManager sharedCNLiveChatManager] sendMessage:textField.text type:CNLive_ConversationType_PRIVATE targetId:privateUserId success:^(id message) {
  257 + [[CNLiveChatManager sharedCNLiveChatManager] sendMessage:textField.text type:CNLive_ConversationType_PRIVATE targetId:privateUserId success:^(CNLiveChatMessage *message) {
209 258  
210 259 // 自己发送的消息不会被onReceived:方法实时监听,需要自己做处理
211   - if ([message isKindOfClass:[CNLiveChatMessage class]]) {
212   -
213   - CNLiveChatMessage *textMsg = message;
214   - NSLog(@"文本消息发送成功:%@",textMsg.messageContent);
215   - MessageModel *model = [[MessageModel alloc] init];
216   - model.message = textMsg.messageContent;
217   - model.userId = textMsg.userInfo.userId;
218   - model.name = textMsg.userInfo.name;
219   - model.portraitUri = textMsg.userInfo.portraitUri;
220   - model.type = textMsg.conversationType;
221   - model.messageId = textMsg.messageId;
222   - [_messageArrayM addObject:model];
223   -
224   - // 此处更新 UI 应到主线程
225   - dispatch_async(dispatch_get_main_queue(), ^{
226   - [self.tableView reloadData];
227   - [self scrollToBottom];
228   - });
229   - }
  260 + NSLog(@"文本消息发送成功:%@",message.messageContent);
  261 +
  262 + [_messageArrayM addObject:message];
  263 +
  264 + // 此处更新 UI 应到主线程
  265 + dispatch_async(dispatch_get_main_queue(), ^{
  266 + [self.tableView reloadData];
  267 + [self scrollToBottom];
  268 + });
230 269  
231 270 } error:^(CNLiveChatErrorCode errors, NSString *errorMsg) {
232   - NSLog(@"发送文本消息失败,错误代码:%ld",(long)errors);
  271 + NSLog(@"向用户:%@发送文本消息失败,错误代码:%ld,错误信息:%@",privateUserId,(long)errors,errorMsg);
233 272 }];
234 273  
235 274 textField.text = @"";
... ... @@ -238,46 +277,77 @@ static NSString *imageCellId = @&quot;imageCellId&quot;;
238 277  
239 278  
240 279 #pragma mark - CNLiveChatManagerDelegate !!!!!!!!!!!!!!!!!!!!!!!!!!
241   -- (void)onReceived:(id)message {
  280 +- (void)onReceived:(CNLiveChatMessageBase *)message {
242 281  
243 282 if ([message isKindOfClass:[CNLiveChatMessage class]]) {
244 283  
245 284 CNLiveChatMessage * msg = (CNLiveChatMessage *)message;
  285 + // 只显示本聊天室信息
  286 + if (msg.conversationType == CNLive_ConversationType_PRIVATE && [msg.targetId isEqualToString:privateUserId]) {
246 287  
247   - MessageModel *model = [[MessageModel alloc] init];
248   - model.message = msg.messageContent;
249   - model.userId = msg.userInfo.userId;
250   - model.name = msg.userInfo.name;
251   - model.portraitUri = msg.userInfo.portraitUri;
252   - model.type = msg.conversationType;
253   - [_messageArrayM addObject:model];
254   -
  288 + [_messageArrayM addObject:msg];
  289 + }
255 290 } else if ([message isKindOfClass:[CNliveChatImageMessage class]]) {
256 291  
257 292 CNliveChatImageMessage * msg = (CNliveChatImageMessage *)message;
  293 +
  294 + int progress = [msg getUploadingProgress];
  295 + NSLog(@"%d",progress);
  296 +
  297 + // NSString *filePath = [self getTempPathType:1];
  298 + // [msg getOriginImage:filePath succ:^{
  299 + // NSLog(@"Succ");
  300 + // } fail:^(int code, NSString *msg) {
  301 + // NSLog(@"Fail");
  302 + // }];
  303 +
  304 + // [msg getThumbImage:filePath succ:^{
  305 + //
  306 + // } fail:^(int code, NSString *msg) {
  307 + //
  308 + // }];
  309 +
  310 + if (msg.conversationType == CNLive_ConversationType_PRIVATE && [msg.targetId isEqualToString:privateUserId]) {
258 311  
259   - MessageModel *model = [[MessageModel alloc] init];
260   - model.imageUrl = msg.imageUrl;
261   - model.thumbnailImage = msg.thumbnailImage;
262   - model.originalImage = msg.originalImage;
263   - model.userId = msg.userInfo.userId;
264   - model.name = msg.userInfo.name;
265   - model.portraitUri = msg.userInfo.portraitUri;
266   - model.type = msg.conversationType;
267   - [_messageArrayM addObject:model];
  312 + [_messageArrayM addObject:msg];
  313 + }
268 314  
269 315 } else if ([message isKindOfClass:[CNLiveChatVoiceMessage class]]) {
270   -
271 316 CNLiveChatVoiceMessage * msg = (CNLiveChatVoiceMessage *)message;
  317 +
  318 + // [msg getUploadingProgress]; // *************
  319 +
  320 + // NSString *filePath = [self getTempPathType:2];
  321 + // [msg getSound:filePath succ:^{
  322 + //
  323 + // } fail:^(int code, NSString *msg) {
  324 + //
  325 + // }];
  326 +
  327 + if (msg.conversationType == CNLive_ConversationType_PRIVATE && [msg.targetId isEqualToString:privateUserId]) {
272 328  
273   - MessageModel *model = [[MessageModel alloc] init];
274   - model.duration = msg.duration;
275   - model.targetId = msg.targetId;
276   - model.userId = msg.userInfo.userId;
277   - model.name = msg.userInfo.name;
278   - model.portraitUri = msg.userInfo.portraitUri;
279   - model.type = msg.conversationType;
280   - [_messageArrayM addObject:model];
  329 + [_messageArrayM addObject:msg];
  330 + }
  331 + } else if ([message isKindOfClass:[CNLiveChatVideoMessage class]]) {
  332 + CNLiveChatVideoMessage * msg = (CNLiveChatVideoMessage *)message;
  333 +
  334 + // NSString *filePath = [self getTempPathType:3];//*************************************
  335 + // [msg getVideo:filePath succ:^{
  336 + //
  337 + // } fail:^(int code, NSString *msg) {
  338 + //
  339 + // }];
  340 +
  341 + // [msg getImage:filePath succ:^{
  342 + //
  343 + // } fail:^(int code, NSString *msg) {
  344 + //
  345 + // }];
  346 +
  347 + if (msg.conversationType == CNLive_ConversationType_PRIVATE && [msg.targetId isEqualToString:privateUserId]) {
  348 +
  349 + [_messageArrayM addObject:msg];
  350 + }
281 351 }
282 352 [self.tableView reloadData];
283 353 [self scrollToBottom];
... ... @@ -296,60 +366,286 @@ static NSString *imageCellId = @&quot;imageCellId&quot;;
296 366 }
297 367  
298 368 #pragma mark - 图片 Button Action !!!!!!!!!!!!!!!!!!!!!!!!
299   -- (void)getImageFromIpc
300   -{
301   - // 1.判断相册是否可以打开
302   - if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) return;
303   - // 2. 创建图片选择控制器
304   - UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
305   - /**
306   - typedef NS_ENUM(NSInteger, UIImagePickerControllerSourceType) {
307   - UIImagePickerControllerSourceTypePhotoLibrary, // 相册
308   - UIImagePickerControllerSourceTypeCamera, // 用相机拍摄获取
309   - UIImagePickerControllerSourceTypeSavedPhotosAlbum // 相簿
310   - }
311   - */
312   - // 3. 设置打开照片相册类型(显示所有相簿)
313   - ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
314   - // ipc.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
315   - // ipc.sourceType = UIImagePickerControllerSourceTypeCamera;
316   -
317   - ipc.delegate = self;
318   -
319   - [self presentViewController:ipc animated:YES completion:nil];
  369 +- (void)getVideoFromIpc {
  370 +
  371 + if ([[AVCaptureDevice class] respondsToSelector:@selector(authorizationStatusForMediaType:)])
  372 + {
  373 + AVAuthorizationStatus videoStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
  374 + if (videoStatus == AVAuthorizationStatusRestricted || videoStatus == AVAuthorizationStatusDenied)
  375 + {
  376 + // 没有权限
  377 + NSLog(@"没有相机权限");
  378 + return;
  379 + }
  380 +
  381 + AVAuthorizationStatus audioStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
  382 + if (audioStatus == AVAuthorizationStatusRestricted || audioStatus == AVAuthorizationStatusDenied)
  383 + {
  384 + // 没有权限
  385 + NSLog(@"没有麦克风权限");
  386 + return;
  387 + }
  388 + __weak typeof(self) wself = self;
  389 + if (videoStatus == AVAuthorizationStatusNotDetermined)
  390 + {
  391 + //请求相机权限
  392 + [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted){
  393 +
  394 +
  395 + if(granted)
  396 + {
  397 + AVAuthorizationStatus audio = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
  398 + if (audio == AVAuthorizationStatusNotDetermined)
  399 + {
  400 + //请求麦克风权限
  401 + [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted){
  402 + dispatch_async(dispatch_get_main_queue(), ^{
  403 + if (granted)
  404 + {
  405 + [wself addMicroVideoView];
  406 + }
  407 + });
  408 + }];
  409 + }
  410 + else//这里一定是有麦克风权限了
  411 + {
  412 + dispatch_async(dispatch_get_main_queue(), ^{
  413 + [wself addMicroVideoView];
  414 + });
  415 + }
  416 + }
  417 +
  418 + }];
  419 + }
  420 + else//这里一定是有相机权限了
  421 + {
  422 + if (audioStatus == AVAuthorizationStatusNotDetermined)
  423 + {
  424 + //请求麦克风权限
  425 + [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted){
  426 +
  427 + dispatch_async(dispatch_get_main_queue(), ^{
  428 + if (granted)
  429 + {
  430 + [wself addMicroVideoView];
  431 + }
  432 + });
  433 +
  434 + }];
  435 + }
  436 + else//这里一定是有麦克风权限了
  437 + {
  438 + [wself addMicroVideoView];
  439 + }
  440 +
  441 + }
  442 + }
  443 +}
  444 +
  445 +- (void)addMicroVideoView {
  446 +
  447 + UIImagePickerController *camera = [UIImagePickerController new];
  448 + camera.sourceType = UIImagePickerControllerSourceTypeCamera;
  449 + camera.mediaTypes = @[(NSString *)kUTTypeMovie];
  450 + camera.videoMaximumDuration = 20;
  451 + camera.delegate = self;
  452 + [self presentViewController:camera animated:YES completion:nil];
320 453 }
321 454  
322 455 #pragma mark -- <UIImagePickerControllerDelegate>--
323 456 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info { // 获取图片后的操作
324 457  
  458 + NSString *mediaType = info[UIImagePickerControllerMediaType];
  459 + if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
  460 +
  461 + // 设置图片
  462 + UIImage *img = info[UIImagePickerControllerOriginalImage];
  463 + [self sendImage:img];
  464 + }
  465 + else if([mediaType isEqualToString:(NSString*)kUTTypeMovie]) {
  466 +
  467 + // 视频
  468 + NSURL *sourceURL = info[UIImagePickerControllerMediaURL];
  469 + NSDictionary *infoDict = [self getVideoInfoWithSourcePath:[sourceURL path]];
  470 +
  471 + if ([infoDict[@"duration"] integerValue] < 5) {
  472 + NSLog(@"录制时间太短");
  473 + } else {
  474 +
  475 + [self saveVideoAsMP4:[sourceURL path] success:^(NSString *exportPath) {
  476 +
  477 + NSError *err = nil;
  478 + NSData* data = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:[sourceURL path]] options:NSDataReadingMappedIfSafe error:&err];
  479 + //文件最大不超过28MB
  480 + if(data.length < 28 * 1024 * 1024)
  481 + {
  482 + [self sendVideoMsg:exportPath];
  483 + }
  484 + else
  485 + {
  486 + NSLog(@"发送的文件过大");
  487 + }
  488 +
  489 + } fail:^{
  490 +
  491 + }];
  492 + }
  493 + }
325 494 [picker dismissViewControllerAnimated:YES completion:nil];
  495 +}
  496 +
  497 +#pragma mark -
  498 +#pragma mark - 发送视频 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  499 +- (void)sendVideoMsg:(NSString *)videoPath {
  500 +
  501 + //视频截图
  502 + AVURLAsset *urlAsset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:videoPath] options:nil];
  503 + AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:urlAsset];
  504 + imageGenerator.appliesPreferredTrackTransform = YES; // 截图的时候调整到正确的方向
  505 + CMTime time = CMTimeMakeWithSeconds(1.0, 30); // 1.0为截取视频1.0秒处的图片,30为每秒30帧
  506 + CGImageRef cgImage = [imageGenerator copyCGImageAtTime:time actualTime:nil error:nil];
  507 + UIImage *image = [UIImage imageWithCGImage:cgImage];
  508 +
  509 + UIGraphicsBeginImageContext(CGSizeMake(240, 320));
  510 + // 绘制改变大小的图片
  511 + [image drawInRect:CGRectMake(0,0, 240, 320)];
  512 + // 从当前context中创建一个改变大小后的图片
  513 + UIImage* scaledImage =UIGraphicsGetImageFromCurrentImageContext();
  514 + // 使当前的context出堆栈
  515 + UIGraphicsEndImageContext();
  516 + NSData *snapshotData = UIImageJPEGRepresentation(scaledImage, 0.75);
  517 +
  518 + //保存截图到临时目录
  519 + NSString *tempDir = NSTemporaryDirectory();
  520 + NSString *snapshotPath = [NSString stringWithFormat:@"%@uploadSnapshot%d%3.f", tempDir, self.suffix,[NSDate timeIntervalSinceReferenceDate]];
  521 + self.suffix++;
326 522  
327   - // 设置图片
328   - UIImage *img = info[UIImagePickerControllerOriginalImage];
329   - [self sendImage:img];
  523 + NSError *err;
  524 + NSFileManager *fileMgr = [NSFileManager defaultManager];
  525 +
  526 + if (![fileMgr createFileAtPath:snapshotPath contents:snapshotData attributes:nil])
  527 + {
  528 + NSLog(@"Upload Video Failed: fail to create uploadfile: %@", err);
  529 + return ;
  530 + }
  531 +
  532 + CNLiveChatVideoMessage *videoMsg = [[CNLiveChatVideoMessage alloc] init];
  533 + videoMsg.type = @"mp4";
  534 + videoMsg.duration = (int)urlAsset.duration.value/urlAsset.duration.timescale;
  535 + videoMsg.coverType = @"jpg";
  536 + videoMsg.width = scaledImage.size.width;
  537 + videoMsg.height = scaledImage.size.height;
  538 + videoMsg.videoPath = videoPath;
  539 + videoMsg.coverPath = snapshotPath;
  540 + [[CNLiveChatManager sharedCNLiveChatManager] sendVideoMessage:CNLive_ConversationType_PRIVATE targetId:privateUserId content:videoMsg proBlock:^(CNLiveChatVideoMessage *message) {
  541 +
  542 + } success:^(CNLiveChatVideoMessage *message) {
  543 +
  544 + [_messageArrayM addObject:message];
  545 +
  546 + // 此处更新 UI 应到主线程
  547 + dispatch_async(dispatch_get_main_queue(), ^{
  548 + [self.tableView reloadData];
  549 + [self scrollToBottom];
  550 + });
  551 +
  552 + } error:^(CNLiveChatErrorCode errorCode, NSString *messageId) {
  553 +
  554 + NSLog(@"Fail");
  555 + }];
330 556 }
331 557  
  558 +- (void)saveVideoAsMP4:(NSString *)path success:(void(^)(NSString *exportPath))successBlock fail:(void(^)())fail {
  559 +
  560 + AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:path] options:nil];
  561 + NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
  562 +
  563 + if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality])
  564 +
  565 + {
  566 + AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetPassthrough];
  567 + NSString *exportPath = [NSString stringWithFormat:@"%@%d%3.f.mp4",NSTemporaryDirectory(),self.suffix,[NSDate timeIntervalSinceReferenceDate]];
  568 + self.suffix++;
  569 + exportSession.outputURL = [NSURL fileURLWithPath:exportPath];
  570 + NSLog(@"%@", exportPath);
  571 + exportSession.outputFileType = AVFileTypeMPEG4;
  572 + [exportSession exportAsynchronouslyWithCompletionHandler:^{
  573 +
  574 + if (exportSession.status == AVAssetExportSessionStatusCompleted) {
  575 + NSLog(@"转换成功");
  576 + if (successBlock) {
  577 + successBlock(exportPath);
  578 + }
  579 + } else {
  580 + if (fail) {
  581 + fail();
  582 + }
  583 + }
  584 +
  585 + }];
  586 + } else {
  587 + if (fail) {
  588 + fail();
  589 + }
  590 + }
  591 +}
  592 +
  593 +- (NSDictionary *)getVideoInfoWithSourcePath:(NSString *)path{
  594 + AVURLAsset * asset = [AVURLAsset assetWithURL:[NSURL fileURLWithPath:path]];
  595 + CMTime time = [asset duration];
  596 + int seconds = ceil(time.value/time.timescale);
  597 +
  598 + NSInteger fileSize = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil].fileSize;
  599 +
  600 + return @{@"size" : @(fileSize),
  601 + @"duration" : @(seconds)};
  602 +}
  603 +
  604 +#pragma mark -
  605 +#pragma mark - 图片 发送 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
332 606 - (void)sendImage:(UIImage *)image {
333 607  
  608 + NSData *data = UIImagePNGRepresentation(image);
  609 + if(data.length > 28 * 1024 * 1024)
  610 + {
  611 + NSLog(@"发送的文件过大");
  612 + return;
  613 + }
  614 +
  615 + NSFileManager *fileManager = [NSFileManager defaultManager];
  616 + NSString *nsTmpDIr = NSTemporaryDirectory();
  617 + NSString *filePath = [NSString stringWithFormat:@"%@uploadImage%d%3.f", nsTmpDIr, self.suffix, [NSDate timeIntervalSinceReferenceDate]];
  618 + self.suffix++;
  619 + BOOL isDirectory = NO;
  620 + NSError *err = nil;
  621 +
  622 + // 当前sdk仅支持文件路径上传图片,将图片存在本地临时目录下
  623 + if ([fileManager fileExistsAtPath:filePath isDirectory:&isDirectory])
  624 + {
  625 + if (![fileManager removeItemAtPath:nsTmpDIr error:&err])
  626 + {
  627 + NSLog(@"Upload Image Failed: same upload filename: %@", err);
  628 + return ;
  629 + }
  630 + }
  631 + if (![fileManager createFileAtPath:filePath contents:UIImageJPEGRepresentation(image, 1) attributes:nil])
  632 + {
  633 + NSLog(@"Upload Image Failed: fail to create uploadfile: %@", err);
  634 + return ;
  635 + }
  636 +
334 637 // NSString *path = [[NSBundle mainBundle] pathForResource:@"tu.jpg" ofType:nil];
335   - // CNliveChatImageMessage *imageMsg = [CNliveChatImageMessage messageWithImageURI:path];
336   - CNliveChatImageMessage *imageMsg = nil;//[CNliveChatImageMessage messageWithImage:image];
  638 + CNliveChatImageMessage *imageMsg = [CNliveChatImageMessage messageWithImageURI:filePath];
337 639  
338 640 [[CNLiveChatManager sharedCNLiveChatManager] sendMediaMessage:CNLive_ConversationType_PRIVATE targetId:privateUserId content:imageMsg proBlock:^(CNliveChatImageMessage *message) {
339 641  
  642 + NSLog(@"^^^^^^^^^^^^%@",message.messageId);
  643 +
340 644 } success:^(CNliveChatImageMessage *message) {
341 645  
342 646 NSLog(@"图片消息发送成功~");
343   - MessageModel *model = [[MessageModel alloc] init];
344   - model.imageUrl = message.imageUrl;
345   - model.thumbnailImage = message.thumbnailImage;
346   - model.originalImage = message.originalImage;
347   - model.userId = message.userInfo.userId;
348   - model.name = message.userInfo.name;
349   - model.portraitUri = message.userInfo.portraitUri;
350   - model.type = message.conversationType;
351   - model.messageId = message.messageId;
352   - [_messageArrayM addObject:model];
  647 +
  648 + [_messageArrayM addObject:message];
353 649  
354 650 // 此处更新 UI 应到主线程
355 651 dispatch_async(dispatch_get_main_queue(), ^{
... ... @@ -362,7 +658,7 @@ static NSString *imageCellId = @&quot;imageCellId&quot;;
362 658 }];
363 659 }
364 660  
365   -#pragma mark - 语音 录 Button Action !!!!!!!!!!!!!!!!!!!!!!!!
  661 +#pragma mark - 语音 录音&发送 Button Action !!!!!!!!!!!!!!!!!!!!!!!!
366 662 - (void)voiceAction {
367 663  
368 664 _isVoice = !_isVoice;
... ... @@ -395,40 +691,29 @@ static NSString *imageCellId = @&quot;imageCellId&quot;;
395 691  
396 692 if (self.recordedData && self.duration > 1) {
397 693  
398   - CNLiveChatVoiceMessage *voiceMsg = [CNLiveChatVoiceMessage messageWithPath:@"Path" duration:self.duration]; //************
  694 + CNLiveChatVoiceMessage *voiceMsg = [CNLiveChatVoiceMessage messageWithPath:[NSString stringWithFormat:@"%@",[self recordTempFilePath]] duration:self.duration];
399 695  
400   - [[CNLiveChatManager sharedCNLiveChatManager] sendMessage:voiceMsg type:CNLive_ConversationType_PRIVATE targetId:privateUserId success:^(id message) {
  696 + [[CNLiveChatManager sharedCNLiveChatManager] sendVoiceMessage:CNLive_ConversationType_PRIVATE targetId:privateUserId content:voiceMsg proBlock:^(CNLiveChatVoiceMessage *message) {
  697 +
  698 + NSLog(@"^^^^^^^^^^^^%@",message.messageId);
  699 +
  700 + } success:^(CNLiveChatVoiceMessage *message) {
401 701  
402 702 NSLog(@"语音消息发送成功");
  703 + NSLog(@">>>>>>>>>>>>>>>>!!!%u",message.taskId);
403 704 // 自己发送的消息不会被onReceived:方法实时监听,需要自己做处理
404   - if ([message isKindOfClass:[CNLiveChatVoiceMessage class]]) {
405   -
406   - CNLiveChatVoiceMessage *voiceMsg = message;
407   -
408   -
409   - MessageModel *model = [[MessageModel alloc] init];
410   - model.duration = voiceMsg.duration;
411   - model.targetId = voiceMsg.targetId;
412   - CNLiveChatUserInfo *userInfo = [CNLiveChatManager sharedCNLiveChatManager].currentUserInfo;
413   - model.userId = userInfo.userId;
414   - model.name = userInfo.name;
415   - model.portraitUri = userInfo.portraitUri;
416   - model.type = CNLive_ConversationType_PRIVATE;
417   -
418   - [_messageArrayM addObject:model];
419   -
420   - // 此处更新 UI 应到主线程
421   - dispatch_async(dispatch_get_main_queue(), ^{
422   -
423   - [self.tableView reloadData];
424   -
425   - [self scrollToBottom];
426   - });
427   - }
  705 + [_messageArrayM addObject:message];
  706 + // 此处更新 UI 应到主线程
  707 + dispatch_async(dispatch_get_main_queue(), ^{
  708 + [self.tableView reloadData];
  709 + [self scrollToBottom];
  710 + });
428 711  
429   - } error:^(CNLiveChatErrorCode errors,NSString *errorMsg) {
430   - NSLog(@"语音发送失败,错误码:%ld",(long)errors);
  712 + } error:^(CNLiveChatErrorCode errorCode, NSString *messageId) {
  713 +
  714 + NSLog(@"语音发送失败,错误码:%ld",errorCode);
431 715 }];
  716 +
432 717 } else {
433 718 NSLog(@"时间太短,重新录制");
434 719 }
... ... @@ -462,30 +747,49 @@ static NSString *imageCellId = @&quot;imageCellId&quot;;
462 747 CNLiveVoiceTableViewCell *cell = (CNLiveVoiceTableViewCell *)[[button superview] superview];
463 748 _preCell = cell;
464 749 [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
465   - NSError *error=nil;
466   - MessageModel *model = _messageArrayM[cell.indexPath.row];
467   - _voiceTime = model.duration;
468   - _player = [[AVAudioPlayer alloc] initWithData:model.wavAudioData error:&error];
469   - _player.delegate = self;
470   - _player.numberOfLoops = 0;
471   - [_player prepareToPlay];
472   - if (error) {
473   - NSLog(@"初始化播放器过程发生错误,错误信息:%@",error.localizedDescription);
474   - }
475   - [_player play];
476   - [cell.voicePlayBtn setImage:[UIImage imageNamed:@"语音播"] forState:UIControlStateNormal];
477   - [cell.contentView addSubview:cell.timeLabel];
478   - cell.timeLabel.text = [NSString stringWithFormat:@"%ld s",_voiceTime];
479   - NSDictionary *dict = @{@"cell":cell,
480   - @"model":model};
481   - _voiceTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timeCountDown:) userInfo:dict repeats:YES];
  750 + CNLiveChatMessageBase *message = _messageArrayM[cell.indexPath.row];
  751 + if ([message isKindOfClass:[CNLiveChatVoiceMessage class]]) {
  752 +
  753 + CNLiveChatVoiceMessage *voiceMsg = (CNLiveChatVoiceMessage *)message;
  754 + _voiceTime = voiceMsg.duration;
  755 +
  756 + NSString *filePath = [self getTempPathType:2];
  757 + __weak __typeof(self)wself = self;
  758 + [voiceMsg getSound:filePath succ:^{
  759 +
  760 + NSError *error=nil;
  761 + __strong __typeof (wself) sself = wself;
  762 + wself.player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:filePath] error:&error];
  763 + wself.player.delegate = wself;
  764 + wself.player.numberOfLoops = 0;
  765 + [wself.player prepareToPlay];
  766 + if (error) {
  767 + NSLog(@"初始化播放器过程发生错误,错误信息:%@",error.localizedDescription);
  768 + }
  769 + [wself.player play];
  770 + [cell.voicePlayBtn setImage:[UIImage imageNamed:@"语音播"] forState:UIControlStateNormal];
  771 + [cell.contentView addSubview:cell.timeLabel];
  772 + cell.timeLabel.text = [NSString stringWithFormat:@"%ld s",sself -> _voiceTime];
  773 + NSDictionary *dict = @{@"cell":cell,
  774 + @"message":voiceMsg};
  775 + sself ->_voiceTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timeCountDown:) userInfo:dict repeats:YES];
  776 +
  777 + } fail:^(int code, NSString *msg) {
  778 +
  779 + NSLog(@"播放语音失败");
  780 + }];
  781 +
  782 + } else {
  783 +
  784 +
  785 + }
482 786 }
483 787  
484 788 - (void)timeCountDown:(NSTimer *)timer {
485 789  
486 790 NSDictionary *dict = [timer userInfo];
487 791 CNLiveVoiceTableViewCell *cell = (CNLiveVoiceTableViewCell *)dict[@"cell"];
488   - MessageModel *model = dict[@"model"];
  792 + CNLiveChatVoiceMessage *message = dict[@"message"];
489 793 if (_voiceTime > 0) {
490 794 _voiceTime = _voiceTime - 1;
491 795 cell.timeLabel.text = [NSString stringWithFormat:@"%ld s",_voiceTime];
... ... @@ -497,7 +801,7 @@ static NSString *imageCellId = @&quot;imageCellId&quot;;
497 801 _voiceTimer = nil;
498 802 [cell.voicePlayBtn setImage:[UIImage imageNamed:@"语音播放"] forState:UIControlStateNormal];
499 803 [cell.timeLabel removeFromSuperview];
500   - _voiceTime = model.duration;
  804 + _voiceTime = message.duration;
501 805 }
502 806 }
503 807  
... ... @@ -593,6 +897,39 @@ static NSString *imageCellId = @&quot;imageCellId&quot;;
593 897 return _recordTempFileURL;
594 898 }
595 899  
  900 +- (NSString *)recordTempFilePath {
  901 +
  902 + NSString *Str = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
  903 + NSString *loginId = [CNLiveChatManager sharedCNLiveChatManager].currentUserInfo.userId;
  904 + NSDate *date = [[NSDate alloc] init];
  905 + NSTimeInterval time = [date timeIntervalSince1970];
  906 + NSString *timeStr = [NSString stringWithFormat:@"%llu",(unsigned long long)time];
  907 + NSString *soundSaveDir = [NSString stringWithFormat:@"%@/%@/Audio",Str,loginId];
  908 + if (![self isExistFile:soundSaveDir])
  909 + { // 不存在
  910 + BOOL isCreateDir = [[NSFileManager defaultManager] createDirectoryAtPath:soundSaveDir withIntermediateDirectories:YES attributes:nil error:nil];
  911 + if (!isCreateDir)
  912 + {
  913 + return nil;
  914 + }
  915 + }
  916 +
  917 + NSString *soundSavePath = [NSString stringWithFormat:@"%@/%@",soundSaveDir,timeStr];
  918 + if (![self isExistFile:soundSavePath])
  919 + {
  920 + BOOL isCreate = [[NSFileManager defaultManager] createFileAtPath:soundSavePath contents:nil attributes:nil];
  921 + if (!isCreate)
  922 + {
  923 + return nil;
  924 + }
  925 + }
  926 + BOOL isWrite = [self.recordedData writeToFile:soundSavePath atomically:YES];
  927 + if (!isWrite)
  928 + {
  929 + return nil;
  930 + }
  931 + return soundSavePath;
  932 +}
596 933  
597 934 #pragma mark - 创建文本框 !!!!!!!!!!!!!!!!!!!!!!!!!!
598 935 - (UITextField *)createTextFieldWithFrame:(CGRect)frame font:(float)font {
... ... @@ -684,6 +1021,46 @@ static NSString *imageCellId = @&quot;imageCellId&quot;;
684 1021 return kNilOptions;
685 1022 }
686 1023  
  1024 +#pragma mark -
  1025 +#pragma mark - 获取一个临时路径
  1026 +- (NSString *)getTempPathType:(int)type {
  1027 + NSString *nsTmpDIr = NSTemporaryDirectory();
  1028 +
  1029 + NSString *Str;
  1030 + if (type == 1) {
  1031 + Str = [NSString stringWithFormat:@"GetImage%d",self.suffix];
  1032 + }
  1033 + else if (type == 2) {
  1034 + Str = [NSString stringWithFormat:@"GetAudio%d",self.suffix];
  1035 + }
  1036 + else if (type == 3) {
  1037 + Str = [NSString stringWithFormat:@"GetUGC%d",self.suffix];
  1038 + }
  1039 + self.suffix++;
  1040 + NSString *filePath = [NSString stringWithFormat:@"%@%@%3.f", nsTmpDIr, Str, [NSDate timeIntervalSinceReferenceDate]];
  1041 + if (type == 3) {
  1042 + filePath = [NSString stringWithFormat:@"%@.mp4",filePath];
  1043 + }
  1044 + return filePath;
  1045 +}
  1046 +
  1047 +#pragma mark -
  1048 +#pragma mark - 判断一个全路径文件是否存在
  1049 +- (BOOL)isExistFile:(NSString *)aFilePath
  1050 +{
  1051 + if ([self isEmpty:aFilePath])
  1052 + {
  1053 + return NO;
  1054 + }
  1055 + NSFileManager *fileManager = [NSFileManager defaultManager];
  1056 + return [fileManager fileExistsAtPath:aFilePath];
  1057 +}
  1058 +
  1059 +- (BOOL)isEmpty:(NSString *)string
  1060 +{
  1061 + return string == nil || string.length == 0;
  1062 +}
  1063 +
687 1064 #pragma mark - 隐藏键盘 !!!!!!!!!!!!!!!!!!!!!!!
688 1065 - (void)hideKeyboard {
689 1066  
... ...
CNLiveChatManagerSDKDemo/CNLiveChatManagerSDKDemo/ViewController.m
... ... @@ -13,8 +13,6 @@
13 13  
14 14 @interface ViewController ()
15 15  
16   -@property (nonatomic, strong) UIButton *loginBtn;
17   -
18 16 @property (nonatomic, strong) UIButton *privateBtn;
19 17  
20 18 @property (nonatomic, strong) UIButton *chatRoomBtn;
... ... @@ -31,20 +29,11 @@
31 29 self.view.backgroundColor = [UIColor whiteColor];
32 30 self.title = @"互动云聊天SDK Demo";
33 31  
34   - [self.view addSubview:self.loginBtn];
35 32 [self.view addSubview:self.privateBtn];
36 33 [self.view addSubview:self.chatRoomBtn];
37 34 [self.view addSubview:self.commentBtn];
38 35 }
39 36  
40   -- (UIButton *)loginBtn {
41   - if (!_loginBtn) {
42   - _loginBtn = [self createButtonWithFrame:CGRectMake((KScreenWidth - 100) * 0.5, KScreenHeight * 0.2, 100, 30) title:@"登录"];
43   - [_loginBtn setTitleColor:[UIColor redColor] forState:UIControlStateSelected];
44   - [_loginBtn addTarget:self action:@selector(login:) forControlEvents:UIControlEventTouchUpInside];
45   - }
46   - return _loginBtn;
47   -}
48 37  
49 38 - (UIButton *)privateBtn {
50 39 if (!_privateBtn) {
... ... @@ -77,16 +66,7 @@
77 66  
78 67 if (btn.selected) {
79 68  
80   - CNLiveChatUserInfo *userInfo = [[CNLiveChatUserInfo alloc] initWithUserId:@"20171214" name:@"回家" portrait:@""];
81   - [[CNLiveChatManager sharedCNLiveChatManager] loginServer:userInfo success:^(NSString *userId) {
82   -
83   - NSLog(@"用户:%@ 已成功登陆",userId);
84   - [CNLiveChatManager sharedCNLiveChatManager].currentUserInfo.name = @"XCode9"; // 更改昵称
85   -
86   - } error:^(CNLiveChatConnectErrorCode errors, NSString *errorMsg) {
87   -
88   - NSLog(@"登陆失败,错误码为:%ld",(long)errors);
89   - }];
  69 +
90 70 } else {
91 71  
92 72 [[CNLiveChatManager sharedCNLiveChatManager] connectServerSuccess:^{
... ...