iOS 無法獲取 WiFi 列表?一定是因為你不知道這個框架

EyreFree發表於2017-12-21

iOS 9 釋出之後,蘋果推出了 NetworkExtension,利用這個框架可以實現很多和網路相關的操作。本文主要介紹怎樣使用其中的 NEHotspotHelper 進行裝置 WiFi 列表的獲取。如果你只是想獲取當前裝置正在連線的 WiFi 資訊,有更加便捷的方法,可參考我的另一篇文章:iOS 獲取當前已連線 WiFi 資訊

Demo 地址:github.com/EyreFree/EF…

一. 注意事項

  1. 首先,NEHotspotHelper 只在 iOS 9 及以上版本得到支援,之前版本的 iOS 並不支援該功能;
  2. 然後,你需要有一個開發者賬號;
  3. 最後,該框架目前還沒有大規模開放使用,所以需要向蘋果傳送申請並且稽核通過才能夠獲得使用該框架的許可權,大致內容就是描述一下你需要使用該框架的原因之類的,然後我是用的英文進行描述(感謝百度以及谷歌翻譯),不過據說中文也行。提交申請後大概一週內會收到反饋郵件,申請地址為: developer.apple.com/contact/net…
  4. 我申請的時候就描述了一個 VPN 應用的大概功能就給過了,具體流程見 Network Extension 申請表格填寫及郵件往來 這篇博文;
  5. 如果如果已知 SSID 及密碼的情況下,可以直接呼叫 NEHotspotConfigurationManager API 來進行 WiFi 連線,不需要向蘋果申請 NEHotspotHelper 許可權,不過需要注意的是該方法僅在 iOS 11 及以上系統有效,可參考 iOS NEHotspotConfigurationManager 使用 一文。

二. 建立 App ID

開啟蘋果開發者中心,登陸然後找到 App IDs 選項,點選右上角按鈕建立一個 App ID 用於接下來建立 Provisioning Profile,地址為: developer.apple.com/account/ios… ,如圖所示:

建立 App ID

首先,填寫 Name 以及 Bundle ID,這裡統一填寫為 EFNEHotspotHelperDemo,如圖所示:

填寫 Name

填寫 Bundle ID

接下來這一步注意需要勾選 Wireless Accessory Configuration 這一選項,如圖所示:

勾選 Wireless Accessory Configuration

然後觀察到如圖所示狀態表明已成功開啟:

狀態顯示

在 App IDs 列表中檢視剛建立完成的 App ID:

App IDs 列表

三. 建立 Provisioning Profile

找到 Provisioning Profiles 選項,點選右上角按鈕建立一個 Provisioning Profile 用於接下來建立示例工程,地址為: developer.apple.com/account/ios… ,如圖所示:

建立 Provisioning Profile

首先選擇 Profile 型別,這裡我選擇的是 iOS App Development,可以根據自己的具體需要自由選擇:

選擇 Profile 型別

接下來選擇我們在第二步建立好的 App ID,如圖所示:

選擇 App ID

然後選擇證書和裝置,全選即可:

選擇證書

選擇裝置

在額外許可權這一步需要選中我們申請到的 Network Extension 許可權,可以看到其中包含我們需要使用的 NEHotspotHelper 許可權,如圖所示:

選中 Network Extension 許可權

填寫完 Profile Name 之後,即可成功建立我們需要的 Profile:

填寫 Profile Name

點選 Download 將它下載到本地:

下載 Profile

雙擊開啟,即可將 Profile 新增到本機:

新增 Profile

可以到 XCode 的賬戶設定裡檢視已安裝的 Profile,若未安裝成功可以嘗試點選 Action 中的 Download 按鈕重新下載:

檢視已安裝的 Profile

四. 建立工程

接下來我們建立一個示例工程,演示如何獲取 WiFi 列表。首先,將 Bundle ID 改為之前設定的 EFNEHotspotHelperDemo:

修改 Bundle ID

然後在 Info.plist 中新增後臺模式許可權陣列:

新增後臺模式程式碼

程式碼如下:

<key>UIBackgroundModes</key>
<array>
	<string>network-authentication</string>
</array>
複製程式碼

