// // AppDelegate.m // 唔即云相册 // // Created by 余衡武 on 2021/12/8. // #import "AppDelegate.h" #import #import "AudioSessionObject.h" #import "DDYLanguageTool.h" #import "PLeakSniffer.h" #import "connectDeviceManager.h" #import #import #import #import #import #import //#import #import "ZFLandscapeRotationManager.h" #import #import "pingManager.h" #import "nasUploadFileManager.h" #import "imageVersionRenewTipView.h" #import "imageVersionUpdateDoneView.h" #import "imageVersionUpdateFailView.h" @interface AppDelegate () { CMMotionManager *cmManager; NSString * NASFileByBoxServiceByPingok;//内网地址 NSString * NASFileByBoxServiceByPingNot;//外网地址 } @end @implementation AppDelegate + (AppDelegate*)sharedAppDelegate { static AppDelegate *appDelegate = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ if (appDelegate == nil) { appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate]; } }); return appDelegate; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDarkContent]; //帮客户生成秘钥 // NSString *snStr = @"0333933700222450011053"; // NSString *secretkey = [RSATool sha256_8:snStr]; // HLog(@"%@",secretkey); [AMediaStream globalInitialization]; //保护App,一般常见的问题不会导致闪退,增强App的健壮性,同时会将错误抛出来,根据每个App自身的日志渠道记录 [JJException configExceptionCategory:JJExceptionGuardAll]; [JJException startGuardException]; [JJException registerExceptionHandle:self]; // //Default value:NO no表示异常不退出 YES 表示退出 开发时应该设置为YES // JJException.exceptionWhenTerminate = YES; //test code // NSArray * arr = @[]; // NSString *str = arr[2]; [self setLanguagesFun]; //设置默认值 self.couldPhone_W_PHONE = 720.0; self.couldPhone_H_PHONE = 1280.0; // self.couldPhone_W_PHONE = 1080.0; // self.couldPhone_H_PHONE = 1920.0; [[UIButton appearance] setExclusiveTouch:YES]; cmManager = [[CMMotionManager alloc] init]; if (cmManager.isAccelerometerAvailable){ HLog(@"\n-------摇一摇可用-----"); }else{ HLog(@"\n-------摇一摇不可用-----"); } cmManager.accelerometerUpdateInterval = 0.1; [cmManager startAccelerometerUpdates]; [cmManager startDeviceMotionUpdatesToQueue:[NSOperationQueue new] withHandler:^(CMDeviceMotion * _Nullable motion, NSError * _Nullable error) { // CMRotationRate rotationRate = motion.rotationRate; // CGFloat rotationRatex = rotationRate.x; // CGFloat rotationRatey = rotationRate.y; // CGFloat rotationRatez = rotationRate.z; CMAcceleration accrleration = motion.gravity; CGFloat rotationGravityz = accrleration.z; //HLog(@"rotationRatey: %f",rotationRatey) //HLog(@"rotationGravityz: %f",rotationGravityz) //if (rotationRatey > 7){ if (rotationGravityz > 0.85){ BOOL haveOpenMask = [HWDataManager getBoolWithKey:Consn_Fanzhuan_Exit_app_Open]; BOOL isPrivacyMode = ksharedAppDelegate.DeviceThirdIdMod.data.isPrivacyMode; if (haveOpenMask && isPrivacyMode){ exit(0);/*强制退出app*/ } } }]; // [[ShearDeviceUDPManager shareInstance] startShearchDevice]; // [[ShearDeviceUDPManager shareInstance] shearchDeviceLoop]; //启动后台保活 //[AudioSessionObject shareManager]; [self MonitorNetworkChangesFun]; #ifdef DEBUG [[PLeakSniffer sharedInstance] installLeakSniffer]; #else [Bugly startWithAppId:@"179559a521"]; #endif [SVProgressHUD setDefaultStyle:(SVProgressHUDStyleDark)]; [[UIDevice currentDevice] setBatteryMonitoringEnabled:YES]; [[UIDevice currentDevice] batteryLevel]; // 监听电池电量变化通知 //[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryLevelChanged:) name:UIDeviceBatteryLevelDidChangeNotification object:nil]; //微信注册 [WXApi registerApp:WXAPPid universalLink:wxuniversalLink]; [TencentOAuth setIsUserAgreedAuthorization:YES]; TencentOAuth *tencentOAuth =[[TencentOAuth alloc] initWithAppId:QQAPPid andUniversalLink:QQUniversalLink andDelegate:self]; [self imageLoadingSettings]; _WebRtcLogger = [[RTCFileLogger alloc] initWithDirPath:kSHPath_logs maxFileSize:10*1024*1024]; HLog(@"_WebRtcLogger: %@", _WebRtcLogger); return YES; } /// 在这里写支持的旋转方向,为了防止横屏方向,应用启动时候界面变为横屏模式 - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { ZFInterfaceOrientationMask orientationMask = [ZFLandscapeRotationManager supportedInterfaceOrientationsForWindow:window]; if (orientationMask != ZFInterfaceOrientationMaskUnknow) { return (UIInterfaceOrientationMask)orientationMask; } HLog(@"处理旋转屏幕:%d",self.supportScreenRotateType) //显示密码了 if(ksharedAppDelegate.isDidShowPwdType){ return UIInterfaceOrientationMaskPortrait; } if(self.supportScreenRotateType){ return UIInterfaceOrientationMaskAllButUpsideDown; } if(self.isPlayerScreenLandscapeType){ return UIInterfaceOrientationMaskLandscapeRight; } return UIInterfaceOrientationMaskPortrait; } - (void)applicationWillTerminate:(UIApplication *)application { // [AMediaStream globalDeinitialization]; } #pragma mark - UISceneSession lifecycle - (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options { // Called when a new scene session is being created. // Use this method to select a configuration to create the new scene with. return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role]; } - (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet *)sceneSessions { // Called when the user discards a scene session. // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. // Use this method to release any resources that were specific to the discarded scenes, as they will not return. } - (void)applicationWillEnterForeground:(UIApplication *)application { // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSString *orderNumber = [HWDataManager getStringWithKey:Const_AirpayOrWXorderNum]; if (orderNumber && ![orderNumber isEqualToString:@""]) { [[NSNotificationCenter defaultCenter] postNotificationName:NotNameAirpayOrWXorderNum object:orderNumber]; } }); } - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { return [WXApi handleOpenURL:url delegate:self]; } - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { if (YES == [TencentOAuth CanHandleOpenURL:url]) { return [TencentOAuth HandleOpenURL:url]; } return [WXApi handleOpenURL:url delegate:self]; } - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray> * _Nullable))restorationHandler { if([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) { NSURL *url = userActivity.webpageURL; if(url && [TencentOAuth CanHandleUniversalLink:url]) { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"CI UniversalLink" message:url.description delegate:nil cancelButtonTitle:@"ok" otherButtonTitles:nil, nil]; [alertView show]; //[QQApiInterface handleOpenUniversallink:url delegate:(id)[QQApiShareEntry class]]; return [TencentOAuth HandleUniversalLink:url]; } } return [WXApi handleOpenUniversalLink:userActivity delegate:self]; } #pragma mark 监听网络变化 -(void)MonitorNetworkChangesFun { [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { HLog(@"Reachability: %@", AFStringFromNetworkReachabilityStatus(status)); mainBlock((^{ //[[iToast makeText:[[NSString alloc] initWithFormat:@"Reachability:%@",AFStringFromNetworkReachabilityStatus(status)] ] show]; [[NSNotificationCenter defaultCenter] postNotificationName:NetWorkChangeNotification object:nil]; })); //网络切换 [self handelNetWorkChangeFunBy:status]; }]; [[AFNetworkReachabilityManager sharedManager] startMonitoring]; } #pragma mark 处理网络切换情况 - (void)handelNetWorkChangeFunBy:(AFNetworkReachabilityStatus)status { if(status == AFNetworkReachabilityStatusReachableViaWiFi){//检测到起切换wifi 重新ping一下 [[pingManager shareManager] startPingDeviceIpFun]; } else {//非wifi链接 [pingManager shareManager].isPingOk = NO; } //是否备份中 处理切换网络环境 用户无感备份切换 if(([nasBackupsManager shareInstance].curPhotosBackupsTaskMod && [nasBackupsManager shareInstance].curPhotosBackupsTaskMod.curBackupsState == backupsStateUploading) || [nasBackupsManager shareInstance].isWifiNeedReBackupsType){ //1.先暂停备份 [[nasBackupsManager shareInstance] suspendBackupsFileFun]; //2.重新开启备份 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [[nasBackupsManager shareInstance] reBackupsFileFun]; }); } //是否上传中 处理切换网络环境 用户无感上传切换 BOOL needToReUploadTaskType = [nasUploadFileManager shareInstance].needToReUploadTaskType; if(needToReUploadTaskType){//如果网络层先保存 这里为YES dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [[nasUploadFileManager shareInstance] reUploadFileFunByNetWork]; }); } else{ //有可能是网络变化先收到通知 if([nasUploadFileManager shareInstance].uploadingArr.count > 0){ [[nasUploadFileManager shareInstance] saveUploadingTaskByNetWorkErrorFun]; //因为不知道是网络变化通知快 还是传输快 这里5秒后重新传 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [[nasUploadFileManager shareInstance] reUploadFileFunByNetWork]; }); } } //HLog(@"hxd 1111") //是否下载中 处理切换网络环境 用户无感下载切换 BOOL needToReDownloadTaskType = [nasDownloadFileManager shareInstance].needToReDownloadTaskType; if(needToReDownloadTaskType){//如果网络层先保存 这里为YES //HLog(@"hxd 2222") dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [[nasDownloadFileManager shareInstance] reDownloadloadFileFunByNetWork]; }); } else{ //HLog(@"hxd 3333") //有可能是网络变化先收到通知 if([nasDownloadFileManager shareInstance].downLoadFileModelDataArr.count > 0){ //HLog(@"hxd 4444") [[nasDownloadFileManager shareInstance] saveDownloadloadingTaskByNetWorkErrorFun]; //因为不知道是网络变化通知快 还是传输快 这里5秒后重新传 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [[nasDownloadFileManager shareInstance] reDownloadloadFileFunByNetWork]; }); } } } #pragma mark 多国语言相关 -(void)setLanguagesFun{ NSArray *arLanguages = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"]; NSLog(@"arLanguages:%@",arLanguages); ///获取设备当前地区的代码和APP语言环境 NSString *languageCode = [NSLocale preferredLanguages][0]; // 获取国际通用国家地区代码(应该和手机本身有关) NSString *countryCode = [NSString stringWithFormat:@"-%@", [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode]]; // if (languageCode) { // languageCode = [languageCode stringByReplacingOccurrencesOfString:countryCode withString:@""]; // } NSLog(@"countryCode:%@ languageCode : %@",countryCode, languageCode); ///当前APP使用的语言 NSString *preferredLanguage = [[[NSBundle mainBundle] preferredLocalizations] firstObject]; //获取设备当前地区的代码和APP语言环境 NSString *localeIdentifier = [[NSLocale currentLocale] objectForKey:NSLocaleIdentifier]; NSLog(@"preferredLanguage:%@ localeIdentifier : %@",preferredLanguage, localeIdentifier); //目前支持 中文(简体 繁体) 英文 日语(还没做) if([languageCode rangeOfString:preferredLanguage].location != NSNotFound){ // if([preferredLanguage rangeOfString:@"ja"].location != NSNotFound){ // //日文现在也显示英文 // [self setDefaultEnglishFun]; // } // else { [DDYLanguageTool ddy_SetLanguage:@"" complete:^(NSError *error) { // 刷新rootVC等 }]; } } else{ [self setDefaultEnglishFun]; } } #pragma mark 设置当前显示语言为中文 - (void)setDefaultEnglishFun{ //默认设为英文 [DDYLanguageTool ddy_SetLanguage:@"en" complete:^(NSError *error) { // 刷新rootVC等 }]; } - (void)batteryLevelChanged:(NSNotification *)notification { // 获取当前设备的电池电量 UIDevice *device = notification.object; float batteryLevel = device.batteryLevel; // 根据电量级别执行相应的操作 if (batteryLevel < 0.2) { NSLog(@"Low battery level. Please charge the device."); } else if (batteryLevel < 0.5) { NSLog(@"Medium battery level."); } else { NSLog(@"High battery level."); } } - (void)handleCrashException:(NSString*)exceptionMessage exceptionCategory:(JJExceptionGuardCategory)exceptionCategory extraInfo:(nullable NSDictionary*)info{ NSMutableString *totalLogstr = [NSMutableString new]; if(exceptionMessage){ [totalLogstr appendString:exceptionMessage]; [totalLogstr appendString:@"\n\n\n"]; } if(info){ NSData *jsonData = [NSJSONSerialization dataWithJSONObject:info options:info error:nil]; if(jsonData && jsonData.length>0){ NSString *jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; if(jsonStr){ [totalLogstr appendString:jsonStr]; } } } //写日志 if(totalLogstr && totalLogstr.length >0){ [cachesFileManager writeCrashLogsWithMsg:totalLogstr]; } } - (NSString*)NASShareFileService { //http://transfer.armclouding.com:10012/getFile?path=/sdcard/Download/mmexport1712039794930_4124382.png if(_NASShareFileService && _NASShareFileService.length >0){ return _NASShareFileService; } if(_NASMsgMod){ if([_NASMsgMod.data.domainName rangeOfString:@"http"].location != NSNotFound){ _NASShareFileService = [[NSString alloc] initWithFormat:@"%@:%@/",_NASMsgMod.data.domainName,_NASMsgMod.data.port]; //return [[NSString alloc] initWithFormat:@"%@:%@/",@"http://transfer.armclouding.com",@"10016"]; //return [[NSString alloc] initWithFormat:@"%@:%@/",@"http://transfer.armclouding.com",_NASMsgMod.data.port]; } else{ _NASShareFileService = [[NSString alloc] initWithFormat:@"http://%@:%@/",_NASMsgMod.data.domainName,_NASMsgMod.data.port]; //return [[NSString alloc] initWithFormat:@"http://%@:%@/",@"transfer.armclouding.com",@"10016"]; //return [[NSString alloc] initWithFormat:@"http://%@:%@/",@"transfer.armclouding.com",_NASMsgMod.data.port]; } //return [[NSString alloc] initWithFormat:@"%@getFile?path=",_NASMsgMod.data.baseUrl]; //return [[NSString alloc] initWithFormat:@"%@/",_NASMsgMod.data.baseUrl]; } return _NASShareFileService; } - (NSString*)NASFileByBoxService { //内网情况 if([pingManager shareManager].isPingOk){ if(NASFileByBoxServiceByPingok && NASFileByBoxServiceByPingok.length >0){ return NASFileByBoxServiceByPingok; } NASFileByBoxServiceByPingok = [NSString stringWithFormat:@"http://%@:9888/",ksharedAppDelegate.DeviceThirdIdMod.data.ip]; return NASFileByBoxServiceByPingok; } //外网情况 if(_NASMsgMod){ if(NASFileByBoxServiceByPingNot && NASFileByBoxServiceByPingNot.length >0){ return NASFileByBoxServiceByPingNot; } if([_NASMsgMod.data.domainName rangeOfString:@"http"].location != NSNotFound){ NASFileByBoxServiceByPingNot = [[NSString alloc] initWithFormat:@"%@:%@/",_NASMsgMod.data.domainName,_NASMsgMod.data.port]; } else{ NASFileByBoxServiceByPingNot = [[NSString alloc] initWithFormat:@"http://%@:%@/",_NASMsgMod.data.domainName,_NASMsgMod.data.port]; } return NASFileByBoxServiceByPingNot; } return @""; } #pragma mark 更换设备 重新设置地址 - (void)resetBoxNetUrlFun { _NASShareFileService = nil; NASFileByBoxServiceByPingok = nil; NASFileByBoxServiceByPingNot = nil; } - (void)imageLoadingSettings { [SDImageCache sharedImageCache].config.maxDiskAge = 3600 * 24 * 7; [SDImageCache sharedImageCache].config.maxMemoryCount = 1024 * 1024 * 20; [SDImageCache sharedImageCache].config.shouldCacheImagesInMemory = YES; //[SDImageCache sharedImageCache].config.shouldDecompressImages = NO; //[SDWebImageDownloader sharedDownloader].shouldDecompressImages = NO; [SDImageCache sharedImageCache].config.diskCacheReadingOptions = NSDataReadingMappedIfSafe; } - (BOOL)didShowImageRenewViewFun{ NSArray *subViews = ksharedAppDelegate.window.subviews; for (UIView*view in subViews) { if([view isKindOfClass:[imageVersionRenewTipView class]] ||[view isKindOfClass:[imageVersionUpdateDoneView class]] ||[view isKindOfClass:[imageVersionUpdateFailView class]]){ return YES; } } return NO; } @end