[iOS 13] iOS 13からSSIDの取得方法が変わりました
iOS 13
からSSIDの取得方法が変わり、iOS 12
まで取得出来ていた方法では取得できなくなりました。
iOS 12までの取得方法
環境
Xcode 10.1
Swift 4.2
コード
import UIKit import SystemConfiguration.CaptiveNetwork class ViewController: UIViewController { var ssid: String { if let interfaces = CNCopySupportedInterfaces() as NSArray? { for interface in interfaces { if let interfaceInfo = CNCopyCurrentNetworkInfo(interface as! CFString) as NSDictionary?, let ssid = interfaceInfo[kCNNetworkInfoKeySSID as String] as? String { return ssid } } } return "取得できませんでした。" } override func viewDidLoad() { super.viewDidLoad() print("ssid:\(self.ssid)") } }
iOS 12
からはAccess Wifi Information
を追加する必要があります。
参考:iOS12以降でCNCopyCurrentNetworkInfo() の注意点
iOS 12
で実行すると、現在接続中のSSIDがログに出力されるかと思います。
iOS 13
で同じように実行すると、以下のようなログがでます。
ssid:Wi-Fi
SSIDが取れずWi-Fi
となってしまっています。
原因
WWDC2019のAdvances in Networking, Part 2で発表された内容が影響しているようです。
一部抜粋
And one of the things we realized is that accessing Wi-Fi information can be used to infer locations. So starting now, to access that Wi-Fi information, you will need the same kind of privileges that you need to get other location information.
Google翻訳
そして、私たちが気づいたことの1つは、Wi-Fi情報へのアクセスを使用して場所を推測できることです。 したがって、今から、そのWi-Fi情報にアクセスするには、他の位置情報を取得するために必要なのと同じ種類の特権が必要になります。
Wi-Fi情報にアクセスするには、位置情報を取得する権限が必要になったようです。
対応方法
iOS13でSSIDを取得するには、位置情報の許可を求めます。
先ほどのソースを修正します。
import UIKit import SystemConfiguration.CaptiveNetwork import CoreLocation class ViewController: UIViewController { private var locationManager = CLLocationManager() var ssid: String { if let interfaces = CNCopySupportedInterfaces() as NSArray? { for interface in interfaces { if let interfaceInfo = CNCopyCurrentNetworkInfo(interface as! CFString) as NSDictionary?, let ssid = interfaceInfo[kCNNetworkInfoKeySSID as String] as? String { return ssid } } } return "取得できませんでした。" } override func viewDidLoad() { super.viewDidLoad() if #available(iOS 13.0, *) { self.locationManager.delegate = self self.locationManager.requestWhenInUseAuthorization() } else { print("ssid:\(self.ssid)") } } } extension ViewController: CLLocationManagerDelegate { func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { print("ssid:\(self.ssid)") } }
iOS 13
で実行して位置情報を許可すると、SSIDがログに出力されます。
検証
CNCopyCurrentNetworkInfoのページを見ると、位置情報が許可されていない場合の挙動として、以下の記載があります。
・An app linked against iOS 12 or earlier receives a dictionary with pseudo-values. In this case, the SSID is Wi-Fi (or WLAN in the China region), and the BSSID is 00:00:00:00:00:00.
・An app linked against iOS 13 or later receives NULL.
Google翻訳
・iOS 12以前に対してリンクされたアプリは、擬似値を持つ辞書を受け取ります。
この場合、SSIDはWi-Fi(または中国地域のWLAN)であり、BSSIDは00:00:00:00:00:00です。
・iOS 13以降に対してリンクされたアプリはNULLを受け取ります。
ビルドするSDKによって挙動が変わるようなので、Xcode 10
とXcode 11
でビルドして動作を検証してみます。
XCode 10でビルドして、iOS 13で動作
ssid:Wi-Fi
CNCopyCurrentNetworkInfo
は取れてますが、Wi-Fi
が固定で返ってきます。
XCode 11でビルドして、iOS 13で動作
ssid:取得できませんでした。
CNCopyCurrentNetworkInfo
がnil
になり、SSIDを取得できませんでした。
最後に
あまりSSIDを取得する機会はないと思いますが、何かの参考になれば幸いです。
最後までご覧いただき、ありがとうございました。