NTESSessionUtil.m 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. //
  2. // NTESSessionUtil.m
  3. // NIMDemo
  4. //
  5. // Created by ght on 15-1-27.
  6. // Copyright (c) 2015年 Netease. All rights reserved.
  7. //
  8. #import "NTESSessionUtil.h"
  9. //#import "NTESLoginManager.h"
  10. #import "NTESSnapchatAttachment.h"
  11. #import "NTESJanKenPonAttachment.h"
  12. #import "NTESChartletAttachment.h"
  13. #import "UIImage+NTES.h"
  14. #import "NIMKit.h"
  15. #import "NTESSnapchatAttachment.h"
  16. #import "NTESWhiteboardAttachment.h"
  17. #import "NIMKitInfoFetchOption.h"
  18. #import "NTESSubscribeManager.h"
  19. #import "NIMExtensionHelper.h"
  20. #import "NTESSubscribeDefine.h"
  21. #import "NSDictionary+NTESJson.h"
  22. #import "NTESDevice.h"
  23. double OnedayTimeIntervalValue = 24*60*60; //一天的秒数
  24. static NSString *const NTESRecentSessionAtMark = @"NTESRecentSessionAtMark";
  25. static NSString *const NTESRecentSessionTopMark = @"NTESRecentSessionTopMark";
  26. @implementation NTESSessionUtil
  27. + (CGSize)getImageSizeWithImageOriginSize:(CGSize)originSize
  28. minSize:(CGSize)imageMinSize
  29. maxSize:(CGSize)imageMaxSiz
  30. {
  31. CGSize size;
  32. NSInteger imageWidth = originSize.width ,imageHeight = originSize.height;
  33. NSInteger imageMinWidth = imageMinSize.width, imageMinHeight = imageMinSize.height;
  34. NSInteger imageMaxWidth = imageMaxSiz.width, imageMaxHeight = imageMaxSiz.height;
  35. if (imageWidth > imageHeight) //宽图
  36. {
  37. size.height = imageMinHeight; //高度取最小高度
  38. size.width = imageWidth * imageMinHeight / imageHeight;
  39. if (size.width > imageMaxWidth)
  40. {
  41. size.width = imageMaxWidth;
  42. }
  43. }
  44. else if(imageWidth < imageHeight)//高图
  45. {
  46. size.width = imageMinWidth;
  47. size.height = imageHeight *imageMinWidth / imageWidth;
  48. if (size.height > imageMaxHeight)
  49. {
  50. size.height = imageMaxHeight;
  51. }
  52. }
  53. else//方图
  54. {
  55. if (imageWidth > imageMaxWidth)
  56. {
  57. size.width = imageMaxWidth;
  58. size.height = imageMaxHeight;
  59. }
  60. else if(imageWidth > imageMinWidth)
  61. {
  62. size.width = imageWidth;
  63. size.height = imageHeight;
  64. }
  65. else
  66. {
  67. size.width = imageMinWidth;
  68. size.height = imageMinHeight;
  69. }
  70. }
  71. return size;
  72. }
  73. +(BOOL)isTheSameDay:(NSTimeInterval)currentTime compareTime:(NSDateComponents*)older
  74. {
  75. NSCalendarUnit currentComponents = (NSCalendarUnit)(NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour | NSCalendarUnitMinute);
  76. NSDateComponents *current = [[NSCalendar currentCalendar] components:currentComponents fromDate:[NSDate dateWithTimeIntervalSinceNow:currentTime]];
  77. return current.year == older.year && current.month == older.month && current.day == older.day;
  78. }
  79. +(NSString*)weekdayStr:(NSInteger)dayOfWeek
  80. {
  81. static NSDictionary *daysOfWeekDict = nil;
  82. daysOfWeekDict = @{@(1):@"星期日",
  83. @(2):@"星期一",
  84. @(3):@"星期二",
  85. @(4):@"星期三",
  86. @(5):@"星期四",
  87. @(6):@"星期五",
  88. @(7):@"星期六",};
  89. return [daysOfWeekDict objectForKey:@(dayOfWeek)];
  90. }
  91. +(NSDateComponents*)stringFromTimeInterval:(NSTimeInterval)messageTime components:(NSCalendarUnit)components
  92. {
  93. NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:components fromDate:[NSDate dateWithTimeIntervalSince1970:messageTime]];
  94. return dateComponents;
  95. }
  96. + (NSString *)showNick:(NSString*)uid inSession:(NIMSession*)session{
  97. NSString *nickname = nil;
  98. if (session.sessionType == NIMSessionTypeTeam)
  99. {
  100. NIMTeamMember *member = [[NIMSDK sharedSDK].teamManager teamMember:uid inTeam:session.sessionId];
  101. nickname = member.nickname;
  102. }
  103. if (!nickname.length) {
  104. NIMKitInfo *info = [[NIMKit sharedKit] infoByUser:uid option:nil];
  105. nickname = info.showName;
  106. }
  107. return nickname;
  108. }
  109. +(NSString*)showTime:(NSTimeInterval) msglastTime showDetail:(BOOL)showDetail
  110. {
  111. //今天的时间
  112. NSDate * nowDate = [NSDate date];
  113. NSDate * msgDate = [NSDate dateWithTimeIntervalSince1970:msglastTime];
  114. NSString *result = nil;
  115. NSCalendarUnit components = (NSCalendarUnit)(NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitWeekday|NSCalendarUnitHour | NSCalendarUnitMinute);
  116. NSDateComponents *nowDateComponents = [[NSCalendar currentCalendar] components:components fromDate:nowDate];
  117. NSDateComponents *msgDateComponents = [[NSCalendar currentCalendar] components:components fromDate:msgDate];
  118. NSInteger hour = msgDateComponents.hour;
  119. result = [NTESSessionUtil getPeriodOfTime:hour withMinute:msgDateComponents.minute];
  120. if (hour > 12)
  121. {
  122. hour = hour - 12;
  123. }
  124. if(nowDateComponents.day == msgDateComponents.day) //同一天,显示时间
  125. {
  126. result = [[NSString alloc] initWithFormat:@"%@ %zd:%02d",result,hour,(int)msgDateComponents.minute];
  127. }
  128. else if(nowDateComponents.day == (msgDateComponents.day+1))//昨天
  129. {
  130. result = showDetail? [[NSString alloc] initWithFormat:@"昨天%@ %zd:%02d",result,hour,(int)msgDateComponents.minute] : @"昨天";
  131. }
  132. else if(nowDateComponents.day == (msgDateComponents.day+2)) //前天
  133. {
  134. result = showDetail? [[NSString alloc] initWithFormat:@"前天%@ %zd:%02d",result,hour,(int)msgDateComponents.minute] : @"前天";
  135. }
  136. else if([nowDate timeIntervalSinceDate:msgDate] < 7 * OnedayTimeIntervalValue)//一周内
  137. {
  138. NSString *weekDay = [NTESSessionUtil weekdayStr:msgDateComponents.weekday];
  139. result = showDetail? [weekDay stringByAppendingFormat:@"%@ %zd:%02d",result,hour,(int)msgDateComponents.minute] : weekDay;
  140. }
  141. else//显示日期
  142. {
  143. NSString *day = [NSString stringWithFormat:@"%zd-%zd-%zd", msgDateComponents.year, msgDateComponents.month, msgDateComponents.day];
  144. result = showDetail? [day stringByAppendingFormat:@"%@ %zd:%02d",result,hour,(int)msgDateComponents.minute]:day;
  145. }
  146. return result;
  147. }
  148. + (NSString *)getPeriodOfTime:(NSInteger)time withMinute:(NSInteger)minute
  149. {
  150. NSInteger totalMin = time *60 + minute;
  151. NSString *showPeriodOfTime = @"";
  152. if (totalMin > 0 && totalMin <= 5 * 60)
  153. {
  154. showPeriodOfTime = @"凌晨";
  155. }
  156. else if (totalMin > 5 * 60 && totalMin < 12 * 60)
  157. {
  158. showPeriodOfTime = @"上午";
  159. }
  160. else if (totalMin >= 12 * 60 && totalMin <= 18 * 60)
  161. {
  162. showPeriodOfTime = @"下午";
  163. }
  164. else if ((totalMin > 18 * 60 && totalMin <= (23 * 60 + 59)) || totalMin == 0)
  165. {
  166. showPeriodOfTime = @"晚上";
  167. }
  168. return showPeriodOfTime;
  169. }
  170. + (void)sessionWithInputURL:(NSURL*)inputURL
  171. outputURL:(NSURL*)outputURL
  172. blockHandler:(void (^)(AVAssetExportSession*))handler
  173. {
  174. AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
  175. AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:asset
  176. presetName:AVAssetExportPresetMediumQuality];
  177. session.outputURL = outputURL;
  178. session.outputFileType = AVFileTypeMPEG4; // 支持安卓某些机器的视频播放
  179. session.shouldOptimizeForNetworkUse = YES;
  180. [session exportAsynchronouslyWithCompletionHandler:^(void)
  181. {
  182. handler(session);
  183. }];
  184. }
  185. + (NSDictionary *)dictByJsonData:(NSData *)data
  186. {
  187. NSDictionary *dict = nil;
  188. if ([data isKindOfClass:[NSData class]])
  189. {
  190. NSError *error = nil;
  191. dict = [NSJSONSerialization JSONObjectWithData:data
  192. options:0
  193. error:&error];
  194. if (error) {
  195. DDLogError(@"dictByJsonData failed %@ error %@",data,error);
  196. }
  197. }
  198. return [dict isKindOfClass:[NSDictionary class]] ? dict : nil;
  199. }
  200. + (NSDictionary *)dictByJsonString:(NSString *)jsonString
  201. {
  202. if (!jsonString.length) {
  203. return nil;
  204. }
  205. NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
  206. return [NTESSessionUtil dictByJsonData:data];
  207. }
  208. + (NSString *)tipOnMessageRevoked:(NIMRevokeMessageNotification *)notificaton
  209. {
  210. NSString *fromUid = nil;
  211. NIMSession *session = nil;
  212. NSString *tip = @"";
  213. BOOL isFromMe = NO;
  214. if([notificaton isKindOfClass:[NIMRevokeMessageNotification class]])
  215. {
  216. fromUid = [notificaton messageFromUserId];
  217. session = [notificaton session];
  218. isFromMe = [fromUid isEqualToString:[[NIMSDK sharedSDK].loginManager currentAccount]];
  219. }
  220. else if(!notificaton)
  221. {
  222. isFromMe = YES;
  223. }
  224. else
  225. {
  226. assert(0);
  227. }
  228. if (isFromMe)
  229. {
  230. tip = @"你";
  231. }
  232. else{
  233. switch (session.sessionType) {
  234. case NIMSessionTypeP2P:
  235. tip = @"对方";
  236. break;
  237. case NIMSessionTypeTeam:{
  238. NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:session.sessionId];
  239. NIMTeamMember *member = [[NIMSDK sharedSDK].teamManager teamMember:fromUid inTeam:session.sessionId];
  240. if ([fromUid isEqualToString:team.owner])
  241. {
  242. tip = @"群主";
  243. }
  244. else if(member.type == NIMTeamMemberTypeManager)
  245. {
  246. tip = @"管理员";
  247. }
  248. NIMKitInfoFetchOption *option = [[NIMKitInfoFetchOption alloc] init];
  249. option.session = session;
  250. NIMKitInfo *info = [[NIMKit sharedKit] infoByUser:fromUid option:option];
  251. tip = [tip stringByAppendingString:info.showName];
  252. }
  253. break;
  254. default:
  255. break;
  256. }
  257. }
  258. return [NSString stringWithFormat:@"%@撤回了一条消息",tip];
  259. }
  260. + (BOOL)canMessageBeForwarded:(NIMMessage *)message
  261. {
  262. if (!message.isReceivedMsg && message.deliveryState == NIMMessageDeliveryStateFailed) {
  263. return NO;
  264. }
  265. id<NIMMessageObject> messageObject = message.messageObject;
  266. if ([messageObject isKindOfClass:[NIMCustomObject class]])
  267. {
  268. id<NTESCustomAttachmentInfo> attach = (id<NTESCustomAttachmentInfo>)[(NIMCustomObject *)message.messageObject attachment];
  269. return [attach canBeForwarded];
  270. }
  271. if ([messageObject isKindOfClass:[NIMNotificationObject class]]) {
  272. return NO;
  273. }
  274. if ([messageObject isKindOfClass:[NIMTipObject class]]) {
  275. return NO;
  276. }
  277. if ([messageObject isKindOfClass:[NIMRobotObject class]]) {
  278. NIMRobotObject *robotObject = (NIMRobotObject *)messageObject;
  279. return !robotObject.isFromRobot;
  280. }
  281. return YES;
  282. }
  283. + (BOOL)canMessageBeRevoked:(NIMMessage *)message
  284. {
  285. BOOL canRevokeMessageByRole = [self canRevokeMessageByRole:message];
  286. BOOL isDeliverFailed = !message.isReceivedMsg && message.deliveryState == NIMMessageDeliveryStateFailed;
  287. if (!canRevokeMessageByRole || isDeliverFailed) {
  288. return NO;
  289. }
  290. id<NIMMessageObject> messageObject = message.messageObject;
  291. if ([messageObject isKindOfClass:[NIMTipObject class]]
  292. || [messageObject isKindOfClass:[NIMNotificationObject class]]) {
  293. return NO;
  294. }
  295. if ([messageObject isKindOfClass:[NIMCustomObject class]])
  296. {
  297. id<NTESCustomAttachmentInfo> attach = (id<NTESCustomAttachmentInfo>)[(NIMCustomObject *)message.messageObject attachment];
  298. return [attach canBeRevoked];
  299. }
  300. return YES;
  301. }
  302. + (BOOL)canRevokeMessageByRole:(NIMMessage *)message
  303. {
  304. BOOL isFromMe = [message.from isEqualToString:[[NIMSDK sharedSDK].loginManager currentAccount]];
  305. BOOL isToMe = [message.session.sessionId isEqualToString:[[NIMSDK sharedSDK].loginManager currentAccount]];
  306. BOOL isTeamManager = NO;
  307. if (message.session.sessionType == NIMSessionTypeTeam)
  308. {
  309. NIMTeamMember *member = [[NIMSDK sharedSDK].teamManager teamMember:[NIMSDK sharedSDK].loginManager.currentAccount inTeam:message.session.sessionId];
  310. isTeamManager = member.type == NIMTeamMemberTypeOwner || member.type == NIMTeamMemberTypeManager;
  311. }
  312. BOOL isRobotMessage = NO;
  313. id<NIMMessageObject> messageObject = message.messageObject;
  314. if ([messageObject isKindOfClass:[NIMRobotObject class]]) {
  315. NIMRobotObject *robotObject = (NIMRobotObject *)messageObject;
  316. isRobotMessage = robotObject.isFromRobot;
  317. }
  318. //我发出去的消息并且不是发给我的电脑的消息并且不是机器人的消息,可以撤回
  319. //群消息里如果我是管理员可以撤回以上所有消息
  320. return (isFromMe && !isToMe && !isRobotMessage) || isTeamManager;
  321. }
  322. + (void)addRecentSessionMark:(NIMSession *)session type:(NTESRecentSessionMarkType)type
  323. {
  324. NIMRecentSession *recent = [[NIMSDK sharedSDK].conversationManager recentSessionBySession:session];
  325. if (recent)
  326. {
  327. NSDictionary *localExt = recent.localExt?:@{};
  328. NSMutableDictionary *dict = [localExt mutableCopy];
  329. NSString *key = [NTESSessionUtil keyForMarkType:type];
  330. [dict setObject:@(YES) forKey:key];
  331. [[NIMSDK sharedSDK].conversationManager updateRecentLocalExt:dict recentSession:recent];
  332. }
  333. }
  334. + (void)removeRecentSessionMark:(NIMSession *)session type:(NTESRecentSessionMarkType)type
  335. {
  336. NIMRecentSession *recent = [[NIMSDK sharedSDK].conversationManager recentSessionBySession:session];
  337. if (recent) {
  338. NSMutableDictionary *localExt = [recent.localExt mutableCopy];
  339. NSString *key = [NTESSessionUtil keyForMarkType:type];
  340. [localExt removeObjectForKey:key];
  341. [[NIMSDK sharedSDK].conversationManager updateRecentLocalExt:localExt recentSession:recent];
  342. }
  343. }
  344. + (BOOL)recentSessionIsMark:(NIMRecentSession *)recent type:(NTESRecentSessionMarkType)type
  345. {
  346. NSDictionary *localExt = recent.localExt;
  347. NSString *key = [NTESSessionUtil keyForMarkType:type];
  348. return [localExt[key] boolValue] == YES;
  349. }
  350. + (NSString *)keyForMarkType:(NTESRecentSessionMarkType)type
  351. {
  352. static NSDictionary *keys;
  353. static dispatch_once_t onceToken;
  354. dispatch_once(&onceToken, ^{
  355. keys = @{
  356. @(NTESRecentSessionMarkTypeAt) : NTESRecentSessionAtMark,
  357. @(NTESRecentSessionMarkTypeTop) : NTESRecentSessionTopMark
  358. };
  359. });
  360. return [keys objectForKey:@(type)];
  361. }
  362. + (NSString *)onlineState:(NSString *)userId detail:(BOOL)detail
  363. {
  364. NSString *state = @"";
  365. if (![NTESSubscribeManager sharedManager] || [[NIMSDK sharedSDK].loginManager.currentAccount isEqualToString:userId])
  366. {
  367. //没有开启订阅服务或是自己 不显示在线状态
  368. return state;
  369. }
  370. if ([[NIMSDK sharedSDK].robotManager isValidRobot:userId]) {
  371. return @"在线";
  372. }
  373. NSDictionary *dict = [[NTESSubscribeManager sharedManager] eventsForType:NIMSubscribeSystemEventTypeOnline];
  374. NIMSubscribeEvent *event = [dict objectForKey:userId];
  375. NIMSubscribeOnlineInfo *info = event.subscribeInfo;
  376. if ([info isKindOfClass:[NIMSubscribeOnlineInfo class]] && info.senderClientTypes.count)
  377. {
  378. NIMLoginClientType client = [self resolveShowClientType:info.senderClientTypes];
  379. switch (event.value) {
  380. case NTESCustomStateValueOnlineExt:
  381. case NIMSubscribeEventOnlineValueLogin:
  382. case NIMSubscribeEventOnlineValueLogout:
  383. case NIMSubscribeEventOnlineValueDisconnected:
  384. {
  385. NSString *ext = [event ext:client];
  386. state = [self resolveOnlineState:ext client:client detail:detail];
  387. }
  388. break;
  389. default:
  390. {
  391. NSString *clientName = [self resolveOnlineClientName:client];
  392. state = [NSString stringWithFormat:@"%@在线",clientName];
  393. break;
  394. }
  395. }
  396. }
  397. else
  398. {
  399. state = @"离线";
  400. }
  401. return state;
  402. }
  403. + (NIMLoginClientType)resolveShowClientType:(NSArray *)senderClientTypes
  404. {
  405. NSArray *clients = @[@(NIMLoginClientTypePC),@(NIMLoginClientTypemacOS),@(NIMLoginClientTypeiOS),@(NIMLoginClientTypeAOS),@(NIMLoginClientTypeWeb),@(NIMLoginClientTypeWP)]; //显示优先级
  406. for (NSNumber *type in clients) {
  407. NIMLoginClientType client = type.integerValue;
  408. if ([senderClientTypes containsObject:@(client)]) {
  409. return client;
  410. }
  411. }
  412. return NIMLoginClientTypeUnknown;
  413. }
  414. + (NSString *)resolveOnlineClientName:(NIMLoginClientType )client
  415. {
  416. NSDictionary *formats = @{
  417. @(NIMLoginClientTypePC) : @"PC",
  418. @(NIMLoginClientTypemacOS) : @"Mac",
  419. @(NIMLoginClientTypeiOS): @"iOS",
  420. @(NIMLoginClientTypeAOS): @"Android",
  421. @(NIMLoginClientTypeWeb): @"Web",
  422. @(NIMLoginClientTypeWP) : @"WP"
  423. };
  424. NSString *format = [formats objectForKey:@(client)];
  425. return format? format : @"";
  426. }
  427. + (NSString *)resolveOnlineState:(NSString *)ext client:(NIMLoginClientType)client detail:(BOOL)detail
  428. {
  429. NSString *clientName = [self resolveOnlineClientName:client];
  430. NSString *state = [NSString stringWithFormat:@"%@在线",clientName];
  431. NSDictionary *dict = [ext nimkit_jsonDict];
  432. if (dict) {
  433. NSString *netState = [[NTESDevice currentDevice] networkStatus:[dict jsonInteger:NTESSubscribeNetState]];
  434. NTESOnlineState onlineState = [dict jsonInteger:NTESSubscribeOnlineState];
  435. switch (onlineState) {
  436. case NTESOnlineStateNormal:
  437. {
  438. if (client == NIMLoginClientTypePC ||
  439. client == NIMLoginClientTypeWeb ||
  440. client == NIMLoginClientTypemacOS)
  441. {
  442. //桌面端不显示网络状态,只显示端
  443. return [NSString stringWithFormat:@"%@在线",clientName];
  444. }
  445. else
  446. {
  447. //移动端在会话列表显示网络状态,在会话内(detail)优先显示端+网络状态
  448. if (detail)
  449. {
  450. return [NSString stringWithFormat:@"%@ - %@ 在线",clientName,netState];
  451. }
  452. else
  453. {
  454. return [NSString stringWithFormat:@"%@ 在线",netState];
  455. }
  456. }
  457. }
  458. case NTESOnlineStateBusy:
  459. return @"忙碌";
  460. case NTESOnlineStateLeave:
  461. return @"离开";
  462. default:
  463. break;
  464. }
  465. }
  466. return state;
  467. }
  468. + (NSString *)formatAutoLoginMessage:(NSError *)error
  469. {
  470. NSString *message = [NSString stringWithFormat:@"自动登录失败 %@",error];
  471. NSString *domain = error.domain;
  472. NSInteger code = error.code;
  473. if ([domain isEqualToString:NIMLocalErrorDomain])
  474. {
  475. if (code == NIMLocalErrorCodeAutoLoginRetryLimit)
  476. {
  477. message = @"自动登录错误次数超限,请检查网络后重试";
  478. }
  479. }
  480. else if([domain isEqualToString:NIMRemoteErrorDomain])
  481. {
  482. if (code == NIMRemoteErrorCodeInvalidPass)
  483. {
  484. message = @"密码错误";
  485. }
  486. else if(code == NIMRemoteErrorCodeExist)
  487. {
  488. message = @"当前已经其他设备登录,请使用手动模式登录";
  489. }
  490. }
  491. return message;
  492. }
  493. @end