國行獨(dú)有BUG——iOS10無線局域網(wǎng)權(quán)限問題解決方案

國行iPhone的獨(dú)有無奈

iOS9之后蘋果針對所有的APP權(quán)限新增蜂窩網(wǎng)絡(luò)訪問權(quán)限汇鞭,默認(rèn)都是允許訪問狀態(tài)霍骄,用戶可以自行去“設(shè)置-蜂窩移動網(wǎng)絡(luò)”里關(guān)閉該權(quán)限。


iOS9蜂窩移動網(wǎng)絡(luò)應(yīng)用權(quán)限設(shè)置

iOS10之后蘋果針對國行手機(jī)的APP在蜂窩網(wǎng)絡(luò)訪問權(quán)限的基礎(chǔ)上新增一個無線局域網(wǎng)權(quán)限的選擇。這是由于中國大陸相關(guān)部門出臺的新規(guī)定指出米间,應(yīng)用在未經(jīng)用戶允許的前提下车伞,系統(tǒng)不能授予其使用聯(lián)網(wǎng)的功能喻喳,這其中就包括無線局域網(wǎng)(WIFI)表伦。因此許多應(yīng)用在第一次安裝的時候會自動彈出一個彈窗詢問用戶是否允許該應(yīng)用使用包括無線局域網(wǎng)和蜂窩移動數(shù)據(jù)蹦哼。


iOS10第一次安裝應(yīng)用無線和蜂窩數(shù)據(jù)的授權(quán)彈窗

但是纲熏,這一新增的無線網(wǎng)絡(luò)授權(quán)僅僅在手機(jī)系統(tǒng)層面,在應(yīng)用開發(fā)的層面上蘋果并未做任何相關(guān)的調(diào)整勺拣,也就是說:開發(fā)者無法通過系統(tǒng)API獲取到當(dāng)前用戶對于某個應(yīng)用的無線局域網(wǎng)授權(quán)情況鱼填,因此苹丸,如果用戶在上圖中不注意選擇了不允許或者由于系統(tǒng)BUG的原因(原因詳見:https://juejin.im/post/57e229880e3dd90069867129)無法獲得對應(yīng)的授權(quán),則很容易被用戶誤解是該APP出現(xiàn)BUG宦言,用戶體驗也會大打折扣蜡励。

解決思路

首先,我們明確一點(diǎn):蘋果官方?jīng)]有提供對應(yīng)的API供開發(fā)人員獲取到應(yīng)用的無線局域網(wǎng)的授權(quán)情況兼都。我們解決問題的方法是要引導(dǎo)用戶到相應(yīng)的系統(tǒng)界面進(jìn)行開啟權(quán)限操作(在“設(shè)置-無線局域網(wǎng)/蜂窩移動網(wǎng)絡(luò)-使用無線局域網(wǎng)與蜂窩移動的應(yīng)用”里找到對應(yīng)的APP開啟權(quán)限)扮碧。

手機(jī)設(shè)置界面

無線局域網(wǎng)設(shè)置界面
蜂窩移動網(wǎng)絡(luò)設(shè)置界面
使用無線局域網(wǎng)與蜂窩移動的應(yīng)用設(shè)置界面

接下來慎王,思考一下:能不能對這一種場景進(jìn)行代碼層面的推斷呢?我們嘗試收集相關(guān)的信息:

  • 該權(quán)限被關(guān)閉的結(jié)果:在WIFI可以訪問網(wǎng)絡(luò)的情況下宏侍,應(yīng)用內(nèi)無法訪問網(wǎng)絡(luò)
  • 無線局域網(wǎng)權(quán)限是在蜂窩移動網(wǎng)絡(luò)授權(quán)的基礎(chǔ)上新增一個選項而來
  • 國行iOS10的網(wǎng)絡(luò)授權(quán)選項包括“關(guān)閉”赖淤、“無線局域網(wǎng)”、“無線局域網(wǎng)與蜂窩移動數(shù)據(jù)”


    應(yīng)用網(wǎng)絡(luò)授權(quán)界面

以上信息提煉一下:

  1. 已連接到某個無線局域網(wǎng)(成功連接某個網(wǎng)絡(luò)并且能獲取到SSID信息)
  2. 應(yīng)用內(nèi)網(wǎng)絡(luò)不可觸達(dá)
  3. 網(wǎng)絡(luò)訪問權(quán)限被關(guān)閉

