// // NIMSDKManager.m // YUMI // // Created by YUMI on 2024/12/19. // #import "NIMSDKManager.h" #import "CustomAttachmentDecoder.h" #import "YUMIConstant.h" @interface NIMSDKManager () @property (nonatomic, strong) NIMSDKConfigModel *config; @property (nonatomic, assign) NIMSDKLoginStatus loginStatus; @property (nonatomic, strong) NSMutableArray> *delegates; @property (nonatomic, copy) NIMSDKStatusChangeBlock statusChangeBlock; @property (nonatomic, assign) BOOL isInitialized; @end @implementation NIMSDKManager #pragma mark - 单例方法 + (instancetype)sharedManager { static NIMSDKManager *instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[NIMSDKManager alloc] init]; }); return instance; } - (instancetype)init { self = [super init]; if (self) { _delegates = [NSMutableArray array]; _loginStatus = NIMSDKLoginStatusNotLogin; _isInitialized = NO; } return self; } #pragma mark - 配置和初始化 - (void)configureWithConfig:(NIMSDKConfigModel *)config { self.config = config; } - (void)initializeWithCompletion:(void(^)(NSError * _Nullable error))completion { if (self.isInitialized) { if (completion) { completion(nil); } return; } // 检查配置 if (!self.config || !self.config.appKey) { NSError *error = [NSError errorWithDomain:@"NIMSDKManager" code:-1 userInfo:@{NSLocalizedDescriptionKey: @"NIMSDK配置不完整"}]; if (completion) { completion(error); } return; } // 创建SDK选项 NIMSDKOption *option = [NIMSDKOption optionWithAppKey:self.config.appKey]; if (self.config.apnsCername) { option.apnsCername = self.config.apnsCername; } // 注册SDK [[NIMSDK sharedSDK] registerWithOption:option]; // 注册自定义解码器 [self registerCustomDecoder:[[CustomAttachmentDecoder alloc] init]]; // 配置SDK参数 [NIMSDKConfig sharedConfig].shouldConsiderRevokedMessageUnreadCount = self.config.shouldConsiderRevokedMessageUnreadCount; [[NIMSDKConfig sharedConfig] setShouldSyncStickTopSessionInfos:self.config.shouldSyncStickTopSessionInfos]; [NIMSDKConfig sharedConfig].enabledHttpsForInfo = self.config.enabledHttpsForInfo; [NIMSDKConfig sharedConfig].enabledHttpsForMessage = self.config.enabledHttpsForMessage; // 添加代理 [[NIMSDK sharedSDK].loginManager addDelegate:self]; [[NIMSDK sharedSDK].chatManager addDelegate:self]; [[NIMSDK sharedSDK].systemNotificationManager addDelegate:self]; [[NIMSDK sharedSDK].broadcastManager addDelegate:self]; self.isInitialized = YES; if (completion) { completion(nil); } } - (void)registerCustomDecoder:(id)decoder { [NIMCustomObject registerCustomDecoder:decoder]; } #pragma mark - 登录管理 - (void)loginWithAccount:(NSString *)account token:(NSString *)token completion:(NIMSDKLoginCompletion)completion { if (!self.isInitialized) { NSError *error = [NSError errorWithDomain:@"NIMSDKManager" code:-2 userInfo:@{NSLocalizedDescriptionKey: @"NIMSDK未初始化"}]; if (completion) { completion(error); } return; } self.loginStatus = NIMSDKLoginStatusLogging; [self notifyStatusChange]; [[NIMSDK sharedSDK].loginManager login:account token:token completion:^(NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ if (error) { self.loginStatus = NIMSDKLoginStatusNotLogin; } else { self.loginStatus = NIMSDKLoginStatusLogined; } [self notifyStatusChange]; if (completion) { completion(error); } }); }]; } - (void)autoLoginWithData:(NSDictionary *)data completion:(NIMSDKLoginCompletion)completion { if (!self.isInitialized) { NSError *error = [NSError errorWithDomain:@"NIMSDKManager" code:-2 userInfo:@{NSLocalizedDescriptionKey: @"NIMSDK未初始化"}]; if (completion) { completion(error); } return; } self.loginStatus = NIMSDKLoginStatusLogging; [self notifyStatusChange]; [[NIMSDK sharedSDK].loginManager autoLogin:data]; // 注意:自动登录的结果通过代理方法回调 // 这里暂时返回成功,实际结果通过代理通知 if (completion) { completion(nil); } } - (void)logoutWithCompletion:(NIMSDKLogoutCompletion)completion { [[NIMSDK sharedSDK].loginManager logout:^(NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ if (!error) { self.loginStatus = NIMSDKLoginStatusLogout; [self notifyStatusChange]; } if (completion) { completion(error); } }); }]; } - (void)forceLogoutWithCompletion:(NIMSDKLogoutCompletion)completion { // 强制登出,清理所有状态 [[NIMSDK sharedSDK].loginManager logout:^(NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ self.loginStatus = NIMSDKLoginStatusLogout; [self notifyStatusChange]; if (completion) { completion(error); } }); }]; } #pragma mark - 状态查询 - (NIMSDKLoginStatus)currentLoginStatus { return self.loginStatus; } - (BOOL)isLogined { return [[NIMSDK sharedSDK].loginManager isLogined]; } - (NSString *)currentAccount { return [[NIMSDK sharedSDK].loginManager currentAccount]; } #pragma mark - 推送管理 - (void)updateApnsToken:(NSData *)deviceToken { [[NIMSDK sharedSDK] updateApnsToken:deviceToken]; } - (BOOL)handlePushNotification:(NSDictionary *)userInfo { // 处理推送消息的逻辑 // 这里可以根据具体的推送格式进行解析和处理 return YES; } #pragma mark - 代理管理 - (void)addDelegate:(id)delegate { if (delegate && ![self.delegates containsObject:delegate]) { [self.delegates addObject:delegate]; } } - (void)removeDelegate:(id)delegate { [self.delegates removeObject:delegate]; } - (void)setLoginStatusChangeBlock:(NIMSDKStatusChangeBlock)block { self.statusChangeBlock = block; } #pragma mark - 消息管理 - (void)sendMessage:(NIMMessage *)message toSession:(NIMSession *)session completion:(void(^)(NSError * _Nullable error))completion { [[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:nil]; // 注意:实际发送结果通过代理方法回调 if (completion) { completion(nil); } } - (NSInteger)unreadMessageCount { return [[NIMSDK sharedSDK].conversationManager allUnreadCount]; } - (NSArray *)allRecentSessions { return [[NIMSDK sharedSDK].conversationManager allRecentSessions]; } #pragma mark - 用户管理 - (NIMUser *)userInfo:(NSString *)userId { return [[NIMSDK sharedSDK].userManager userInfo:userId]; } - (void)fetchUserInfos:(NSArray *)userIds completion:(void(^)(NSArray * _Nullable users, NSError * _Nullable error))completion { [[NIMSDK sharedSDK].userManager fetchUserInfos:userIds completion:completion]; } #pragma mark - 聊天室管理 - (void)enterChatroom:(NSString *)roomId completion:(void(^)(NSError * _Nullable error))completion { [[NIMSDK sharedSDK].chatroomManager enterChatroom:roomId completion:completion]; } - (void)exitChatroom:(NSString *)roomId completion:(void(^)(NSError * _Nullable error))completion { [[NIMSDK sharedSDK].chatroomManager exitChatroom:roomId completion:completion]; } #pragma mark - 工具方法 - (NIMMessage *)createCustomMessageWithAttachment:(id)attachment { NIMCustomObject *customObject = [[NIMCustomObject alloc] init]; customObject.attachment = attachment; NIMMessage *message = [[NIMMessage alloc] init]; message.messageObject = customObject; return message; } - (NIMMessage *)createTextMessage:(NSString *)text { return [[NIMMessage alloc] initWithText:text]; } - (NIMMessage *)createImageMessage:(UIImage *)image { NIMImageObject *imageObject = [[NIMImageObject alloc] initWithImage:image]; NIMMessage *message = [[NIMMessage alloc] init]; message.messageObject = imageObject; return message; } - (NIMMessage *)createAudioMessage:(NSString *)filePath duration:(NSTimeInterval)duration { NIMAudioObject *audioObject = [[NIMAudioObject alloc] initWithSourcePath:filePath]; audioObject.duration = duration; NIMMessage *message = [[NIMMessage alloc] init]; message.messageObject = audioObject; return message; } #pragma mark - 清理方法 - (void)cleanup { // 移除代理 [[NIMSDK sharedSDK].loginManager removeDelegate:self]; [[NIMSDK sharedSDK].chatManager removeDelegate:self]; [[NIMSDK sharedSDK].systemNotificationManager removeDelegate:self]; [[NIMSDK sharedSDK].broadcastManager removeDelegate:self]; // 清理状态 self.loginStatus = NIMSDKLoginStatusNotLogin; self.isInitialized = NO; [self.delegates removeAllObjects]; self.statusChangeBlock = nil; } #pragma mark - 私有方法 - (void)notifyStatusChange { // 通知代理 for (id delegate in self.delegates) { if ([delegate respondsToSelector:@selector(nimSDKManager:didChangeLoginStatus:)]) { [delegate nimSDKManager:self didChangeLoginStatus:self.loginStatus]; } } // 通知block if (self.statusChangeBlock) { self.statusChangeBlock(self.loginStatus); } } #pragma mark - NIMLoginManagerDelegate - (void)onAutoLoginFailed:(NSError *)error { dispatch_async(dispatch_get_main_queue(), ^{ self.loginStatus = NIMSDKLoginStatusAutoLoginFailed; [self notifyStatusChange]; // 通知代理 for (id delegate in self.delegates) { if ([delegate respondsToSelector:@selector(nimSDKManager:didAutoLoginFailed:)]) { [delegate nimSDKManager:self didAutoLoginFailed:error]; } } }); } - (void)onKickout:(NIMLoginKickoutResult *)result { dispatch_async(dispatch_get_main_queue(), ^{ self.loginStatus = NIMSDKLoginStatusKickout; [self notifyStatusChange]; // 通知代理 for (id delegate in self.delegates) { if ([delegate respondsToSelector:@selector(nimSDKManager:didKickout:)]) { [delegate nimSDKManager:self didKickout:result]; } } }); } #pragma mark - NIMChatManagerDelegate - (void)onRecvMessages:(NSArray *)messages { dispatch_async(dispatch_get_main_queue(), ^{ // 通知代理 for (id delegate in self.delegates) { if ([delegate respondsToSelector:@selector(nimSDKManager:didReceiveMessages:)]) { [delegate nimSDKManager:self didReceiveMessages:messages]; } } }); } #pragma mark - NIMBroadcastManagerDelegate - (void)onReceiveBroadcastMessage:(NIMBroadcastMessage *)broadcastMessage { dispatch_async(dispatch_get_main_queue(), ^{ // 通知代理 for (id delegate in self.delegates) { if ([delegate respondsToSelector:@selector(nimSDKManager:didReceiveBroadcastMessage:)]) { [delegate nimSDKManager:self didReceiveBroadcastMessage:broadcastMessage]; } } }); } @end