269 lines
9.9 KiB
Objective-C
269 lines
9.9 KiB
Objective-C
//
|
||
// AppDelegate.m
|
||
// YUMI
|
||
//
|
||
// Created by admin on 2023/3/9.
|
||
//
|
||
|
||
|
||
#import "AppDelegate.h"
|
||
|
||
#import "BaseNavigationController.h"
|
||
#import <AppTrackingTransparency/AppTrackingTransparency.h>
|
||
#import "ClientConfig.h"
|
||
#import "AccountModel.h"
|
||
#import "YuMi-swift.h"
|
||
#import "EPSignatureColorGuideView.h"
|
||
#import "EPEmotionColorStorage.h"
|
||
|
||
UIKIT_EXTERN NSString * const kOpenRoomNotification;
|
||
|
||
@interface AppDelegate ()
|
||
|
||
@end
|
||
|
||
@implementation AppDelegate
|
||
|
||
- (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];
|
||
|
||
@kWeakify(self);
|
||
[[ClientConfig shareConfig] clientConfig:^{
|
||
@kStrongify(self);
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
[self loadMainPage];
|
||
});
|
||
}];
|
||
|
||
if (@available(iOS 15, *)) {
|
||
[[UITableView appearance] setSectionHeaderTopPadding:0];
|
||
}
|
||
|
||
return YES;
|
||
}
|
||
|
||
// MARK: - Helper Methods
|
||
|
||
/// 获取 keyWindow(iOS 13+ 兼容)
|
||
- (UIWindow *)getKeyWindow {
|
||
// iOS 13+ 使用 connectedScenes 获取 window
|
||
if (@available(iOS 13.0, *)) {
|
||
for (UIWindowScene *scene in [UIApplication sharedApplication].connectedScenes) {
|
||
if (scene.activationState == UISceneActivationStateForegroundActive) {
|
||
for (UIWindow *window in scene.windows) {
|
||
if (window.isKeyWindow) {
|
||
return window;
|
||
}
|
||
}
|
||
// 如果没有 keyWindow,返回第一个 window
|
||
return scene.windows.firstObject;
|
||
}
|
||
}
|
||
}
|
||
|
||
// iOS 13 以下,使用旧方法(已废弃但仍然可用)
|
||
#pragma clang diagnostic push
|
||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||
return [UIApplication sharedApplication].keyWindow;
|
||
#pragma clang diagnostic pop
|
||
}
|
||
|
||
|
||
- (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];
|
||
});
|
||
}
|
||
|
||
[[ClientConfig shareConfig] clientInit];
|
||
}
|
||
|
||
/// 检查并显示专属颜色引导页
|
||
- (void)checkAndShowSignatureColorGuide {
|
||
UIWindow *keyWindow = [self getKeyWindow];
|
||
if (!keyWindow) return;
|
||
|
||
BOOL hasSignatureColor = [EPEmotionColorStorage hasUserSignatureColor];
|
||
|
||
#if DEBUG
|
||
// 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 = [self getKeyWindow];
|
||
if (window) {
|
||
window.rootViewController = epTabBar;
|
||
[window makeKeyAndVisible];
|
||
}
|
||
}
|
||
|
||
|
||
- (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:
|
||
break;
|
||
case ATTrackingManagerAuthorizationStatusAuthorized:
|
||
break;
|
||
case ATTrackingManagerAuthorizationStatusNotDetermined: {
|
||
// NSLog(@"用户未做选择或未弹窗IDFA");
|
||
//请求弹出用户授权框,只会在程序运行是弹框1次,除非卸载app重装,通地图、相机等权限弹框一样
|
||
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
|
||
// NSLog(@"app追踪IDFA权限:%lu",(unsigned long)status);
|
||
}];
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
|
||
#pragma mark - Core Data stack
|
||
@synthesize managedObjectContext = _managedObjectContext;
|
||
@synthesize managedObjectModel = _managedObjectModel;
|
||
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
|
||
|
||
-(NSURL *)applicationDocumentsDirectory{
|
||
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
|
||
}
|
||
|
||
- (NSManagedObjectModel *)managedObjectModel {
|
||
// The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
|
||
if (_managedObjectModel != nil) {
|
||
return _managedObjectModel;
|
||
}
|
||
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"_1_______" withExtension:@"momd"];
|
||
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
|
||
return _managedObjectModel;
|
||
}
|
||
|
||
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
|
||
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it.
|
||
if (_persistentStoreCoordinator != nil) {
|
||
return _persistentStoreCoordinator;
|
||
}
|
||
|
||
// Create the coordinator and store
|
||
|
||
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
|
||
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"_1_______.sqlite"];
|
||
NSError *error = nil;
|
||
NSString *failureReason = @"There was an error creating or loading the application's saved data.";
|
||
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
|
||
// Report any error we got.
|
||
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
|
||
dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
|
||
dict[NSLocalizedFailureReasonErrorKey] = failureReason;
|
||
dict[NSUnderlyingErrorKey] = error;
|
||
error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
|
||
// Replace this with code to handle the error appropriately.
|
||
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
|
||
// NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
|
||
abort();
|
||
}
|
||
|
||
return _persistentStoreCoordinator;
|
||
}
|
||
|
||
|
||
- (NSManagedObjectContext *)managedObjectContext {
|
||
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
|
||
if (_managedObjectContext != nil) {
|
||
return _managedObjectContext;
|
||
}
|
||
|
||
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
|
||
if (!coordinator) {
|
||
return nil;
|
||
}
|
||
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
|
||
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
|
||
return _managedObjectContext;
|
||
}
|
||
|
||
#pragma mark - Core Data Saving support
|
||
|
||
- (void)saveContext {
|
||
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
|
||
if (managedObjectContext != nil) {
|
||
NSError *error = nil;
|
||
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
|
||
// Replace this implementation with code to handle the error appropriately.
|
||
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
|
||
// NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
|
||
abort();
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
@end
|