NIMKitDataProviderImpl.m 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. //
  2. // NIMKitDataProviderImpl.m
  3. // NIMKit
  4. //
  5. // Created by chris on 2016/10/31.
  6. // Copyright © 2016年 NetEase. All rights reserved.
  7. //
  8. #import <UIKit/UIKit.h>
  9. #import "NIMKit.h"
  10. #import "NIMKitDataProviderImpl.h"
  11. #import "NIMKitInfoFetchOption.h"
  12. #import "UIImage+NIMKit.h"
  13. #pragma mark - kit data request
  14. @interface NIMKitDataRequest : NSObject
  15. @property (nonatomic,strong) NSMutableSet *failedUserIds;
  16. @property (nonatomic,assign) NSInteger maxMergeCount; //最大合并数
  17. - (void)requestUserIds:(NSArray *)userIds;
  18. @end
  19. @implementation NIMKitDataRequest{
  20. NSMutableArray *_requstUserIdArray; //待请求池
  21. BOOL _isRequesting;
  22. }
  23. - (instancetype)init{
  24. self = [super init];
  25. if (self) {
  26. _failedUserIds = [[NSMutableSet alloc] init];
  27. _requstUserIdArray = [[NSMutableArray alloc] init];
  28. }
  29. return self;
  30. }
  31. - (void)requestUserIds:(NSArray *)userIds
  32. {
  33. for (NSString *userId in userIds)
  34. {
  35. if (![_requstUserIdArray containsObject:userId] && ![_failedUserIds containsObject:userId])
  36. {
  37. [_requstUserIdArray addObject:userId];
  38. }
  39. }
  40. [self request];
  41. }
  42. - (void)request
  43. {
  44. static NSUInteger MaxBatchReuqestCount = 10;
  45. if (_isRequesting || [_requstUserIdArray count] == 0) {
  46. return;
  47. }
  48. _isRequesting = YES;
  49. NSArray *userIds = [_requstUserIdArray count] > MaxBatchReuqestCount ?
  50. [_requstUserIdArray subarrayWithRange:NSMakeRange(0, MaxBatchReuqestCount)] : [_requstUserIdArray copy];
  51. __weak typeof(self) weakSelf = self;
  52. [[NIMSDK sharedSDK].userManager fetchUserInfos:userIds
  53. completion:^(NSArray *users, NSError *error) {
  54. [weakSelf afterReuquest:userIds];
  55. if (!error && users.count)
  56. {
  57. [[NIMKit sharedKit] notfiyUserInfoChanged:userIds];
  58. }
  59. else if ([weakSelf shouldAddToFailedUsers:error])
  60. {
  61. [weakSelf.failedUserIds addObjectsFromArray:userIds];
  62. }
  63. }];
  64. }
  65. - (void)afterReuquest:(NSArray *)userIds
  66. {
  67. _isRequesting = NO;
  68. [_requstUserIdArray removeObjectsInArray:userIds];
  69. [self request];
  70. }
  71. - (BOOL)shouldAddToFailedUsers:(NSError *)error
  72. {
  73. //没有错误这种异常情况走到这个路径里也不对,不再请求
  74. return error.code != NIMRemoteErrorCodeTimeoutError || !error;
  75. }
  76. @end
  77. #pragma mark - data provider impl
  78. @interface NIMKitDataProviderImpl()<NIMUserManagerDelegate,NIMTeamManagerDelegate,NIMLoginManagerDelegate>
  79. @property (nonatomic,strong) UIImage *defaultUserAvatar;
  80. @property (nonatomic,strong) UIImage *defaultTeamAvatar;
  81. @property (nonatomic,strong) NIMKitDataRequest *request;
  82. @end
  83. @implementation NIMKitDataProviderImpl
  84. - (instancetype)init{
  85. self = [super init];
  86. if (self) {
  87. _request = [[NIMKitDataRequest alloc] init];
  88. _request.maxMergeCount = 20;
  89. [[NIMSDK sharedSDK].userManager addDelegate:self];
  90. [[NIMSDK sharedSDK].teamManager addDelegate:self];
  91. [[NIMSDK sharedSDK].loginManager addDelegate:self];
  92. }
  93. return self;
  94. }
  95. - (void)dealloc
  96. {
  97. [[NIMSDK sharedSDK].userManager removeDelegate:self];
  98. [[NIMSDK sharedSDK].teamManager removeDelegate:self];
  99. [[NIMSDK sharedSDK].loginManager removeDelegate:self];
  100. }
  101. #pragma mark - public api
  102. - (NIMKitInfo *)infoByUser:(NSString *)userId
  103. option:(NIMKitInfoFetchOption *)option
  104. {
  105. //优先检测是否为机器人
  106. NIMKitInfo *info = [self infoByRobot:userId];
  107. if (info == nil)
  108. {
  109. NIMSession *session = option.message.session?:option.session;
  110. info = [self infoByUser:userId session:session option:option];
  111. }
  112. return info;
  113. }
  114. - (NIMKitInfo *)infoByTeam:(NSString *)teamId
  115. option:(NIMKitInfoFetchOption *)option
  116. {
  117. NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:teamId];
  118. NIMKitInfo *info = [[NIMKitInfo alloc] init];
  119. info.showName = team.teamName;
  120. info.infoId = teamId;
  121. info.avatarImage = self.defaultTeamAvatar;
  122. info.avatarUrlString = team.thumbAvatarUrl;
  123. return info;
  124. }
  125. #pragma mark - 用户信息拼装
  126. //会话中用户信息
  127. - (NIMKitInfo *)infoByUser:(NSString *)userId
  128. session:(NIMSession *)session
  129. option:(NIMKitInfoFetchOption *)option
  130. {
  131. NIMSessionType sessionType = session.sessionType;
  132. NIMKitInfo *info;
  133. switch (sessionType) {
  134. case NIMSessionTypeP2P:
  135. {
  136. info = [self userInfoInP2P:userId option:option];
  137. }
  138. break;
  139. case NIMSessionTypeTeam:
  140. {
  141. info = [self userInfo:userId inTeam:session.sessionId option:option];
  142. }
  143. break;
  144. case NIMSessionTypeChatroom:
  145. {
  146. info = [self userInfo:userId inChatroom:session.sessionId option:option];
  147. }
  148. break;
  149. default:
  150. NSAssert(0, @"invalid type");
  151. break;
  152. }
  153. if (!info)
  154. {
  155. if (!userId.length)
  156. {
  157. NSLog(@"warning: fetch user failed because userid is empty");
  158. }
  159. else
  160. {
  161. [self.request requestUserIds:@[userId]];
  162. }
  163. info = [[NIMKitInfo alloc] init];
  164. info.infoId = userId;
  165. info.showName = userId; //默认值
  166. info.avatarImage = self.defaultUserAvatar;
  167. }
  168. return info;
  169. }
  170. #pragma mark - P2P 用户信息
  171. - (NIMKitInfo *)userInfoInP2P:(NSString *)userId
  172. option:(NIMKitInfoFetchOption *)option
  173. {
  174. NIMUser *user = [[NIMSDK sharedSDK].userManager userInfo:userId];
  175. NIMUserInfo *userInfo = user.userInfo;
  176. NIMKitInfo *info;
  177. if (userInfo)
  178. {
  179. info = [[NIMKitInfo alloc] init];
  180. info.infoId = userId;
  181. NSString *name = [self nickname:user
  182. memberInfo:nil
  183. option:option];
  184. info.showName = name?:userId;
  185. info.avatarUrlString = userInfo.thumbAvatarUrl;
  186. info.avatarImage = self.defaultUserAvatar;
  187. }
  188. return info;
  189. }
  190. #pragma mark - 群组用户信息
  191. - (NIMKitInfo *)userInfo:(NSString *)userId
  192. inTeam:(NSString *)teamId
  193. option:(NIMKitInfoFetchOption *)option
  194. {
  195. NIMUser *user = [[NIMSDK sharedSDK].userManager userInfo:userId];
  196. NIMUserInfo *userInfo = user.userInfo;
  197. NIMTeamMember *member = [[NIMSDK sharedSDK].teamManager teamMember:userId
  198. inTeam:teamId];
  199. NIMKitInfo *info;
  200. if (userInfo || member)
  201. {
  202. info = [[NIMKitInfo alloc] init];
  203. info.infoId = userId;
  204. NSString *name = [self nickname:user
  205. memberInfo:member
  206. option:option];
  207. info.showName = name?:userId;
  208. info.avatarUrlString = userInfo.thumbAvatarUrl;
  209. info.avatarImage = self.defaultUserAvatar;
  210. }
  211. return info;
  212. }
  213. #pragma mark - 聊天室用户信息
  214. - (NIMKitInfo *)userInfo:(NSString *)userId
  215. inChatroom:(NSString *)roomId
  216. option:(NIMKitInfoFetchOption *)option
  217. {
  218. NIMKitInfo *info = [[NIMKitInfo alloc] init];
  219. info.infoId = userId;
  220. if ([userId isEqualToString:[NIMSDK sharedSDK].loginManager.currentAccount])
  221. {
  222. switch ([NIMSDK sharedSDK].loginManager.currentAuthMode) {
  223. case NIMSDKAuthModeChatroom:
  224. {
  225. NSAssert([NIMKit sharedKit].independentModeExtraInfo, @"in mode NIMSDKAuthModeChatroom , must has independentModeExtraInfo");
  226. info.showName = [NIMKit sharedKit].independentModeExtraInfo.myChatroomNickname;
  227. info.avatarUrlString = [NIMKit sharedKit].independentModeExtraInfo.myChatroomAvatar;
  228. }
  229. break;
  230. case NIMSDKAuthModeIM:
  231. {
  232. NIMUser *user = [[NIMSDK sharedSDK].userManager userInfo:userId];
  233. info.showName = user.userInfo.nickName;
  234. info.avatarUrlString = user.userInfo.thumbAvatarUrl;
  235. }
  236. break;
  237. default:
  238. {
  239. NSAssert(0, @"invalid mode");
  240. }
  241. break;
  242. }
  243. }
  244. else
  245. {
  246. NSAssert(option.message, @"message must has value in chatroom");
  247. NIMMessageChatroomExtension *ext = [option.message.messageExt isKindOfClass:[NIMMessageChatroomExtension class]] ?
  248. (NIMMessageChatroomExtension *)option.message.messageExt : nil;
  249. info.showName = ext.roomNickname;
  250. info.avatarUrlString = ext.roomAvatar;
  251. }
  252. info.avatarImage = self.defaultUserAvatar;
  253. return info;
  254. }
  255. //机器人
  256. - (NIMKitInfo *)infoByRobot:(NSString *)userId
  257. {
  258. NIMKitInfo *info = nil;
  259. if ([[NIMSDK sharedSDK].robotManager isValidRobot:userId])
  260. {
  261. NIMRobot *robot = [[NIMSDK sharedSDK].robotManager robotInfo:userId];
  262. if (robot)
  263. {
  264. info = [[NIMKitInfo alloc] init];
  265. info.infoId = userId;
  266. info.showName = robot.nickname;
  267. info.avatarUrlString = robot.thumbAvatarUrl;
  268. info.avatarImage = self.defaultUserAvatar;
  269. }
  270. }
  271. return info;
  272. }
  273. //昵称优先级
  274. - (NSString *)nickname:(NIMUser *)user
  275. memberInfo:(NIMTeamMember *)memberInfo
  276. option:(NIMKitInfoFetchOption *)option
  277. {
  278. NSString *name = nil;
  279. do{
  280. if (!option.forbidaAlias && [user.alias length])
  281. {
  282. name = user.alias;
  283. break;
  284. }
  285. if (memberInfo && [memberInfo.nickname length])
  286. {
  287. name = memberInfo.nickname;
  288. break;
  289. }
  290. if ([user.userInfo.nickName length])
  291. {
  292. name = user.userInfo.nickName;
  293. break;
  294. }
  295. }while (0);
  296. return name;
  297. }
  298. #pragma mark - avatar
  299. - (UIImage *)defaultTeamAvatar
  300. {
  301. if (!_defaultTeamAvatar)
  302. {
  303. _defaultTeamAvatar = [UIImage nim_imageInKit:@"avatar_team"];
  304. }
  305. return _defaultTeamAvatar;
  306. }
  307. - (UIImage *)defaultUserAvatar
  308. {
  309. if (!_defaultUserAvatar)
  310. {
  311. _defaultUserAvatar = [UIImage nim_imageInKit:@"avatar_user"];
  312. }
  313. return _defaultUserAvatar;
  314. }
  315. //将个人信息和群组信息变化通知给 NIMKit 。
  316. //如果您的应用不托管个人信息给云信,则需要您自行在上层监听个人信息变动,并将变动通知给 NIMKit。
  317. #pragma mark - NIMUserManagerDelegate
  318. - (void)onFriendChanged:(NIMUser *)user
  319. {
  320. [self notifyUser:user];
  321. }
  322. - (void)onUserInfoChanged:(NIMUser *)user
  323. {
  324. [self notifyUser:user];
  325. }
  326. - (void)notifyUser:(NIMUser *)user
  327. {
  328. if (!user)
  329. {
  330. NSLog(@"warning: notify user failed because user is empty");
  331. }
  332. else
  333. {
  334. [[NIMKit sharedKit] notfiyUserInfoChanged:@[user.userId]];
  335. }
  336. }
  337. #pragma mark - NIMTeamManagerDelegate
  338. - (void)onTeamAdded:(NIMTeam *)team
  339. {
  340. [self notifyTeamInfo:team];
  341. }
  342. - (void)onTeamUpdated:(NIMTeam *)team
  343. {
  344. [self notifyTeamInfo:team];
  345. }
  346. - (void)onTeamRemoved:(NIMTeam *)team
  347. {
  348. [self notifyTeamInfo:team];
  349. }
  350. - (void)onTeamMemberChanged:(NIMTeam *)team
  351. {
  352. [self notifyTeamMember:team];
  353. }
  354. - (void)notifyTeamInfo:(NIMTeam *)team
  355. {
  356. if (!team.teamId.length)
  357. {
  358. NSLog(@"warning: notify teamid failed because teamid is empty");
  359. }
  360. else
  361. {
  362. [[NIMKit sharedKit] notifyTeamInfoChanged:@[team.teamId]];
  363. }
  364. }
  365. - (void)notifyTeamMember:(NIMTeam *)team
  366. {
  367. if (!team.teamId.length)
  368. {
  369. NSLog(@"warning: notify team member failed because teamid is empty");
  370. }
  371. else
  372. {
  373. [[NIMKit sharedKit] notifyTeamMemebersChanged:@[team.teamId]];
  374. }
  375. }
  376. #pragma mark - NIMLoginManagerDelegate
  377. - (void)onLogin:(NIMLoginStep)step
  378. {
  379. if (step == NIMLoginStepSyncOK) {
  380. [[NIMKit sharedKit] notifyTeamInfoChanged:nil];
  381. [[NIMKit sharedKit] notifyTeamMemebersChanged:nil];
  382. }
  383. }
  384. @end