Edited at

SSIDを取得するにはアップルの許可が必要になった!?

More than 3 years have passed since last update.

iOS8までは、WiFiホットスポットなどのWifiネットワークを検出するために、 SystemConfiguration.CaptiveNetwork で提供されている

CNCopySupportedInterfacesCNCopyCurrentNetworkInfo というメソッドを利用できました。

CaptiveNetwork Reference

iOS9では Deprecated 扱いになっています。

@available(iOS, introduced=4.1, deprecated=9.0, message="For captive network applications, this has been completely replaced by <NetworkExtension/NEHotspotHelper.h>. For other applications, there is no direct replacement. Please file a bug describing your use of this API to that we can consider your requirements as this situation evolves.")

public func CNCopySupportedInterfaces() -> CFArray?

@available(iOS, introduced=4.1, deprecated=9.0, message="For captive network applications, this has been completely replaced by <NetworkExtension/NEHotspotHelper.h>. For other applications, there is no direct replacement. Please file a bug describing your use of this API to that we can consider your requirements as this situation evolves.")

public func CNCopyCurrentNetworkInfo(interfaceName: CFString) -> CFDictionary?

次のコードはXcode7.2でビルド時に警告が表示されますが、正しい結果が得られています。

import SystemConfiguration.CaptiveNetwork

/// 有効なWiFiネットワーク情報をすべて取得して、結果をコンソールに表示する
/// 警告は扱いだが、iOS9.2上でも一応動作する
func printRetrievedWifiNetwork() {
guard let interfaces:CFArray! = CNCopySupportedInterfaces() else {
return
}
print("interfaces: \(interfaces)")

for i in 0..<CFArrayGetCount(interfaces) {
guard let interfaceName: UnsafePointer<Void> = CFArrayGetValueAtIndex(interfaces, i) else {
continue
}
let rec = unsafeBitCast(interfaceName, AnyObject.self)
guard let unsafeInterfaceData = CNCopyCurrentNetworkInfo("\(rec)") else {
continue
}
guard let interfaceData = unsafeInterfaceData as Dictionary! else {
continue
}
print("SSID: \(interfaceData["SSID"] as! String)")
print("BSSID: \(interfaceData["BSSID"] as! String)")
}
}

結果はこんな感じ(1つしか見つからなかった場合)

interfaces: Optional((

en0
))
SSID: PLDTHOMEDSL-NK
BSSID: 18:1e:78:97:9b:2

iOS9では NetworkExtension を使用することが推奨されています。

Manage Hotspot Networks - NEHotspotHelper Class Reference

import NetworkExtension.NEHotspotHelper

または
import NetworkExtension

/// 有効なWiFiネットワーク情報をすべて取得して、結果をコンソールに表示する

/// Xcode7.2でワーニングやエラーが出ないことは確認済み
func printRetrievedWifiNetwork() {
let interfaces = NEHotspotHelper.supportedNetworkInterfaces()

print("--- \(interfaces)") // Appleの許可が得られるまで、常に空

for interface in interfaces as! [NEHotspotNetwork] {
print("--- \(interfaces)")
let ssid = interface.SSID
let bssid = interface.BSSID
let secure = interface.secure
let autoJoined = interface.autoJoined
let signalStrength = interface.signalStrength

print("ssid: \(ssid)")
print("bssid: \(bssid)")
print("secure: \(secure)")
print("autoJoined: \(autoJoined)")
print("signalStrength: \(signalStrength)")
}
}

上記のコードを実行しても、ネットワークが1件も取得できません。

おかしいと思い、Network Extension Framework Referenceに属するNEHotspotHelper Class Referenceをよく見ると、次のような記述がありました。


IMPORTANT

The com.apple.developer.networking.HotspotHelper entitlement is required in order to use NEHotspotHelper. To request this entitlement, send an email to networkextension@apple.com.


なんと、NEHotspotHelperを使用するための資格を取得する必要がありそうです。

そこで、空メールを networkextension@apple.com に送ってみたところ、次のような自動返信メールがすぐに届きました。

Thank you for requesting information about the Network Extension framework. Please respond to the following questions so that we may further evaluate your request.

Company name and address:

Developer Program Team ID:

Main contact person information (name, email, phone):

URL of your website containing your product description:

What is your company’s primary function? (Select all that apply)
[ ] Carrier
[ ] WiFi Aggregator
[ ] Firewall/Security
[ ] Router/Server manufacturer
[ ] Other: ...... (Please specify)

Which market(s) is your product targeted to? (Select all that apply)
[ ] Enterprise/Government
[ ] Education
[ ] Consumer

What type of solution does your company provide? (Select all that apply)
[ ] Hotspot WiFi solution
[ ] VPN Access solution for Enterprise/Business
[ ] Web Content Filtering solution

Which platforms does your application support? (Select all that apply)
[ ] iOS
[ ] OS X

What IP protocol does your application support?
[ ] IPv4
[ ] IPv6
[ ] Both IPv4 and IPv6

What Transport protocol does your application support?
[ ] UDP
[ ] TCP
[ ] Both UDP and TCP

What VPN protocol does your application support (for VPN solutions only)? (Select all that apply)
[ ] PPP
[ ] IKEv1/IPSec
[ ] IKEv2/IPSec
[ ] SSL
[ ] Other: ...... ( Please specify)
[ ] N/A

What Network layer does your application support (for VPN solutions only)?
[ ] Packet Tunnel (IP routing via virtual network interface)
[ ] App Proxy (Application payload)
[ ] Both IP Layer and App Proxy

What authentication protocol(s) does your solution utilize (for VPN solutions only)? (Select all that apply)
[ ] Certificate
[ ] Username/Password
[ ] MultiFactor Authentication
[ ] EAP Methods:..... (Please specify)
[ ] Other: ...... (Please Specify)
[ ] N/A

What authentication protocol(s) does your solution utilize (for Content Filter solutions only)? (Select all that apply)
[ ] Certificate
[ ] UseName/Password
[ ] MultiFactor Authentication
[ ] Other: ...... (Please Specify)
[ ] N/A

What authentication protocol(s) does your solution utilize (for Hotspot WiFi solutions only)? (Select all that apply)
[ ] WISPr 1.*
[ ] WISPr 2.*
[ ] Other HTTPS based
[ ] DNS
[ ] Passpoint (Hotpsot 2.0)
[ ] Other: ...... (Please specify)
[ ] N/A

Does your solution contain or integrate with an MDM server?
[ ] Yes
[ ] No

Does your solution integrate with a cloud service, such as Content Filter service, VPN service, MDM service, ...?
[ ] Yes: ...... (Please Specify)
[ ] No

Regards,
Developer Technical Support
Apple Worldwide Developer Relations

このように、NEHotspotHelperを利用する資格を得るには、当該アプリが何をするかを詳細に答える必要があります。

おそらく、不正利用防止などのセキュリティを考慮した結果だとは思いますが、面倒ですねw。

自分は今回実験をしたいだけで、アップルに申請するようなアプリを作るわけではないので、ここまでで終わりますが、実際にこのメールの質問に答えて許可を得られた方は是非コメントやリンクなどで情報をくださいませ。

補足:

ここまで書いた後で、What's New in Network Extension and VPN - WWDC 2015 - Videos - Apple Developerを見てみたところ、一番最後にさらっと触れられていました。