針對以上三點(diǎn)谅河,就能推斷出應(yīng)用的無線網(wǎng)絡(luò)權(quán)限被關(guān)閉咱旱,那么我們開始對這三點(diǎn)“優(yōu)雅”地書寫代碼。

1. 判斷當(dāng)前手機(jī)成功連接某個網(wǎng)絡(luò)并且能獲取到SSID信息

以下代碼若能成功返回非空信息绷耍,則說明成功連接到某個網(wǎng)絡(luò)(返回的內(nèi)容為SSID信息)

- (NSDictionary *)fetchSSIDInfo {
    
    NSArray *ifs = (__bridge_transfer NSArray *)CNCopySupportedInterfaces();
    
    if (!ifs) {
        
        return nil;
        
    }
    
    NSDictionary *info = nil;
    
    for (NSString *ifnam in ifs) {
        
        info = (__bridge_transfer NSDictionary *)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
        
        if (info && [info count]) { break; }
        
    }
    
    return info;
    
}

2. 判斷應(yīng)用內(nèi)網(wǎng)絡(luò)不可觸達(dá)

這里使用 AFNetworking 的 AFNetworkReachabilityManager 進(jìn)行監(jiān)測吐限,可以使用蘋果官方的 Reachability (https://developer.apple.com/library/ios/#samplecode/Reachability/Introduction/Intro.html)褂始,二者同源诸典。
PS:這里的判斷方法并不是真正意義上的判斷網(wǎng)絡(luò)是否可以觸達(dá),該方法僅僅判斷應(yīng)用能否連接上手機(jī)網(wǎng)絡(luò)崎苗,網(wǎng)絡(luò)類型如何狐粱,并不能判斷手機(jī)連接到無線局域網(wǎng)之后是否可以訪問外網(wǎng)的情況,不過用這種方法已經(jīng)滿足我們的需求胆数,因為權(quán)限限制是在應(yīng)用能否訪問手機(jī)網(wǎng)絡(luò)這一節(jié)點(diǎn)脑奠。

- (void)startAFNetworkMonitoring {
    // 這里sharedHTTPSessionManager使用只是對AFHTTPSessionManager進(jìn)行單例封裝,因為對默認(rèn)的AFHTTPSessionManager直接使用有內(nèi)存泄漏的問題
    AFHTTPSessionManager *manager = [KCSharedSessionManager sharedHTTPSessionManager];
    // 應(yīng)用網(wǎng)絡(luò)狀態(tài)改變時執(zhí)行異步回調(diào)
    [manager.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        switch (status) {
            // 蜂窩網(wǎng)絡(luò)
            case AFNetworkReachabilityStatusReachableViaWWAN:
                break;
            case AFNetworkReachabilityStatusReachableViaWiFi:
                _netState = YES;
                break;
            case AFNetworkReachabilityStatusNotReachable:
                _netState = NO;
                break;
            case AFNetworkReachabilityStatusUnknown:
                _netState = NO;
                break;
            default:
                _netState = NO;
                break;
        }
    }];
    
    [manager.reachabilityManager startMonitoring];

}

3. 判斷網(wǎng)絡(luò)訪問權(quán)限被關(guān)閉

使用iOS9新增的系統(tǒng)庫CoreTelephony.framework進(jìn)行判斷(蜂窩網(wǎng)絡(luò)權(quán)限授權(quán)也是iOS9才增加的)幅慌。
這里帶一個思考:無線局域網(wǎng)權(quán)限授權(quán)是在蜂窩網(wǎng)絡(luò)權(quán)限授權(quán)的基礎(chǔ)上新增一項宋欺,我們可以嘗試下通過這個庫,獲取到的僅僅只有無線局域網(wǎng)權(quán)限而無蜂窩網(wǎng)絡(luò)權(quán)限時的授權(quán)狀態(tài)值是怎樣的胰伍。
PS:值得一提的是齿诞,CTCellularData的block屬性cellularDataRestrictionDidUpdateNotifier并不會自動釋放,而且即使對應(yīng)的CTCellularData實(shí)例釋放了骂租,該block屬性也不會釋放祷杈,注意使用即可

