我剛經歷了一場末日(停電),特別是在你想寫文檔的時候。。。
言歸正傳,今天的問題是解決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,在回調里進行相應的人機交互就可以了。
2.延遲請求
就是把配置請求放到首頁VC里,不要放到AppDelegate里,同時監聽網絡狀態(AF,其他第三方等)有個致命性的問題就是獲取網絡狀態會有一定的延遲(親測),導致很多情況,還有就是要自己處理權限彈框以及對原有代碼邏輯要進行修改。
總結
這個問題遇到幾次了,原來都是用第二種方式進行了一定的優化,這次的APP有一個配置信息接口導致出現問題,寫下來作為記錄,方法還有很多種,不足的地方還有很多,僅供大家參考。