新增完成後可以在 Target -> Capabilities 中看到後臺模式已處於開啟狀態:

後臺模式已開啟

接下來在 Capabilities 找到 Wireless Accessory Configuration 並將其開啟:

開啟 Wireless Accessory Configuration

在工程中找到名為 {工程名}.entitlements 的檔案,例如 Demo 中的應為 EFNEHotspotHelperDemo.entitlements,在其中加入 HotspotHelper 許可權程式碼:

新增 HotspotHelper 許可權程式碼

程式碼如下:

<key>com.apple.developer.networking.HotspotHelper</key>
<true/>
複製程式碼

好了,到這裡已經完成了各種亂七八糟的配置工作,可以嘗試進行 Build。如果沒有提示錯誤資訊的話,接下來就可以愉快地使用 HotspotHelper 了;如果有問題的話,請檢查之前的步驟是否都已正確完成或者根據錯誤資訊修改具體專案。

五. 核心程式碼

首先,在需要使用 HotspotHelper 的地方新增標頭檔案引用,這裡以 Objective-C 程式碼為例:

#import <NetworkExtension/NetworkExtension.h>
複製程式碼

然後使用如下程式碼即可將 WiFi 列表資訊列印到 XCode 控制檯,注意:這裡需要開啟系統 設定 中的 無線區域網 頁面才能獲取相關資訊,因為開啟該頁面系統重新整理 WiFi 資訊時才會觸發該回撥:

- (void)scanWifiInfos{
    NSLog(@"1.Start");

    NSMutableDictionary* options = [[NSMutableDictionary alloc] init];
    [options setObject:@"EFNEHotspotHelperDemo" forKey: kNEHotspotHelperOptionDisplayName];
    dispatch_queue_t queue = dispatch_queue_create("EFNEHotspotHelperDemo", NULL);

    NSLog(@"2.Try");
    BOOL returnType = [NEHotspotHelper registerWithOptions: options queue: queue handler: ^(NEHotspotHelperCommand * cmd) {

        NSLog(@"4.Finish");
        NEHotspotNetwork* network;
        if (cmd.commandType == kNEHotspotHelperCommandTypeEvaluate || cmd.commandType == kNEHotspotHelperCommandTypeFilterScanList) {
            // 遍歷 WiFi 列表,列印基本資訊
            for (network in cmd.networkList) {
                NSString* wifiInfoString = [[NSString alloc] initWithFormat: @"---------------------------\nSSID: %@\nMac地址: %@\n訊號強度: %f\nCommandType:%ld\n---------------------------\n\n", network.SSID, network.BSSID, network.signalStrength, (long)cmd.commandType];
                NSLog(@"%@", wifiInfoString);

                // 檢測到指定 WiFi 可設定密碼直接連線
                if ([network.SSID isEqualToString: @"測試 WiFi"]) {
                    [network setConfidence: kNEHotspotHelperConfidenceHigh];
                    [network setPassword: @"123456789"];
                    NEHotspotHelperResponse *response = [cmd createResponse: kNEHotspotHelperResultSuccess];
                    NSLog(@"Response CMD: %@", response);
                    [response setNetworkList: @[network]];
                    [response setNetwork: network];
                    [response deliver];
                }
            }
        }
    }];

    // 註冊成功 returnType 會返回一個 Yes 值,否則 No
    NSLog(@"3.Result: %@", returnType == YES ? @"Yes" : @"No");
}
複製程式碼

六. 演示

唔,Demo 執行效果如下,點選 Open WiFi Setting 按鈕可直接開啟 無線區域網 頁面:

執行效果

具體可嘗試下載 Demo 並完成相應配置後體驗:github.com/EyreFree/EF…

七. 備註

參考以下資料完成本 Demo,在此表示感謝:

iOS 9.0 搜尋附近Wi-Fi熱點 IOS NetworkExtension 框架使用筆記 iOS NEHotspotHelper使用 iOS-NetworkExtension-NEHotspotHelper API Reference - NetworkExtension

八. 附錄

Network Extension 申請表格填寫及郵件往來


如有任何智慧財產權、版權問題或理論錯誤,還請指正。
https://juejin.im/post/5a3214cd51882506fd589047
轉載請註明原作者及以上資訊。

相關文章