NEHotspotHelperでAuthenticatingにフックする
NEHotspotHelperの情報は、開発に使用するのにも申請が必須というハードルの高さからか情報が少ない。 そんな中で貴重な情報源の次のページを参考にNEHotspotHelperを使ってみるとはまるケースがある。
[iOS] Wi-Fi一覧でアピール表示し、パスワードを自動入力して接続させる方法(とまとレストランの販売促進アプリ) | Developers.IO
はまったケース
[Apple Inc. online: Authentication State Machine]
上図のAuthenticating
やMaintaining
の処理にフックしたい場合に、参考コードに処理を付け加える形で書くと、kNEHotspotHelperCommandTypeAuthenticate
がいつまでも呼ばれない。
というのは、下記のコードをよくよく読んでみると、
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@"🍅🍅🍅とまとレストラン🍅🍅🍅", kNEHotspotHelperOptionDisplayName, nil]; dispatch_queue_t queue = dispatch_get_main_queue(); BOOL isAvailable = [NEHotspotHelper registerWithOptions:options queue:queue handler: ^(NEHotspotHelperCommand * cmd) { NSMutableArray *hotspotList = [NSMutableArray new]; if(cmd.commandType == kNEHotspotHelperCommandTypeEvaluate || cmd.commandType == kNEHotspotHelperCommandTypeFilterScanList) { for (NEHotspotNetwork* network in cmd.networkList) { NSLog(@">%@", network.SSID); if ([network.SSID isEqualToString:@"spw05"]) { [network setConfidence:kNEHotspotHelperConfidenceHigh]; [network setPassword:@"password"]; [hotspotList addObject:network]; } } NEHotspotHelperResponse *response = [cmd createResponse:kNEHotspotHelperResultSuccess]; [response setNetworkList:hotspotList]; [response deliver]; } }];
[Developers.IO online: [iOS] Wi-Fi一覧でアピール表示し、パスワードを自動入力して接続させる方法(とまとレストランの販売促進アプリ) | Developers.IO]
kNEHotspotHelperCommandTypeEvaluate
のときはcmd.networkList
にはnil
が入ってくるので、setNetworkList
で空リストがセットされている。
そのため、対象のNetworkがNEHotspotHelperの管理対象から外れて、kNEHotspotHelperCommandTypeEvaluate
以降のkNEHotspotHelperCommandTypeAuthenticate
などのコマンドが送られない状態となっている。
kNEHotspotHelperCommandTypeAuthenticate
が呼ばれるために必要なこと
フォーラムの次の回答によると、
NEHotspotHelper (NetworkExtension iOS9.0) Sampl... | Apple Developer Forums
kNEHotspotHelperCommandTypeEvaluate
のときに下記の処理をすればAuthenticating
ステートが呼ばれるらしい。
- コマンドからレスポンスを作製する(NEHotspotHelperResponse *response = [cmd createResponse:kNEHotspotHelperResultSuccess])
- コマンドからnetworkを取得する(NENetwork *network = cmd.network)
- networkに
confidence
を設定する(setConfidence) - レスポンスにnetworkを追加する(setNetwork)
- レスポンスを配達する( [response deliver])
サンプルコード
以上を踏まえて、次のようなコードを書いてみると(ついでにSwift3に書き換え)、確かにauthenticate
が呼ばれるようになった。
よかったです。
let options : [String: NSString] = [ kNEHotspotHelperOptionDisplayName: "🍅🍅🍅とまとレストラン🍅🍅🍅" ] let isAvailable = NEHotspotHelper.register(options: options, queue: DispatchQueue.main) { (cmd) in print(cmd) switch cmd.commandType { case .filterScanList: let list = cmd.networkList var networks = [NEHotspotNetwork]() for network in list! { if network.ssid == "spw05" { network.setPassword("password") network.setConfidence(.high) networks.append(network) } } let response = cmd.createResponse(.success) response.setNetworkList(networks) response.deliver() case .evaluate: let network = cmd.network! let response = cmd.createResponse(.success) network.setConfidence(.high) response.setNetwork(network) response.deliver() case .authenticate: let network = cmd.network! let response = cmd.createResponse(.success) response.setNetwork(network) response.deliver() case .maintain: let network = cmd.network! let response = cmd.createResponse(.success) response.setNetwork(network) response.deliver() case .none: // anycode break case .presentUI: // anycode break case .logoff: // anycode break } }