@import CoreTelephony;
- (void)startCellularDataAuthMonitoring {
    if (!self.cellularData) self.cellularData = [[CTCellularData alloc] init];
    self.cellularData.cellularDataRestrictionDidUpdateNotifier = nil;
    if (self.cellularData) {
        // 該block為異步回調(diào)
        self.cellularData.cellularDataRestrictionDidUpdateNotifier = ^(CTCellularDataRestrictedState state) { 
            // 獲取應(yīng)用聯(lián)網(wǎng)授權(quán)狀態(tài)
            switch (state) {
                case kCTCellularDataRestricted: NSLog(@"Restricrted"); // 權(quán)限受限
                    break;
                case kCTCellularDataNotRestricted: NSLog(@"Not Restricted"); // 權(quán)限不受限
                    break;
                case kCTCellularDataRestrictedStateUnknown: NSLog(@"Unknown"); // 未知,第一次請求
                    break;
                default:
                    break;
            }
        };
    };
}

經(jīng)過測試渗饮,發(fā)現(xiàn)如下圖的狀態(tài)值對應(yīng)的網(wǎng)絡(luò)受限情況:


網(wǎng)絡(luò)受限情況對應(yīng)的狀態(tài)值

總結(jié)使用

現(xiàn)在邏輯已經(jīng)很清晰但汞,就是當(dāng)以上三個判斷都成立的時候宿刮,可以推斷出用戶關(guān)閉了應(yīng)用訪問無線互聯(lián)網(wǎng)的權(quán)限,這時候就可以彈出引導(dǎo)用戶打開相關(guān)權(quán)限的彈窗了私蕾。
這里有一個需要注意的地方是:CTCellularData和AFNetworkReachabilityManager用戶監(jiān)測的回調(diào)都是異步的僵缺,也就是說,當(dāng)發(fā)生對應(yīng)的狀態(tài)改變時踩叭,回調(diào)才會生效磕潮,這里需要分別對狀態(tài)值的改變進(jìn)行監(jiān)聽或者設(shè)置依賴才能正確執(zhí)行我們的判斷邏輯,這里我使用了RAC進(jìn)行信號的監(jiān)聽容贝。

    @weakify(self);
    // 當(dāng)網(wǎng)絡(luò)權(quán)限和網(wǎng)絡(luò)狀態(tài)值發(fā)生改變(開機(jī)啟動時狀態(tài)值從空改變到有值)時自脯,觸發(fā)信號監(jiān)聽邏輯
    [[[RACSignal merge:@[RACObserve(self.cellularData, restrictedState),
                         RACObserve([KCSharedSessionManager sharedHTTPSessionManager].reachabilityManager, networkReachabilityStatus)]]
      bufferWithTime: 0 onScheduler: [RACScheduler mainThreadScheduler]]
     subscribeNext: ^(id value) {
         @strongify(self);
         if (self.cellularData.restrictedState == kCTCellularDataRestricted && [KCSharedSessionManager sharedHTTPSessionManager].reachabilityManager.networkReachabilityStatus == AFNetworkReachabilityStatusNotReachable && [self fetchSSIDInfo]) {
             // 回到主線程
             dispatch_async_on_main_queue(^{
                  // 顯示彈窗
             });
         }
     }];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市斤富,隨后出現(xiàn)的幾起案子膏潮,更是在濱河造成了極大的恐慌,老刑警劉巖满力,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件焕参,死亡現(xiàn)場離奇詭異,居然都是意外死亡脚囊,警方通過查閱死者的電腦和手機(jī)龟糕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進(jìn)店門桐磁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來悔耘,“玉大人,你說我怎么就攤上這事我擂〕囊裕” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵校摩,是天一觀的道長看峻。 經(jīng)常有香客問我,道長衙吩,這世上最難降的妖魔是什么互妓? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮坤塞,結(jié)果婚禮上冯勉,老公的妹妹穿的比我還像新娘。我一直安慰自己摹芙,他們只是感情好灼狰,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著浮禾,像睡著了一般交胚。 火紅的嫁衣襯著肌膚如雪份汗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天蝴簇,我揣著相機(jī)與錄音杯活,去河邊找鬼。 笑死军熏,一個胖子當(dāng)著我的面吹牛轩猩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播荡澎,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼均践,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了摩幔?” 一聲冷哼從身側(cè)響起彤委,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎或衡,沒想到半個月后焦影,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡封断,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年斯辰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坡疼。...
    茶點(diǎn)故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡彬呻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出柄瑰,到底是詐尸還是另有隱情闸氮,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布教沾,位于F島的核電站蒲跨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏授翻。R本人自食惡果不足惜或悲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望堪唐。 院中可真熱鬧巡语,春花似錦、人聲如沸羔杨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽兜材。三九已至理澎,卻和暖如春逞力,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背糠爬。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工寇荧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人执隧。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓揩抡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親镀琉。 傳聞我的和親對象是個殘疾皇子峦嗤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容