iOS10 優化APP首次安裝網路許可權提示方案
我剛經歷了一場末日(停電),特別是在你想寫文件的時候。。。
言歸正傳,今天的問題是解決iOS10系統下首次按鈕APP彈出的網路許可權提示所帶來了問題以及優化。
起因
查了相關文章知道由於大陸工信部出臺的新規指出,應用在未經使用者允許的前提下,系統不能授予其使用聯網、獲取定位的功能。Apple在iOS10系統中加入了關於應用使用資料的授權彈窗提示,使用者在iOS系統及以上系統中第一次開啟應用時,會被要求對於是否授予應用聯網許可權進行選擇。
問題
Apple把自己的問題解決了, 但是Apple沒有給出官方的獲取選擇事件的回撥,這樣就是給開發者挖坑了。
對於很多開發者習慣於把預載入介面放到AppDelegate的同志就很苦惱了。
這樣會造成配置介面請求失敗,首頁資料為空的情況,第一次獲取DeviceToken失敗,新增推送通知失敗,第三方初始化失敗,以至於導致很多延伸的問題。
解決
1.根據CTCellularData類獲取網路許可權狀態以及監聽狀態改變回調(推薦)
我就在使用此方法。話不多說上程式碼,註釋很詳細;
新增CoreTelephony系統庫,在AppDelegate.m裡#import<CoreTelephony/CTCellularData.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. //1.獲取網路許可權 根絕許可權進行人機互動 if (__IPHONE_10_0) { [self networkStatus:application didFinishLaunchingWithOptions:launchOptions]; }else { //2.2已經開啟網路許可權 監聽網路狀態 [self addReachabilityManager:application didFinishLaunchingWithOptions:launchOptions]; } //初始化window self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; [self.window setBackgroundColor:[UIColor whiteColor]]; // //建立UI [self createWindowRootWithType:2]; [self.window makeKeyAndVisible]; return YES; } /* CTCellularData在iOS9之前是私有類,許可權設定是iOS10開始的,所以App Store稽核沒有問題 獲取網路許可權狀態 */ - (void)networkStatus:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //2.根據許可權執行相應的互動 CTCellularData *cellularData = [[CTCellularData alloc] init]; /* 此函式會在網路許可權改變時再次呼叫 */ cellularData.cellularDataRestrictionDidUpdateNotifier = ^(CTCellularDataRestrictedState state) { switch (state) { case kCTCellularDataRestricted: NSLog(@"Restricted"); //2.1許可權關閉的情況下 再次請求網路資料會彈出設定網路提示 [self getAppInfo]; break; case kCTCellularDataNotRestricted: NSLog(@"NotRestricted"); //2.2已經開啟網路許可權 監聽網路狀態 [self addReachabilityManager:application didFinishLaunchingWithOptions:launchOptions]; // [self getInfo_application:application didFinishLaunchingWithOptions:launchOptions]; break; case kCTCellularDataRestrictedStateUnknown: NSLog(@"Unknown"); //2.3未知情況 (還沒有遇到推測是有網路但是連線不正常的情況下) [self getAppInfo]; break; default: break; } }; } /** 實時檢查當前網路狀態 */ - (void)addReachabilityManager:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { AFNetworkReachabilityManager *afNetworkReachabilityManager = [AFNetworkReachabilityManager sharedManager]; //這個可以放在需要偵聽的頁面 // [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(afNetworkStatusChanged:) name:AFNetworkingReachabilityDidChangeNotification object:nil]; [afNetworkReachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { switch (status) { case AFNetworkReachabilityStatusNotReachable:{ NSLog(@"網路不通:%@",@(status) ); break; } case AFNetworkReachabilityStatusReachableViaWiFi:{ NSLog(@"網路通過WIFI連線:%@",@(status)); if (self.mallConfigModel == nil) { [self getInfo_application:application didFinishLaunchingWithOptions:launchOptions]; } break; } case AFNetworkReachabilityStatusReachableViaWWAN:{ NSLog(@"網路通過無線連線:%@",@(status) ); if (self.mallConfigModel == nil) { [self getInfo_application:application didFinishLaunchingWithOptions:launchOptions]; } break; } default: break; } }]; [afNetworkReachabilityManager startMonitoring]; //開啟網路監視器; } - (void)getInfo_application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //第三方庫初始化 [self initValueThirdParty:application didFinishLaunchingWithOptions:launchOptions]; // //獲取初始資訊 [self initData]; //新增通知 [self addNotification]; }
這樣也同時解決了使用者如果選擇不允許和限制兩種情況,在使用者沒有統一聯網的情況下,APP會顯示沒有網路的UI,重新進入APP會呼叫在不允許狀態下會呼叫一個測試介面,APP會自動彈出重新選擇網路許可權以及說明的彈窗,進入設定修改過APP聯網許可權以後選擇回到APP就會觸發cellularDataRestrictionDidUpdateNotifier,在回撥裡進行相應的人機互動就可以了。
2018年08月09日更新
這段時間一直出現微信沒有註冊的問題,不是必現而且只有線上存在,推薦大家第三方庫(特別是需要網路的庫)的初始化不需要放到判斷網路許可權裡面,直接初始化。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. //預設更新 self.appIsUpdate = YES; //1.獲取網路許可權 根絕許可權進行人機互動 if (IS_IOS_(10)) { [self networkStatus:application didFinishLaunchingWithOptions:launchOptions]; }else { //2.2已經開啟網路許可權 監聽網路狀態 [self addReachabilityManager:application didFinishLaunchingWithOptions:launchOptions]; } //初始化第三方庫 [self initValueThirdParty:application didFinishLaunchingWithOptions:launchOptions]; //啟動頁停留1秒鐘。 [NSThread sleepForTimeInterval:1.0]; //初始化window self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; [self.window setBackgroundColor:[UIColor whiteColor]]; //建立主檢視 if ([DataBase nowUser]) { [self createWindowRootWithType:2]; }else { [self createWindowRootWithType:1]; } [self.window makeKeyAndVisible]; return YES; }
2.延遲請求
就是把配置請求放到首頁VC裡,不要放到AppDelegate裡,同時監聽網路狀態(AF,其他第三方等)有個致命性的問題就是獲取網路狀態會有一定的延遲(親測),導致很多情況,還有就是要自己處理許可權彈框以及對原有程式碼邏輯要進行修改。
總結
這個問題遇到幾次了,原來都是用第二種方式進行了一定的優化,這次的APP有一個配置資訊介面導致出現問題,寫下來作為記錄,方法還有很多種,不足的地方還有很多,僅供大家參考。