// Created by Tencent on 2023/06/09. // Copyright © 2023 Tencent. All rights reserved. #import "TUILogin.h" #import "TUICore.h" #import "TUIDefine.h" @import ImSDK_Plus; NSString *const TUIInitSdkSuccessNotification = @"TUIInitSdkSuccessNotification"; NSString *const TUIInitSdkFailNotification = @"TUIInitSdkFailNotification"; NSString *const TUILoginSuccessNotification = @"TUILoginSuccessNotification"; NSString *const TUILoginFailNotification = @"TUILoginFailNotification"; NSString *const TUILogoutSuccessNotification = @"TUILogoutSuccessNotification"; NSString *const TUILogoutFailNotification = @"TUILogoutFailNotification"; @implementation TUILoginConfig - (instancetype)init { if (self = [super init]) { self.logLevel = TUI_LOG_INFO; } return self; } @end @interface TUILogin () @property(nonatomic, strong) NSHashTable *loginListenerSet; @property(nonatomic, assign) int sdkAppID; @property(nonatomic, copy) NSString *userID; @property(nonatomic, copy) NSString *userSig; @property(nonatomic, copy) NSString *nickName; @property(nonatomic, copy) NSString *faceUrl; @property(nonatomic, assign) BOOL loginWithInit; @property(nonatomic, assign) TUIBusinessScene currentBusinessScene; @end @implementation TUILogin #pragma mark - API + (void)initWithSdkAppID:(int)sdkAppID { [TUILogin.shareInstance initWithSdkAppID:sdkAppID]; } + (void)login:(NSString *)userID userSig:(NSString *)userSig succ:(TSucc)succ fail:(TFail)fail { [TUILogin.shareInstance login:userID userSig:userSig succ:succ fail:fail]; } + (void)login:(int)sdkAppID userID:(NSString *)userID userSig:(NSString *)userSig succ:(TSucc)succ fail:(TFail)fail { [TUILogin.shareInstance login:sdkAppID userID:userID userSig:userSig config:nil succ:succ fail:fail]; } + (void)login:(int)sdkAppID userID:(NSString *)userID userSig:(NSString *)userSig config:(TUILoginConfig *)config succ:(TSucc)succ fail:(TFail)fail { [TUILogin.shareInstance login:sdkAppID userID:userID userSig:userSig config:config succ:succ fail:fail]; } + (void)getSelfUserInfo { [TUILogin.shareInstance getSelfUserInfo]; } + (void)logout:(TSucc)succ fail:(TFail)fail { [TUILogin.shareInstance logout:succ fail:fail]; } + (void)addLoginListener:(id)listener { [TUILogin.shareInstance addLoginListener:listener]; } + (void)removeLoginListener:(id)listener { [TUILogin.shareInstance removeLoginListener:listener]; } + (int)getSdkAppID { return [TUILogin.shareInstance getSdkAppID]; } + (BOOL)isUserLogined { return [V2TIMManager sharedInstance].getLoginStatus == V2TIM_STATUS_LOGINED; } + (NSString *)getUserID { return [TUILogin.shareInstance getUserID]; } + (NSString *)getUserSig { return [TUILogin.shareInstance getUserSig]; } + (NSString *)getNickName { return [TUILogin.shareInstance getNickName]; } + (NSString *)getFaceUrl { return [TUILogin.shareInstance getFaceUrl]; } + (void)setCurrentBusinessScene:(TUIBusinessScene)scene { TUILogin.shareInstance.currentBusinessScene = scene; } + (TUIBusinessScene)getCurrentBusinessScene { return TUILogin.shareInstance.currentBusinessScene; } #pragma mark - Private + (instancetype)shareInstance { static id gShareInstance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ gShareInstance = [[self alloc] init]; }); return gShareInstance; } - (instancetype)init { if (self = [super init]) { _loginListenerSet = [NSHashTable weakObjectsHashTable]; _sdkAppID = 0; _userID = nil; _userSig = nil; _nickName = nil; _faceUrl = nil; _loginWithInit = NO; _currentBusinessScene = None; } return self; } - (void)initWithSdkAppID:(int)sdkAppID { if (0 != self.sdkAppID && sdkAppID != self.sdkAppID) { [self logout:nil fail:nil]; [[V2TIMManager sharedInstance] unInitSDK]; } self.sdkAppID = sdkAppID; V2TIMSDKConfig *config = [[V2TIMSDKConfig alloc] init]; config.logLevel = V2TIM_LOG_INFO; if ([[V2TIMManager sharedInstance] initSDK:sdkAppID config:config listener:nil]) { [NSNotificationCenter.defaultCenter postNotificationName:TUIInitSdkSuccessNotification object:nil]; } else { [NSNotificationCenter.defaultCenter postNotificationName:TUIInitSdkFailNotification object:nil]; } } - (void)login:(NSString *)userID userSig:(NSString *)userSig succ:(TSucc)succ fail:(TFail)fail { self.userID = userID; self.userSig = userSig; self.loginWithInit = NO; self.currentBusinessScene = None; if ([[[V2TIMManager sharedInstance] getLoginUser] isEqualToString:userID]) { if (succ) { succ(); } [NSNotificationCenter.defaultCenter postNotificationName:TUILoginSuccessNotification object:nil]; } else { __weak __typeof(self) weakSelf = self; [[V2TIMManager sharedInstance] login:userID userSig:userSig succ:^{ __strong __typeof(weakSelf) strongSelf = weakSelf; [strongSelf getSelfUserInfo]; if (succ) { succ(); } [NSNotificationCenter.defaultCenter postNotificationName:TUILoginSuccessNotification object:nil]; } fail:^(int code, NSString *desc) { if (fail) { fail(code, desc); } [NSNotificationCenter.defaultCenter postNotificationName:TUILoginFailNotification object:nil]; }]; } } - (void)login:(int)sdkAppID userID:(NSString *)userID userSig:(NSString *)userSig config:(TUILoginConfig *)config succ:(TSucc)succ fail:(TFail)fail { self.loginWithInit = YES; self.currentBusinessScene = None; if (0 != self.sdkAppID && sdkAppID != self.sdkAppID) { [self logout:nil fail:nil]; [[V2TIMManager sharedInstance] unInitSDK]; } self.sdkAppID = sdkAppID; self.userID = userID; self.userSig = userSig; V2TIMSDKConfig *sdkConfig = [[V2TIMSDKConfig alloc] init]; if (config != nil) { sdkConfig.logLevel = (V2TIMLogLevel)config.logLevel; sdkConfig.logListener = ^(V2TIMLogLevel logLevel, NSString *logContent) { if (config.onLog) { config.onLog(logLevel, logContent); } }; } else { sdkConfig.logLevel = V2TIM_LOG_INFO; } if ([[V2TIMManager sharedInstance] initSDK:sdkAppID config:sdkConfig]) { [NSNotificationCenter.defaultCenter postNotificationName:TUIInitSdkSuccessNotification object:nil]; } else { [NSNotificationCenter.defaultCenter postNotificationName:TUIInitSdkFailNotification object:nil]; } [V2TIMManager.sharedInstance addIMSDKListener:self]; [[V2TIMManager sharedInstance] callExperimentalAPI:@"getLoginAccountType" param:nil succ:^(NSObject *result) { int accountType = [((NSNumber *)result) intValue]; [TUILogin.shareInstance loginImpl:accountType userID:userID userSig:userSig config:config succ:succ fail:fail]; } fail:^(int code, NSString *desc) { [TUILogin.shareInstance loginImpl:TUI_ACCOUNT_TYPE_UNKOWN userID:userID userSig:userSig config:config succ:succ fail:fail]; }]; } - (void)loginImpl:(int)loginAccountType userID:(NSString *)userID userSig:(NSString *)userSig config:(TUILoginConfig *)config succ:(TSucc)succ fail:(TFail)fail { if ([[[V2TIMManager sharedInstance] getLoginUser] isEqualToString:userID] && loginAccountType == TUI_ACCOUNT_TYPE_IM) { if (succ) { succ(); } [NSNotificationCenter.defaultCenter postNotificationName:TUILoginSuccessNotification object:nil]; return; } if (config && config.initLocalStorageOnly) { [[V2TIMManager sharedInstance] callExperimentalAPI:@"initLocalStorage" param:self.userID succ:^(NSObject *result) { if (succ) { succ(); } } fail:^(int code, NSString *desc) { if (fail) { fail(code, desc); } }]; return; } __weak __typeof(self) weakSelf = self; [[V2TIMManager sharedInstance] login:userID userSig:userSig succ:^{ __strong __typeof(weakSelf) strongSelf = weakSelf; [strongSelf getSelfUserInfo]; if (succ) { succ(); } [NSNotificationCenter.defaultCenter postNotificationName:TUILoginSuccessNotification object:nil]; } fail:^(int code, NSString *desc) { self.loginWithInit = NO; if (fail) { fail(code, desc); } [NSNotificationCenter.defaultCenter postNotificationName:TUILoginFailNotification object:nil]; }]; } - (void)getSelfUserInfo { if (self.userID == nil) { return; } __weak typeof(self) weakSelf = self; [[V2TIMManager sharedInstance] getUsersInfo:@[ self.userID ] succ:^(NSArray *infoList) { V2TIMUserFullInfo *info = infoList.firstObject; weakSelf.nickName = info.nickName; weakSelf.faceUrl = info.faceURL; } fail:nil]; } - (void)logout:(TSucc)succ fail:(TFail)fail { self.userID = @""; self.userSig = @""; self.currentBusinessScene = None; [[V2TIMManager sharedInstance] logout:^{ if (succ) { succ(); } if (self.loginWithInit) { // The new interface is currently used to log in. When logging out, you need to deinitialize and remove the listener. [V2TIMManager.sharedInstance removeIMSDKListener:self]; [V2TIMManager.sharedInstance unInitSDK]; self.sdkAppID = 0; } [NSNotificationCenter.defaultCenter postNotificationName:TUILogoutSuccessNotification object:nil]; } fail:^(int code, NSString *desc) { if (fail) { fail(code, desc); } [NSNotificationCenter.defaultCenter postNotificationName:TUILogoutFailNotification object:nil]; }]; } - (void)addLoginListener:(id)listener { if (listener == nil) { return; } @synchronized(self) { if (![_loginListenerSet.allObjects containsObject:listener]) { [_loginListenerSet addObject:listener]; } } } - (void)removeLoginListener:(id)listener { if (listener == nil) { return; } @synchronized(self) { if ([_loginListenerSet.allObjects containsObject:listener]) { [_loginListenerSet removeObject:listener]; } } } - (int)getSdkAppID { return self.sdkAppID; } - (NSString *)getUserID { return self.userID; } - (NSString *)getUserSig { return self.userSig; } - (NSString *)getNickName { return self.nickName; } - (NSString *)getFaceUrl { return self.faceUrl; } - (void)doInMainThread:(dispatch_block_t)callback { if ([NSThread isMainThread]) { if (callback) { callback(); } return; } dispatch_async(dispatch_get_main_queue(), callback); } #pragma mark - V2TIMSDKListener - (void)onConnecting { __weak typeof(self) weakSelf = self; [self doInMainThread:^{ for (id listener in weakSelf.loginListenerSet) { if ([listener respondsToSelector:@selector(onConnecting)]) { [listener onConnecting]; } } [TUICore notifyEvent:TUICore_NetworkConnection_EVENT_CONNECTION_STATE_CHANGED subKey:TUICore_NetworkConnection_EVENT_SUB_KEY_CONNECTING object:nil param:nil]; }]; } - (void)onConnectSuccess { __weak typeof(self) weakSelf = self; [self doInMainThread:^{ for (id listener in weakSelf.loginListenerSet) { if ([listener respondsToSelector:@selector(onConnectSuccess)]) { [listener onConnectSuccess]; } } [TUICore notifyEvent:TUICore_NetworkConnection_EVENT_CONNECTION_STATE_CHANGED subKey:TUICore_NetworkConnection_EVENT_SUB_KEY_CONNECT_SUCCESS object:nil param:nil]; }]; } - (void)onConnectFailed:(int)code err:(NSString *)err { __weak typeof(self) weakSelf = self; [self doInMainThread:^{ for (id listener in weakSelf.loginListenerSet) { if ([listener respondsToSelector:@selector(onConnectFailed:err:)]) { [listener onConnectFailed:code err:err]; } } [TUICore notifyEvent:TUICore_NetworkConnection_EVENT_CONNECTION_STATE_CHANGED subKey:TUICore_NetworkConnection_EVENT_SUB_KEY_CONNECT_FAILED object:nil param:nil]; }]; } - (void)onKickedOffline { self.currentBusinessScene = None; __weak typeof(self) weakSelf = self; [self doInMainThread:^{ for (id listener in weakSelf.loginListenerSet) { if ([listener respondsToSelector:@selector(onKickedOffline)]) { [listener onKickedOffline]; } } }]; } - (void)onUserSigExpired { self.currentBusinessScene = None; __weak typeof(self) weakSelf = self; [self doInMainThread:^{ for (id listener in weakSelf.loginListenerSet) { if ([listener respondsToSelector:@selector(onUserSigExpired)]) { [listener onUserSigExpired]; } } }]; } - (void)onSelfInfoUpdated:(V2TIMUserFullInfo *)info { if (self.userID && self.userID.length > 0 && [self.userID isEqualToString:info.userID]) { self.nickName = info.nickName; self.faceUrl = info.faceURL; } } @end