// // AppDelegate.m // YUMI // // Created by admin on 2023/3/9. // #import "AppDelegate.h" #import "BaseNavigationController.h" #import #import "ClientConfig.h" #import "AccountModel.h" #import "YuMi-swift.h" #import "UIView+VAP.h" #import "SocialShareManager.h" #import "EPSignatureColorGuideView.h" #import "EPEmotionColorStorage.h" #import "EPNIMManager.h" UIKIT_EXTERN NSString * const kOpenRoomNotification; @interface AppDelegate () @end @implementation AppDelegate //日志接口 void qg_VAP_Logger_handler(VAPLogLevel level, const char* file, int line, const char* func, NSString *module, NSString *format, ...) { // 屏蔽 MP4 播放 log return; // if (format.UTF8String == nil) { // NSLog(@"log包含非utf-8字符"); // return; // } // if (level > VAPLogLevelDebug) { // va_list argList; // va_start(argList, format); // NSString* message = [[NSString alloc] initWithFormat:format arguments:argList]; // file = [NSString stringWithUTF8String:file].lastPathComponent.UTF8String; // NSLog(@"<%@> %s(%@):%s [%@] - %@",@(level), file, @(line), func, module, message); // va_end(argList); // } } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; UIStoryboard *launchStoryboard = [UIStoryboard storyboardWithName:@"Launch Screen" bundle:nil]; UIViewController *launchScreenVC = [launchStoryboard instantiateInitialViewController]; self.window.rootViewController = launchScreenVC; [self.window makeKeyAndVisible]; [VAPView registerHWDLog:qg_VAP_Logger_handler]; // 冷启动配置:client/init → client/config,由 EPConfigManager 统一调度 @kWeakify(self); [[EPConfigManager shared] startColdBootWithOnSuccess:^{ // 配置成功,初始化 NIMSDK 并进入主页面 [[EPNIMManager sharedManager] initializeWithCompletion:^(NSError * _Nullable error) { @kStrongify(self); if (error) { NSLog(@"[AppDelegate] NIMSDK 初始化失败: %@", error); } else { NSLog(@"[AppDelegate] NIMSDK 初始化成功"); } // 无论 NIMSDK 是否成功,都进入主页面 [self loadMainPage]; }]; } onFailure:^(NSString * _Nonnull errorMessage) { @kStrongify(self); // 配置失败,显示错误提示 UIAlertController *alert = [UIAlertController alertControllerWithTitle:YMLocalizedString(@"提示") message:errorMessage preferredStyle:UIAlertControllerStyleAlert]; [alert addAction:[UIAlertAction actionWithTitle:YMLocalizedString(@"确定") style:UIAlertActionStyleDefault handler:nil]]; [self.window.rootViewController presentViewController:alert animated:YES completion:nil]; }]; if (@available(iOS 15, *)) { [[UITableView appearance] setSectionHeaderTopPadding:0]; } return YES; } // MARK: - Helper Methods - (void)loadMainPage { AccountModel *accountModel = [[AccountInfoStorage instance] getCurrentAccountInfo]; if (accountModel == nil || accountModel.uid == nil || accountModel.access_token == nil) { [self toLoginPage]; }else{ [self toHomeTabbarPage]; // 延迟检查专属颜色(等待 window 初始化完成) dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.8 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self checkAndShowSignatureColorGuide]; }); } } // 移除 EPConfig 通知相关方法,改用 block 回调 /// 检查并显示专属颜色引导页 - (void)checkAndShowSignatureColorGuide { UIWindow *keyWindow = kWindow; if (!keyWindow) return; BOOL hasSignatureColor = [EPEmotionColorStorage hasUserSignatureColor]; #if 0 // Debug 环境:总是显示引导页 NSLog(@"[AppDelegate] Debug 模式:显示专属颜色引导页(已有颜色: %@)", hasSignatureColor ? @"YES" : @"NO"); EPSignatureColorGuideView *guideView = [[EPSignatureColorGuideView alloc] init]; // 设置颜色确认回调 guideView.onColorConfirmed = ^(NSString *hexColor) { [EPEmotionColorStorage saveUserSignatureColor:hexColor]; NSLog(@"[AppDelegate] 用户选择专属颜色: %@", hexColor); }; // 如果已有颜色,设置 Skip 回调 if (hasSignatureColor) { guideView.onSkipTapped = ^{ NSLog(@"[AppDelegate] 用户跳过专属颜色选择"); }; } // 显示引导页,已有颜色时显示 Skip 按钮 [guideView showInWindow:keyWindow showSkipButton:hasSignatureColor]; #else // Release 环境:仅在未设置专属颜色时显示 if (!hasSignatureColor) { EPSignatureColorGuideView *guideView = [[EPSignatureColorGuideView alloc] init]; guideView.onColorConfirmed = ^(NSString *hexColor) { [EPEmotionColorStorage saveUserSignatureColor:hexColor]; NSLog(@"[AppDelegate] 用户选择专属颜色: %@", hexColor); }; [guideView showInWindow:keyWindow]; } #endif } - (void)toLoginPage { // 使用新的 Swift 登录页面 EPLoginViewController *lvc = [[EPLoginViewController alloc] init]; BaseNavigationController *navigationController = [[BaseNavigationController alloc] initWithRootViewController:lvc]; navigationController.modalPresentationStyle = UIModalPresentationFullScreen; self.window.rootViewController = navigationController; } - (void)toHomeTabbarPage { EPTabBarController *epTabBar = [EPTabBarController create]; [epTabBar refreshTabBarWithIsLogin:YES]; UIWindow *window = kWindow; if (window) { window.rootViewController = epTabBar; [window makeKeyAndVisible]; } } - (void)applicationDidEnterBackground:(UIApplication *)application { NSInteger count = [[EPNIMManager sharedManager] allUnreadCount]; [[UIApplication sharedApplication] setApplicationIconBadgeNumber:count]; } - (void)applicationDidBecomeActive:(UIApplication *)application { [self getAdvertisingTrackingAuthority]; [[NSNotificationCenter defaultCenter]postNotificationName:@"kAppDidBecomeActive" object:nil]; } - (void)getAdvertisingTrackingAuthority { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ if (@available(iOS 14, *)) { ATTrackingManagerAuthorizationStatus status = ATTrackingManager.trackingAuthorizationStatus; switch (status) { case ATTrackingManagerAuthorizationStatusDenied: // NSLog(@"用户拒绝IDFA"); break; case ATTrackingManagerAuthorizationStatusAuthorized: // NSLog(@"用户允许IDFA"); break; case ATTrackingManagerAuthorizationStatusNotDetermined: { // NSLog(@"用户未做选择或未弹窗IDFA"); //请求弹出用户授权框,只会在程序运行是弹框1次,除非卸载app重装,通地图、相机等权限弹框一样 [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) { // NSLog(@"app追踪IDFA权限:%lu",(unsigned long)status); }]; } break; default: break; } } }); } - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { // 上传 deviceToken 至云信服务器(统一走 EPNIMManager) [[EPNIMManager sharedManager] updateApnsToken:deviceToken]; } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{ NSString *data = userInfo[@"data"]; if(data){ NSDictionary *dataDic = [data mj_JSONObject]; NSString *userId = dataDic[@"uid"]; if(userId){ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter]postNotificationName:kOpenRoomNotification object:nil userInfo:@{@"type":@"kOpenChat",@"uid":userId,@"isNoAttention":@(YES)}]; ClientConfig *config = [ClientConfig shareConfig]; config.pushChatId = userId; }); return; } } dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSString *userId = userInfo[@"uid"]; if(userId){ [[NSNotificationCenter defaultCenter]postNotificationName:kOpenRoomNotification object:nil userInfo:@{@"type":@"kOpenChat",@"uid":userId,@"isNoAttention":@(YES)}]; ClientConfig *config = [ClientConfig shareConfig]; config.pushChatId = userId; } }); } ///URL Scheme跳转 -(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options{ // TODO: 在 EPTabbar 中补充 [SocialShareManager sharedManager] setHandleJumpToRoom [[SocialShareManager sharedManager] handleURL:url]; return YES; } @end