Commit 5666338ca2f56d07a33a9e73354f03c7c399f6a7
1 parent
53e2f273
no message
Showing
11 changed files
with
625 additions
and
271 deletions
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
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
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
CNLiveChatManagerSDKDemo/CNLiveChatManagerSDKDemo/ChatRoomViewController.m
| ... | ... | @@ -891,35 +891,6 @@ static NSString *videoCellId = @"videoCellId"; |
| 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 = @"imageCellId"; |
| 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 = @"imageCellId"; |
| 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 = @"imageCellId"; |
| 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 = @"imageCellId"; |
| 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 = @"imageCellId"; |
| 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 = @"imageCellId"; |
| 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 = @"imageCellId"; |
| 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 = @"imageCellId"; |
| 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 = @"imageCellId"; |
| 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 = @"imageCellId"; |
| 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 = @"imageCellId"; |
| 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:^{ | ... | ... |