AppDelegate.m 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009
  1. //
  2. // AppDelegate.m
  3. // KulexiuForTeacher
  4. //
  5. // Created by Kyle on 2022/3/16.
  6. //
  7. #import "AppDelegate.h"
  8. #import "KSTabBarViewController.h"
  9. #import "InstitutionTabBarController.h"
  10. #import <AppTrackingTransparency/AppTrackingTransparency.h>
  11. #import "KSUpdateManager.h"
  12. #import "KSUpdateAlert.h"
  13. #import <KSToolLibrary/KSNetworkAccessibleManager.h>
  14. #import <Bugly/Bugly.h>
  15. #import <UMCommon/UMCommon.h>
  16. #import <UMShare/UMShare.h>
  17. #import <UShareUI/UShareUI.h>
  18. // 引入 JPush 功能所需头文件
  19. #import "JPUSHService.h"
  20. // iOS10 注册 APNs 所需头文件
  21. #ifdef NSFoundationVersionNumber_iOS_9_x_Max
  22. #import <UserNotifications/UserNotifications.h>
  23. #endif
  24. #import <KSToolLibrary/UrlDecode.h>
  25. #import "KSBaseWKWebViewController.h"
  26. #import "UserInfoManager.h"
  27. #import "WXApi.h"
  28. #import "GuideViewController.h"
  29. #import "HomeworkDetailViewController.h"
  30. #import "MyCourseViewController.h"
  31. #import "NotiferMessageViewController.h"
  32. #import "TenantNotiferCenterController.h"
  33. #import "LaunchAnimationViewController.h"
  34. #import "KSEnterLiveroomManager.h"
  35. #import "TXIMLinsenter.h"
  36. #import <TUICore/TUIConfig.h>
  37. #import <TUIChat/TUIChat.h>
  38. #import "FeedbackListViewController.h"
  39. @import TXLiteAVSDK_Professional;
  40. @interface AppDelegate ()<WXApiDelegate,JPUSHRegisterDelegate,V2TXLivePremierObserver>
  41. @property (nonatomic, assign) BOOL isNeedUpdate;
  42. @property (nonatomic, strong) NSTimer *timer;
  43. @property (nonatomic, strong) KSUpdateAlert *alertView;
  44. @property (nonatomic, assign) BOOL hasCheckTrackAuth;
  45. @end
  46. @implementation AppDelegate
  47. //此方法会在设备横竖屏变化的时候调用
  48. - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
  49. if (_allowAutoRotate) {
  50. //只支持横屏
  51. return UIInterfaceOrientationMaskLandscapeRight;
  52. }else{
  53. //支持竖屏
  54. return UIInterfaceOrientationMaskPortrait;
  55. }
  56. }
  57. - (void)networkEnableCheck {
  58. [KSNetworkAccessibleManager setAlertEnable:YES];
  59. [KSNetworkAccessibleManager setStateDidUpdateNotifier:^(KSNetworkAccessibleState state) {
  60. NSLog(@"setStateDidUpdateNotifier > %zd", state);
  61. }];
  62. [KSNetworkAccessibleManager start];
  63. }
  64. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  65. // Override point for customization after application launch.
  66. [self configCertConfig];
  67. [self networkEnableCheck];
  68. [self initTXRTCConfig];
  69. [self registerSDK];
  70. [Bugly startWithAppId:@"adfcb3bc3d"];
  71. if (@available(iOS 13.0, *)) {
  72. [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDarkContent;
  73. } else {
  74. // Fallback on earlier versions
  75. [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;
  76. }
  77. // 全局配置光标颜色
  78. [[UITextField appearance] setTintColor:CLIENT_THEMECOLOR];
  79. [[UITextView appearance] setTintColor:CLIENT_THEMECOLOR];
  80. // 配置极光推送
  81. [self configJPUSHWithLaunchOptions:launchOptions];
  82. // 腾讯群相关
  83. [self configTXIM];
  84. LaunchAnimationViewController *animationVC = [[LaunchAnimationViewController alloc] init];
  85. MJWeakSelf;
  86. [animationVC launchAnimationFinish:^{
  87. [weakSelf configRootVC];
  88. }];
  89. self.window.rootViewController = animationVC;
  90. [self.window makeKeyAndVisible];
  91. if (@available(iOS 15.0, *)) {
  92. UITableView.appearance.sectionHeaderTopPadding = 0;
  93. }
  94. if (IOS11) {
  95. UITableView.appearance.estimatedRowHeight = 0;
  96. UITableView.appearance.estimatedSectionFooterHeight = 0;
  97. UITableView.appearance.estimatedSectionHeaderHeight = 0;
  98. } else {
  99. }
  100. // keyboardManager
  101. [IQKeyboardManager sharedManager].enable = YES;
  102. [IQKeyboardManager sharedManager].toolbarManageBehaviour = IQAutoToolbarByPosition;
  103. [IQKeyboardManager sharedManager].enableAutoToolbar = YES;
  104. [IQKeyboardManager sharedManager].keyboardDistanceFromTextField = 10.0f;
  105. [IQKeyboardManager sharedManager].shouldResignOnTouchOutside = YES;
  106. /**
  107. * 推送处理 1
  108. */
  109. [self registerRemoteNotification:application];
  110. [UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[UIDocumentBrowserViewController class]]].tintColor = CLIENT_THEMECOLOR;
  111. [self openServer];
  112. return YES;
  113. }
  114. - (void)configCertConfig {
  115. [KSNetworkingManager configCertConfig];
  116. }
  117. - (void)refreshThemeColorAndConfig {
  118. // 全局配置光标颜色
  119. NSLog(@"------ %zd",[UserDefaultObjectForKey(TENANT_ID) integerValue]);
  120. [[UITextField appearance] setTintColor:CLIENT_THEMECOLOR];
  121. [[UITextView appearance] setTintColor:CLIENT_THEMECOLOR];
  122. [UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[UIDocumentBrowserViewController class]]].tintColor = CLIENT_THEMECOLOR;
  123. TUIConfig *config = [TUIConfig defaultConfig];
  124. config.defaultGroupAvatarImage = [UIImage imageNamed:CLIENT_GROUP_LOGO];
  125. }
  126. - (void)configRootVC {
  127. [APPLOGIN_MANAGER configSetting];
  128. BOOL hasLaunchGuide = UserDefaultBoolForKey(FIRST_LOGIN_KEY);
  129. if (hasLaunchGuide == NO) {
  130. GuideViewController *guideVC = [[GuideViewController alloc] init];
  131. CustomNavViewController *navCtrl = [[CustomNavViewController alloc] initWithRootViewController:guideVC];
  132. self.window.rootViewController = navCtrl;
  133. }
  134. else {
  135. NSString *token = UserDefault(TokenKey);
  136. if ([NSString isEmptyString:token]) { // 未登录
  137. LoginViewController *logonVC = [[LoginViewController alloc] init];
  138. CustomNavViewController *navCtrl = [[CustomNavViewController alloc] initWithRootViewController:logonVC];
  139. self.window.rootViewController = navCtrl;
  140. }
  141. else {
  142. [KSNetworkingManager configRequestHeader];
  143. NSInteger tenantId = [UserDefaultObjectForKey(TENANT_ID) integerValue];
  144. if (tenantId > 0) {
  145. [KSNetworkingManager addHeader:[NSString stringWithFormat:@"%zd", tenantId] forKey:@"coopId"];
  146. }
  147. [USER_MANAGER queryUserInfoSendLoginUMCount];
  148. [self initTableBar];
  149. }
  150. }
  151. [self versionCheck];
  152. }
  153. - (void)displayUnreadMessageCount {
  154. [self countUnreadMessage];
  155. }
  156. - (void)registerSDK {
  157. NSString *universalLinkUrl = [NSString stringWithFormat:@"%@%@",@"https://online.colexiu.com",@"/studentApp/"];
  158. [WXApi registerApp:@"wx97408cd22c879ff7" universalLink:universalLinkUrl];
  159. }
  160. - (void)appTrackActionAuth {
  161. if (self.hasCheckTrackAuth == NO) {
  162. if (@available(iOS 14, *)) {
  163. [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
  164. dispatch_main_async_safe(^{
  165. [self configUM];
  166. });
  167. }];
  168. } else {
  169. // Fallback on earlier versions
  170. [self configUM];
  171. }
  172. self.hasCheckTrackAuth = YES;
  173. }
  174. }
  175. - (void)configUM {
  176. [UMConfigure initWithAppkey:@"62a2a806eae04539a8e253ed" channel:@"App Store"];
  177. #ifdef DEBUG
  178. [UMConfigure setLogEnabled:YES];
  179. #endif
  180. // 配置友盟分享
  181. // 微信、QQ、微博完整版会校验合法的universalLink,不设置会在初始化平台失败
  182. //配置微信Universal Link需注意 universalLinkDic的key是rawInt类型,不是枚举类型 ,即为 UMSocialPlatformType.wechatSession.rawInt
  183. NSString *callbackUrl = [NSString stringWithFormat:@"%@%@",@"https://online.colexiu.com",@"/studentApp/"];
  184. [UMSocialGlobal shareInstance].universalLinkDic = @{@(UMSocialPlatformType_WechatSession):callbackUrl,@(UMSocialPlatformType_Sina):callbackUrl};
  185. /* 设置微信的appKey和appSecret */
  186. [[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_WechatSession appKey:@"wx97408cd22c879ff7" appSecret:@"d3f119b577ccacb262da153f4210174f" redirectURL:nil];
  187. /*
  188. * 移除相应平台的分享,如微信收藏
  189. */
  190. [[UMSocialManager defaultManager] removePlatformProviderWithPlatformTypes:@[@(UMSocialPlatformType_WechatFavorite)]];
  191. /* 设置sina */
  192. [[UMSocialManager defaultManager] setPlaform:UMSocialPlatformType_Sina appKey:@"3712190405" appSecret:@"e77924e0125dbd751bab61063d8338fb" redirectURL:nil];
  193. // 自定义分享类型
  194. [UMSocialUIManager addCustomPlatformWithoutFilted:UMSocialPlatformType_UserDefine_Begin+1 withPlatformIcon:[UIImage imageNamed:@"share_group"] withPlatformName:@"群聊"];
  195. // [UMSocialUIManager addCustomPlatformWithoutFilted:UMSocialPlatformType_UserDefine_Begin+2 withPlatformIcon:[UIImage imageNamed:@"share_savePic"] withPlatformName:@"保存图片"];
  196. }
  197. - (void)versionCheck {
  198. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  199. [KSUpdateManager ks_updateWithAPPID:@"1626971695" withBundleId:nil block:^(NSString * _Nonnull currentVersion, NSString * _Nonnull storeVersion, NSString * _Nonnull openUrl, BOOL isUpdate) {
  200. if (isUpdate) {
  201. [KSNetworkingManager appVersionInfoRequest:KS_GET success:^(NSDictionary * _Nonnull dic) {
  202. if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
  203. NSString *serviceVersion = [[dic ks_dictionaryValueForKey:@"data"] ks_stringValueForKey:@"version"];
  204. if ([serviceVersion isEqualToString:storeVersion] || [self isLowerVersionCompareLocalVersion:currentVersion serviceVersion:serviceVersion]) {
  205. // desc
  206. NSString *descMessage = [[dic ks_dictionaryValueForKey:@"data"] ks_stringValueForKey:@"description"];
  207. // 判断
  208. if ([[dic ks_dictionaryValueForKey:@"data"] ks_boolValueForKey:@"isForceUpdate"]) {
  209. self.isNeedUpdate = YES;
  210. [self showAlertWithMemo:storeVersion descMessage:descMessage isforce:YES openUrl:openUrl];
  211. }
  212. else {
  213. self.isNeedUpdate = NO;
  214. [self showAlertWithMemo:storeVersion descMessage:descMessage isforce:NO openUrl:openUrl];
  215. }
  216. }
  217. }
  218. } faliure:^(NSError * _Nonnull error) {
  219. [self showAlertWithMemo:storeVersion descMessage:@"全新版本上线了,赶快来体验吧!" isforce:NO openUrl:openUrl];
  220. }];
  221. }
  222. else {
  223. NSLog(@"当前版本%@,商店版本%@,不需要更新",currentVersion,storeVersion);
  224. }
  225. }];
  226. });
  227. }
  228. /**
  229. 极光推送
  230. */
  231. - (void)configJPUSHWithLaunchOptions:(NSDictionary *)launchOptions {
  232. // 3.0.0及以后版本注册
  233. JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
  234. if (@available(iOS 12.0, *)) {
  235. entity.types = JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSound|JPAuthorizationOptionProvidesAppNotificationSettings;
  236. } else {
  237. entity.types = JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSound;
  238. }
  239. if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
  240. }
  241. [JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
  242. //如不需要使用IDFA,advertisingIdentifier 可为nil
  243. [JPUSHService setupWithOption:launchOptions appKey:@"911d07f359c18a078f29792f"
  244. channel:nil
  245. apsForProduction:JSPUSH_ENVIRONMENT
  246. advertisingIdentifier:nil];
  247. }
  248. - (void)initTXRTCConfig {
  249. [V2TXLivePremier setLicence:CONFIG_TXLiveLicenceURL key:CONFIG_TXLiveLicenceKey];
  250. [V2TXLivePremier setObserver:self];
  251. NSLog(@"SDK Version = %@", [V2TXLivePremier getSDKVersionStr]);
  252. }
  253. - (void)configTXIM {
  254. TUIConfig *config = [TUIConfig defaultConfig];
  255. // 修改默认头像
  256. config.defaultAvatarImage = [UIImage imageNamed:STUDENT_AVATAR];
  257. // 修改默认群组头像
  258. config.defaultGroupAvatarImage = [UIImage imageNamed:CLIENT_GROUP_LOGO];
  259. // 禁用群组九宫格头像
  260. config.avatarType = TAvatarTypeRounded;
  261. config.enableGroupGridAvatar = NO;
  262. // 关闭toaset
  263. config.enableToast = NO;
  264. TUIChatConfig *chatConfig = [TUIChatConfig defaultConfig];
  265. chatConfig.backgroudColor = HexRGB(0xF8F8F8);
  266. chatConfig.enableWelcomeCustomMessage = NO;
  267. chatConfig.enableTypingStatus = YES;
  268. }
  269. #pragma mark - private method
  270. - (void)registerRemoteNotification:(UIApplication *)application {
  271. /**
  272. * 推送说明:
  273. *
  274. 我们在知识库里还有推送调试页面加了很多说明,当遇到推送问题时可以去知识库里搜索还有查看推送测试页面的说明。
  275. *
  276. 首先必须设置deviceToken,可以搜索本文件关键字“推送处理”。模拟器是无法获取devicetoken,也就没有推送功能。
  277. *
  278. 当使用"开发/测试环境"的appkey测试推送时,必须用Development的证书打包,并且在后台上传"开发/测试环境"的推送证书,证书必须是development的。
  279. 当使用"生产/线上环境"的appkey测试推送时,必须用Distribution的证书打包,并且在后台上传"生产/线上环境"的推送证书,证书必须是distribution的。
  280. */
  281. #pragma clang diagnostic push
  282. #pragma clang diagnostic ignored "-Wdeprecated-declarations"
  283. if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
  284. //注册推送, 用于iOS8以及iOS8之后的系统
  285. UIUserNotificationSettings *settings = [UIUserNotificationSettings
  286. settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)
  287. categories:nil];
  288. [application registerUserNotificationSettings:settings];
  289. } else {
  290. //注册推送,用于iOS8之前的系统
  291. UIRemoteNotificationType myTypes =
  292. UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
  293. [application registerForRemoteNotificationTypes:myTypes];
  294. }
  295. #pragma clang diagnostic pop
  296. }
  297. /**
  298. * 推送处理2
  299. */
  300. //注册用户通知设置
  301. #pragma clang diagnostic push
  302. #pragma clang diagnostic ignored "-Wdeprecated-declarations"
  303. #pragma clang diagnostic ignored "-Wdeprecated-implementations"
  304. - (void)application:(UIApplication *)application
  305. didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
  306. [application registerForRemoteNotifications];
  307. }
  308. #pragma clang diagnostic pop
  309. /**
  310. * 推送处理3
  311. */
  312. - (void)application:(UIApplication *)application
  313. didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  314. // 注册极光deviceToken
  315. /// Required - 注册 DeviceToken
  316. [JPUSHService registerDeviceToken:deviceToken];
  317. if ([TXIM_LINSENTER isCurrentUserLoginIM]) {
  318. [self registerTXIMDeviceToken:deviceToken];
  319. }
  320. else {
  321. self.deviceToken = deviceToken;
  322. }
  323. }
  324. - (void)registerTXIMDeviceToken:(NSData *)deviceToken {
  325. if (deviceToken) {
  326. V2TIMAPNSConfig *config = [[V2TIMAPNSConfig alloc] init];
  327. config.businessID = TXOfflinePushCertificateIDForAPNS;
  328. config.token = deviceToken;
  329. [[V2TIMManager sharedInstance] setAPNS:config succ:^{
  330. NSLog(@"%s, succ", __func__);
  331. } fail:^(int code, NSString *desc) {
  332. NSLog(@"%s, fail, %d, %@", __func__, code, desc);
  333. }];
  334. }
  335. }
  336. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  337. // 极光推送
  338. [JPUSHService handleRemoteNotification:userInfo];
  339. }
  340. /**
  341. * 推送处理4
  342. * userInfo内容请参考官网文档
  343. */
  344. #pragma clang diagnostic push
  345. #pragma clang diagnostic ignored "-Wdeprecated-implementations"
  346. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
  347. // 极光推送
  348. [JPUSHService handleRemoteNotification:userInfo];
  349. }
  350. #pragma clang diagnostic pop
  351. - (void)applicationDidEnterBackground:(UIApplication *)application {
  352. // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
  353. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
  354. // 后台情况下如果持续时间超过3分钟,主动退出房间
  355. self.timer = [NSTimer scheduledTimerWithTimeInterval:180.0f target:self selector:@selector(quitClassRoom) userInfo:nil repeats:NO];
  356. [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
  357. // 退到后台发送消息
  358. [[NSNotificationCenter defaultCenter] postNotificationName:@"appEnterBackground" object:nil];
  359. if (_isServiceStart){//停止本地服务器
  360. [self stopServer];
  361. }
  362. }
  363. - (void)quitClassRoom {
  364. [[NSNotificationCenter defaultCenter] postNotificationName:@"backgroundQuit" object:nil];
  365. }
  366. - (void)applicationWillEnterForeground:(UIApplication *)application {
  367. // 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.
  368. if (self.timer) {
  369. [self.timer invalidate];
  370. self.timer = nil;
  371. }
  372. if (self.isNeedUpdate) {
  373. [self versionCheck];
  374. }
  375. [self checkConnectionStatus];
  376. // 退到后台发送消息
  377. [[NSNotificationCenter defaultCenter] postNotificationName:@"appEnterForeground" object:nil];
  378. if (!_isServiceStart){
  379. _isServiceStart = [self startServer];
  380. }
  381. }
  382. - (void)checkConnectionStatus {
  383. BOOL isConnected = [TXIM_LINSENTER isCurrentUserLoginIM];
  384. NSString *token = UserDefault(TokenKey);
  385. if (isConnected == NO && ![NSString isEmptyString:token]) { // 连接失败或未连接 需要重新连接
  386. [USER_MANAGER checkTokenEnableConnectIM];
  387. }
  388. }
  389. - (void)applicationDidBecomeActive:(UIApplication *)application {
  390. // app启动或者app从后台进入前台都会调用这个方法
  391. [JPUSHService resetBadge]; // 清空 JPush 服务器中存储的 badge 值
  392. // 退到后台发送消息
  393. [[NSNotificationCenter defaultCenter] postNotificationName:@"appDidBecomeActive" object:nil];
  394. }
  395. - (void)applicationWillTerminate:(UIApplication *)application {
  396. // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
  397. }
  398. #pragma mark- JPUSHRegisterDelegate
  399. - (void)jpushNotificationAuthorization:(JPAuthorizationStatus)status withInfo:(NSDictionary *)info {
  400. NSLog(@"receive notification authorization status:%lu, info:%@", status, info);
  401. }
  402. #ifdef __IPHONE_12_0
  403. - (void)jpushNotificationCenter:(UNUserNotificationCenter *)center openSettingsForNotification:(UNNotification *)notification {
  404. NSString *title = nil;
  405. if (notification) {
  406. title = @"从通知界面直接进入应用";
  407. }else{
  408. title = @"从系统设置界面进入应用";
  409. }
  410. NSLog(@"%@", title);
  411. }
  412. #endif
  413. // iOS 10 Support
  414. - (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler API_AVAILABLE(ios(10.0)){
  415. // Required
  416. NSDictionary * userInfo = notification.request.content.userInfo;
  417. if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
  418. [JPUSHService handleRemoteNotification:userInfo];
  419. }
  420. if (@available(iOS 10.0, *)) {
  421. // completionHandler(UNNotificationPresentationOptionAlert);
  422. completionHandler(UNNotificationPresentationOptionAlert|UNNotificationPresentationOptionSound);
  423. } else {
  424. // Fallback on earlier versions
  425. } // 需要执行这个方法,选择是否提醒用户,有 Badge、Sound、Alert 三种类型可以选择设置
  426. }
  427. // iOS 10 Support
  428. - (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler API_AVAILABLE(ios(10.0)){
  429. // Required
  430. NSDictionary * userInfo = response.notification.request.content.userInfo;
  431. if (@available(iOS 10.0, *)) {
  432. if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
  433. [JPUSHService handleRemoteNotification:userInfo];
  434. }
  435. else {
  436. }
  437. } else {
  438. // Fallback on earlier versions
  439. }
  440. completionHandler(); // 系统要求执行这个方法
  441. NSMutableDictionary *infoDict = [NSMutableDictionary dictionaryWithDictionary:userInfo];
  442. [self getVCUserInfoDict:infoDict];
  443. [JPUSHService resetBadge]; // 清空 JPush 服务器中存储的 badge 值
  444. }
  445. #pragma mark 根据不同消息跳转不同界面
  446. - (void)getVCUserInfoDict:(NSMutableDictionary *)infoDict {
  447. BOOL isJPush = [[infoDict allKeys] containsObject:@"_j_msgid"]; // 极光推送标识区分
  448. if (isJPush) {
  449. if (![NSString isEmptyString:[infoDict ks_stringValueForKey:@"memo"]]) {
  450. NSData *jsonData = [[infoDict ks_stringValueForKey:@"memo"] mj_JSONData];
  451. NSError *error;
  452. NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
  453. if (!error) {
  454. UIViewController *vc = self.window.rootViewController;
  455. NSString *token = UserDefault(TokenKey);
  456. if ([vc isKindOfClass:[LaunchAnimationViewController class]] || [NSString isEmptyString:token]) {
  457. self.outLinkParm = [NSMutableDictionary dictionaryWithDictionary:dict];
  458. return;
  459. }
  460. [self handSource:dict];
  461. }
  462. }
  463. }
  464. else {
  465. // 跳转到第二个页面
  466. [self.tabBarController tabBarSelectedWithIndex:2];
  467. }
  468. }
  469. - (BOOL)isLowerVersionCompareLocalVersion:(NSString *)localVersion serviceVersion:(NSString *)version {
  470. localVersion = [localVersion stringByReplacingOccurrencesOfString:@"." withString:@""];
  471. if (localVersion.length == 3) {
  472. localVersion = [localVersion stringByAppendingString:@"0"];
  473. }
  474. else if (localVersion.length==2) {
  475. localVersion = [localVersion stringByAppendingString:@"00"];
  476. }else if (localVersion.length==1){
  477. localVersion = [localVersion stringByAppendingString:@"000"];
  478. }
  479. version = [version stringByReplacingOccurrencesOfString:@"." withString:@""];
  480. if (version.length == 3) {
  481. version = [version stringByAppendingString:@"0"];
  482. }
  483. else if (version.length==2) {
  484. version = [version stringByAppendingString:@"00"];
  485. }else if (version.length==1){
  486. version = [version stringByAppendingString:@"000"];
  487. }
  488. if (([localVersion floatValue] < [version floatValue])) {
  489. return YES;
  490. }
  491. else {
  492. return NO;
  493. }
  494. }
  495. - (void)showMemoAlert {
  496. if (_isShowFlashAlert == NO && self.messageDict != nil) {
  497. [self showAlertWithMemo:[self.messageDict ks_stringValueForKey:@"memo"] descMessage:[self.messageDict ks_stringValueForKey:@"descMessage"] isforce:[self.messageDict ks_boolValueForKey:@"isforce"] openUrl:[self.messageDict ks_stringValueForKey:@"openUrl"]];
  498. }
  499. }
  500. - (void)showAlertWithMemo:(NSString *)memo descMessage:(NSString *)descMessage isforce:(BOOL)isforce openUrl:(NSString *)openUrl {
  501. if (_isShowFlashAlert) {
  502. NSMutableDictionary *parm = [NSMutableDictionary dictionary];
  503. [parm setValue:memo forKey:@"memo"];
  504. [parm setValue:descMessage forKey:@"descMessage"];
  505. [parm setValue:@(isforce) forKey:@"isforce"];
  506. [parm setValue:openUrl forKey:@"openUrl"];
  507. self.messageDict = [parm mutableCopy];
  508. return;
  509. }
  510. self.messageDict = nil;
  511. #pragma clang diagnostic push
  512. #pragma clang diagnostic ignored "-Wdeprecated-declarations"
  513. MJWeakSelf;
  514. [self.alertView configWithMemo:memo desc:descMessage isForce:isforce callback:^(BOOL isSure) {
  515. weakSelf.isShowMemoAlert = NO;
  516. if (isSure) {
  517. if (@available(iOS 10.0, *)) {
  518. if ([[UIApplication sharedApplication] respondsToSelector:@selector(openURL:options:completionHandler:)]) {
  519. [[UIApplication sharedApplication] openURL:[NSURL URLWithString:openUrl] options:@{} completionHandler:^(BOOL success) {
  520. }];
  521. } else {
  522. BOOL success = [[UIApplication sharedApplication] openURL:[NSURL URLWithString:openUrl]];
  523. NSLog(@"Open %d",success);
  524. }
  525. } else {
  526. // Fallback on earlier versions
  527. bool can = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:openUrl]];
  528. if(can){
  529. [[UIApplication sharedApplication] openURL:[NSURL URLWithString:openUrl]];
  530. }
  531. }
  532. }
  533. else {
  534. }
  535. }];
  536. #pragma clang diagnostic pop
  537. [self.alertView showAlert];
  538. self.isShowMemoAlert = YES;
  539. }
  540. - (void)requestRongCloudToken {
  541. [KSNetworkingManager refreshImTokenRequest:KS_POST success:^(NSDictionary * _Nonnull dic) {
  542. if ([dic ks_integerValueForKey:@"code"] == 200 && [dic ks_boolValueForKey:@"status"]) {
  543. NSString *newToken = [dic ks_stringValueForKey:@"data"];
  544. if (![NSString isEmptyString:newToken]) {
  545. UserDefaultSet(newToken, IM_TOKEN);
  546. [[NSUserDefaults standardUserDefaults] synchronize];
  547. [USER_MANAGER checkTokenEnableConnectIM];
  548. }
  549. }
  550. else {
  551. NSLog(@"error");
  552. }
  553. } faliure:^(NSError * _Nonnull error) {
  554. }];
  555. }
  556. - (void)initTableBar {
  557. if (self.tabBarController) {
  558. [self.tabBarController removeControllerNotifer];
  559. }
  560. // -1 为平台用户
  561. if ([UserDefaultObjectForKey(TENANT_ID) integerValue] <= 0) {
  562. self.tabBarController = [[KSTabBarViewController alloc] init];
  563. self.window.rootViewController = self.tabBarController;
  564. }
  565. else {
  566. self.tabBarController = [[InstitutionTabBarController alloc] init];
  567. self.window.rootViewController = self.tabBarController;
  568. }
  569. [[UITabBar appearance] setBackgroundImage:[[UIImage alloc] init]];
  570. [[UITabBar appearance] setShadowImage:[[UIImage alloc] init]];
  571. [self countUnreadMessage];
  572. }
  573. - (void)initLoginView {
  574. LoginViewController *logonVC = [[LoginViewController alloc] init];
  575. CustomNavViewController *navCtrl = [[CustomNavViewController alloc] initWithRootViewController:logonVC];
  576. self.window.rootViewController = navCtrl;
  577. }
  578. - (void)applicationWillResignActive:(UIApplication *)application {
  579. // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
  580. // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
  581. [self countUnreadMessage];
  582. }
  583. - (void)didReceiveMessageNotification:(NSNotification *)notification {
  584. }
  585. - (BOOL)handleOutLink:(NSURL *)url {
  586. NSString *detailUrl = [url absoluteString];
  587. if ([detailUrl containsString:@"linkUrl="]) {
  588. NSString *linkUrl = [[detailUrl componentsSeparatedByString:@"linkUrl="] lastObject];
  589. if (![NSString isEmptyString:linkUrl]) {
  590. linkUrl = [linkUrl removeUrlEndcodeString];
  591. // 转成 dic
  592. NSData *jsonData = [linkUrl mj_JSONData];
  593. NSError *error;
  594. NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
  595. if (error) {
  596. NSLog(@"jsonString解析失败:%@", error);
  597. return NO;
  598. }
  599. else {
  600. UIViewController *vc = self.window.rootViewController;
  601. NSString *token = UserDefault(TokenKey);
  602. if ([vc isKindOfClass:[LaunchAnimationViewController class]] || [NSString isEmptyString:token]) {
  603. self.outLinkParm = [NSMutableDictionary dictionaryWithDictionary:dict];
  604. return NO;
  605. }
  606. [self handSource:dict];
  607. }
  608. }
  609. }
  610. NSLog(@"%@", detailUrl);
  611. return YES;
  612. }
  613. #pragma mark ---- 处理外链
  614. - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
  615. return [self handleOutLink:url];
  616. }
  617. - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
  618. NSString* webpageStr = userActivity.webpageURL.absoluteString;
  619. if ([webpageStr containsString:@"wx97408cd22c879ff7"] && [webpageStr containsString:@"pay"]) {
  620. BOOL isok = [WXApi handleOpenUniversalLink:userActivity delegate:self];
  621. if (isok) {
  622. return YES;
  623. }
  624. }
  625. if (![[UMSocialManager defaultManager] handleUniversalLink:userActivity options:nil]) {
  626. // 其他SDK的回调
  627. }
  628. return YES;
  629. }
  630. #pragma mark ---- lazying
  631. - (KSUpdateAlert *)alertView {
  632. if (!_alertView) {
  633. _alertView = [KSUpdateAlert shareInstance];
  634. }
  635. return _alertView;
  636. }
  637. - (void)handSource:(NSDictionary *)dict {
  638. NSString *action = [dict ks_stringValueForKey:@"action"];
  639. NSString *clientType = [dict ks_stringValueForKey:@"clientType"];
  640. if ([clientType isEqualToString:@"TENANT"]) { // 机构
  641. NSString *webUrl = [dict ks_stringValueForKey:@"url"];
  642. if (![NSString isEmptyString:webUrl]) {
  643. KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
  644. webCtrl.url = [webUrl getUrlEndcodeString];
  645. CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
  646. [navCtrl pushViewController:webCtrl animated:YES];
  647. }
  648. else if ([action isEqualToString:@"app"]) {
  649. NSString *pageType = [dict ks_stringValueForKey:@"pageTag"];
  650. if ([pageType isEqualToString:@"feedback"]) { //反馈
  651. [self toFeedback];
  652. }
  653. return;
  654. }
  655. else { // 统一跳转消息列表
  656. UIViewController *vc = [UIApplication sharedApplication].keyWindow.rootViewController;
  657. if ([vc isKindOfClass:[UITabBarController class]]) {
  658. KSTabBarViewController *tabCtrl = (KSTabBarViewController *)vc;
  659. CustomNavViewController *navCtrl = (CustomNavViewController *)tabCtrl.selectedViewController;
  660. if ([navCtrl.visibleViewController isKindOfClass:NSClassFromString(@"TenantNotiferCenterController")]) {
  661. TenantNotiferCenterController *ctrl = (TenantNotiferCenterController *)navCtrl.visibleViewController;
  662. [ctrl refreshView];
  663. }
  664. else {
  665. [self.tabBarController tabBarSelectedWithIndex:3];
  666. CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
  667. TenantNotiferCenterController *ctrl = [[TenantNotiferCenterController alloc] init];
  668. [navCtrl pushViewController:ctrl animated:YES];
  669. }
  670. }
  671. else {
  672. [self.tabBarController tabBarSelectedWithIndex:3];
  673. CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
  674. TenantNotiferCenterController *ctrl = [[TenantNotiferCenterController alloc] init];
  675. [navCtrl pushViewController:ctrl animated:YES];
  676. }
  677. }
  678. }
  679. else { // 平台
  680. if ([action isEqualToString:@"app"]) {
  681. NSString *pageType = [dict ks_stringValueForKey:@"pageTag"];
  682. if ([pageType isEqualToString:@"practiceClass"]) { // 我的课程 ->陪练课
  683. DISPLAY_INDEX index = DISPLAY_INDEX_FIRST;
  684. MyCourseViewController *ctrl = [[MyCourseViewController alloc] init];
  685. [ctrl displayWithIndex:index];
  686. CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
  687. [navCtrl pushViewController:ctrl animated:YES];
  688. }
  689. else if ([pageType isEqualToString:@"liveClass"]) { // 我的课程 ->直播课
  690. DISPLAY_INDEX index = DISPLAY_INDEX_LIVE;
  691. MyCourseViewController *ctrl = [[MyCourseViewController alloc] init];
  692. [ctrl displayWithIndex:index];
  693. CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
  694. [navCtrl pushViewController:ctrl animated:YES];
  695. }
  696. else if ([pageType isEqualToString:@"videoClass"]) { // 我的课程 ->视频课
  697. DISPLAY_INDEX index = DISPLAY_INDEX_VIEO;
  698. MyCourseViewController *ctrl = [[MyCourseViewController alloc] init];
  699. [ctrl displayWithIndex:index];
  700. CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
  701. [navCtrl pushViewController:ctrl animated:YES];
  702. }
  703. else if ([pageType isEqualToString:@"buyPractice"] || [pageType isEqualToString:@"courseRemind"]) { // 课表
  704. [self.tabBarController tabBarSelectedWithIndex:1];
  705. CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
  706. [navCtrl popToRootViewControllerAnimated:YES];
  707. }
  708. else if ([pageType isEqualToString:@"homework"]) {
  709. NSString *parmString = [dict ks_stringValueForKey:@"params"];
  710. NSData *parmData = [parmString mj_JSONData];
  711. NSError *error;
  712. NSDictionary *parm = [NSJSONSerialization JSONObjectWithData:parmData options:NSJSONReadingMutableContainers error:&error];
  713. if (!error) {
  714. HomeworkDetailViewController *detailVC = [[HomeworkDetailViewController alloc] init];
  715. detailVC.courseId = [parm ks_stringValueForKey:@"courseId"];
  716. CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
  717. [navCtrl pushViewController:detailVC animated:YES];
  718. }
  719. }
  720. else if ([pageType isEqualToString:@"liveRoom"]) { // 直播
  721. NSString *parmString = [dict ks_stringValueForKey:@"params"];
  722. NSData *parmData = [parmString mj_JSONData];
  723. NSError *error;
  724. NSDictionary *parm = [NSJSONSerialization JSONObjectWithData:parmData options:NSJSONReadingMutableContainers error:&error];
  725. if (!error) {
  726. CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
  727. [KSEnterLiveroomManager joinLiveWithRoomId:[parm ks_stringValueForKey:@"liveRoomId"] inController:navCtrl callback:^{
  728. }];
  729. }
  730. }
  731. else if ([pageType isEqualToString:@"message"]) {
  732. UIViewController *vc = [UIApplication sharedApplication].keyWindow.rootViewController;
  733. if ([vc isKindOfClass:[UITabBarController class]]) {
  734. KSTabBarViewController *tabCtrl = (KSTabBarViewController *)vc;
  735. CustomNavViewController *navCtrl = (CustomNavViewController *)tabCtrl.selectedViewController;
  736. if ([navCtrl.visibleViewController isKindOfClass:NSClassFromString(@"NotiferMessageViewController")]) {
  737. NotiferMessageViewController *ctrl = (NotiferMessageViewController *)navCtrl.visibleViewController;
  738. [ctrl refreshView];
  739. }
  740. else {
  741. [self.tabBarController tabBarSelectedWithIndex:0];
  742. CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
  743. NotiferMessageViewController *ctrl = [[NotiferMessageViewController alloc] init];
  744. [navCtrl pushViewController:ctrl animated:YES];
  745. }
  746. }
  747. else {
  748. [self.tabBarController tabBarSelectedWithIndex:0];
  749. CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
  750. NotiferMessageViewController *ctrl = [[NotiferMessageViewController alloc] init];
  751. [navCtrl pushViewController:ctrl animated:YES];
  752. }
  753. }
  754. else if ([pageType isEqualToString:@"feedback"]) { //反馈
  755. [self toFeedback];
  756. }
  757. else { // 统一跳转消息列表
  758. UIViewController *vc = [UIApplication sharedApplication].keyWindow.rootViewController;
  759. if ([vc isKindOfClass:[UITabBarController class]]) {
  760. KSTabBarViewController *tabCtrl = (KSTabBarViewController *)vc;
  761. CustomNavViewController *navCtrl = (CustomNavViewController *)tabCtrl.selectedViewController;
  762. if ([navCtrl.visibleViewController isKindOfClass:NSClassFromString(@"NotiferMessageViewController")]) {
  763. NotiferMessageViewController *ctrl = (NotiferMessageViewController *)navCtrl.visibleViewController;
  764. [ctrl refreshView];
  765. }
  766. else {
  767. [self.tabBarController tabBarSelectedWithIndex:0];
  768. CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
  769. NotiferMessageViewController *ctrl = [[NotiferMessageViewController alloc] init];
  770. [navCtrl pushViewController:ctrl animated:YES];
  771. }
  772. }
  773. else {
  774. [self.tabBarController tabBarSelectedWithIndex:0];
  775. CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
  776. NotiferMessageViewController *ctrl = [[NotiferMessageViewController alloc] init];
  777. [navCtrl pushViewController:ctrl animated:YES];
  778. }
  779. }
  780. }
  781. else {
  782. NSString *webUrl = [dict ks_stringValueForKey:@"url"];
  783. if (![NSString isEmptyString:webUrl]) {
  784. KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
  785. webCtrl.url = [webUrl getUrlEndcodeString];
  786. CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
  787. [navCtrl pushViewController:webCtrl animated:YES];
  788. }
  789. }
  790. }
  791. }
  792. - (void)toFeedback {
  793. FeedbackListViewController *ctrl = [[FeedbackListViewController alloc] init];
  794. CustomNavViewController *navCtrl = self.tabBarController.selectedViewController;
  795. [navCtrl pushViewController:ctrl animated:YES];
  796. }
  797. - (void)handleNotiferSource {
  798. if (self.outLinkParm) {
  799. [self handSource:self.outLinkParm];
  800. self.outLinkParm = nil;
  801. }
  802. }
  803. // 统计消息数量
  804. - (void)countUnreadMessage {
  805. if ([TXIM_LINSENTER isCurrentUserLoginIM]) {
  806. [TXIM_LINSENTER getUnReadCountCallback:^(NSInteger count) {
  807. dispatch_async(dispatch_get_main_queue(),^{
  808. NSLog(@"----- %zd",count);
  809. [UIApplication sharedApplication].applicationIconBadgeNumber = count;
  810. if (count >= 1) {
  811. [self noteIMNewsCount:count];
  812. } else {
  813. [self clearIMNewsCount];
  814. }
  815. NSDictionary *receiveMsg = @{@"unreadCount":@(count)};
  816. [[NSNotificationCenter defaultCenter] postNotificationName:CHATVIEW_REFRESHSTATUS object:receiveMsg];
  817. });
  818. }];
  819. }
  820. }
  821. - (void)noteIMNewsCount:(NSInteger)count {
  822. if ([self.tabBarController isKindOfClass:[KSTabBarViewController class]]) {
  823. [self.tabBarController noteNewsWithIndex:2 count:count];
  824. }
  825. else {
  826. [self.tabBarController noteNewsWithIndex:1 count:count];
  827. }
  828. }
  829. - (void)clearIMNewsCount {
  830. if ([self.tabBarController isKindOfClass:[KSTabBarViewController class]]) {
  831. [self.tabBarController clearNewsWithIndex:2];
  832. }
  833. else {
  834. [self.tabBarController clearNewsWithIndex:1];
  835. }
  836. }
  837. - (void)openServer {//开启本地服务器
  838. self.httpServer = [[HTTPServer alloc]init];
  839. [self.httpServer setType:@"_http._tcp."];
  840. [self.httpServer setPort:6040];
  841. NSString *webPath = [self getCourewareSavePath];
  842. NSFileManager *fileManager = [[NSFileManager alloc] init];
  843. NSLog(@"%@",webPath);
  844. if (![fileManager fileExistsAtPath:webPath]){
  845. NSLog(@"File path error!");
  846. }else{
  847. [self.httpServer setDocumentRoot:webPath];
  848. NSLog(@"服务器路径:%@", webPath);
  849. self.isServiceStart = [self startServer];
  850. }
  851. }
  852. - (NSString *)getCourewareSavePath {
  853. // 在Documents目录下创建一个名为CoursewarePath的文件夹
  854. NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"CoursewarePath"];
  855. NSFileManager *fileManager = [NSFileManager defaultManager];
  856. BOOL isDir = FALSE;
  857. BOOL isDirExist = [fileManager fileExistsAtPath:path isDirectory:&isDir];
  858. if(!(isDirExist && isDir)) {
  859. BOOL bCreateDir = [fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
  860. if(!bCreateDir){
  861. NSLog(@"创建文件夹失败!");
  862. }
  863. // NSLog(@"创建文件夹成功,文件路径%@",path);
  864. }
  865. return path;
  866. }
  867. - (BOOL)startServer {//启动服务
  868. BOOL ret = NO;
  869. NSError *error = nil;
  870. if([self.httpServer start:&error]){
  871. NSLog(@"HTTP服务器启动成功端口号为: %hu", [_httpServer listeningPort]);
  872. self.serverPort = [NSString stringWithFormat:@"%d",[self.httpServer listeningPort]];
  873. ret = YES;
  874. }else{
  875. NSLog(@"启动HTTP服务器出错: %@", error);
  876. }
  877. return ret;
  878. }
  879. - (void)stopServer{//停止服务
  880. if (self.httpServer != nil){
  881. [self.httpServer stop];
  882. self.isServiceStart = NO;
  883. }
  884. }
  885. @end