iPhone没有私人图书馆得到SSID
我有一个商业应用程序,有一个完全合法的理由,看到它所连接的networking的SSID:如果它连接到一个Adhocnetworking的第三方硬件设备,它需要以不同的方式运作,如果它是连接到互联网。
我见过的关于获取SSID的一切都告诉我必须使用Apple80211,我知道这是一个私人图书馆。 我还读到,如果我使用私人图书馆,苹果将不会批准该应用程序。
我是在一个苹果和一个困难的地方之间卡住的,还是有我在这里失踪的东西?
从iOS 7或8开始,您可以做到这一点,它利用ARC和模块,它们将自动链接到所需的框架中:
@import SystemConfiguration.CaptiveNetwork; /** Returns first non-empty SSID network info dictionary. * @see CNCopyCurrentNetworkInfo */ - (NSDictionary *)fetchSSIDInfo { NSArray *interfaceNames = CFBridgingRelease(CNCopySupportedInterfaces()); NSLog(@"%s: Supported interfaces: %@", __func__, interfaceNames); NSDictionary *SSIDInfo; for (NSString *interfaceName in interfaceNames) { SSIDInfo = CFBridgingRelease( CNCopyCurrentNetworkInfo((__bridge CFStringRef)interfaceName)); NSLog(@"%s: %@ => %@", __func__, interfaceName, SSIDInfo); BOOL isNotEmpty = (SSIDInfo.count > 0); if (isNotEmpty) { break; } } return SSIDInfo; }
(这是为iOS 4.1+编写的代码示例的现代化版本,唯一的变化是引入更清晰的variables名称,并采用ARC和模块)。
示例输出:
2011-03-04 15:32:00.669 ShowSSID[4857:307] -[ShowSSIDAppDelegate fetchSSIDInfo]: Supported interfaces: ( en0 ) 2011-03-04 15:32:00.693 ShowSSID[4857:307] -[ShowSSIDAppDelegate fetchSSIDInfo]: en0 => { BSSID = "ca:fe:ca:fe:ca:fe"; SSID = XXXX; SSIDDATA = <01234567 01234567 01234567>; }
请注意,模拟器上不支持ifs。 在您的设备上testing。
在4.1之前,你可能会通过系统configuration字典有一些运气。 例如,在我的Mac上使用scutil
:
$ scutil > show State:/Network/Interface/en1/AirPort <dictionary> { Power Status : 1 SecureIBSSEnabled : FALSE BSSID : <data> 0xcafecafecafe SSID_STR : XXXX SSID : <data> 0x012345670123456701234567 Busy : FALSE CHANNEL : <dictionary> { CHANNEL : 1 CHANNEL_FLAGS : 10 } } > exit
这是根据@ elsurudo的代码清理的ARC版本:
- (id)fetchSSIDInfo { NSArray *ifs = (__bridge_transfer NSArray *)CNCopySupportedInterfaces(); NSLog(@"Supported interfaces: %@", ifs); NSDictionary *info; for (NSString *ifnam in ifs) { info = (__bridge_transfer NSDictionary *)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam); NSLog(@"%@ => %@", ifnam, info); if (info && [info count]) { break; } } return info; }
更新为iOS 10及以上
CNCopySupportedInterfaces在iOS 10中不再被弃用。( API参考 )
您需要导入SystemConfiguration / CaptiveNetwork.h并将SystemConfiguration.framework添加到目标的链接库(在构build阶段下)。
这是一个swift代码片段(RikiRiocma的答案) :
import Foundation import SystemConfiguration.CaptiveNetwork public class SSID { class func fetchSSIDInfo() -> String { var currentSSID = "" if let interfaces = CNCopySupportedInterfaces() { for i in 0..<CFArrayGetCount(interfaces) { let interfaceName: UnsafePointer<Void> = CFArrayGetValueAtIndex(interfaces, i) let rec = unsafeBitCast(interfaceName, AnyObject.self) let unsafeInterfaceData = CNCopyCurrentNetworkInfo("\(rec)") if unsafeInterfaceData != nil { let interfaceData = unsafeInterfaceData! as Dictionary! currentSSID = interfaceData["SSID"] as! String } } } return currentSSID } }
( 重要: CNCopySupportedInterfaces在模拟器上返回nil。)
对于Objective-c,请参阅Esad在这里和下面的回答
+ (NSString *)GetCurrentWifiHotSpotName { NSString *wifiName = nil; NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces(); for (NSString *ifnam in ifs) { NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam); if (info[@"SSID"]) { wifiName = info[@"SSID"]; } } return wifiName; }
更新为iOS 9
截至iOS 9俘虏networking已弃用*。 ( 来源 )
*不再在iOS 10中弃用,请参阅上文。
build议您使用NEHotspotHelper( 来源 )
您将需要通过networkextension@apple.com通过电子邮件向苹果发送电子邮件并请求授权。 ( 来源 )
示例代码( 不是我的代码,见Pablo A的答案 ):
for(NEHotspotNetwork *hotspotNetwork in [NEHotspotHelper supportedNetworkInterfaces]) { NSString *ssid = hotspotNetwork.SSID; NSString *bssid = hotspotNetwork.BSSID; BOOL secure = hotspotNetwork.secure; BOOL autoJoined = hotspotNetwork.autoJoined; double signalStrength = hotspotNetwork.signalStrength; }
注意:是的,他们弃用了iOS 9的CNCopySupportedInterfaces,并在iOS 10中颠覆了自己的位置。我跟一位苹果networking工程师交谈过,之后就有了这么多人提交了Radars,并在Apple Developer论坛上发表了这个问题。
这对我的设备(而不是模拟器)。 确保你添加了系统configuration框架。
#import <SystemConfiguration/CaptiveNetwork.h> + (NSString *)currentWifiSSID { // Does not work on the simulator. NSString *ssid = nil; NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces(); for (NSString *ifnam in ifs) { NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam); if (info[@"SSID"]) { ssid = info[@"SSID"]; } } return ssid; }
这个代码很好地工作,以获得SSID。
#import <SystemConfiguration/CaptiveNetwork.h> @implementation IODAppDelegate @synthesize window = _window; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { CFArrayRef myArray = CNCopySupportedInterfaces(); CFDictionaryRef myDict = CNCopyCurrentNetworkInfo(CFArrayGetValueAtIndex(myArray, 0)); NSLog(@"Connected at:%@",myDict); NSDictionary *myDictionary = (__bridge_transfer NSDictionary*)myDict; NSString * BSSID = [myDictionary objectForKey:@"BSSID"]; NSLog(@"bssid is %@",BSSID); // Override point for customization after application launch. return YES; }
这是结果:
Connected at:{ BSSID = 0; SSID = "Eqra'aOrange"; SSIDDATA = <45717261 27614f72 616e6765>;
}
请参阅CaptiveNetwork中的CNCopyCurrentNetworkInfo: http : //developer.apple.com/library/ios/#documentation/SystemConfiguration/Reference/CaptiveNetworkRef/Reference/reference.html 。
这里是简短和甜蜜的Swift版本。
记得链接和导入框架:
import UIKit import SystemConfiguration.CaptiveNetwork
定义方法:
func fetchSSIDInfo() -> CFDictionary? { if let ifs = CNCopySupportedInterfaces().takeUnretainedValue() as? [String], ifName = ifs.first, info = CNCopyCurrentNetworkInfo((ifName as CFStringRef)) { return info.takeUnretainedValue() } return nil }
在需要时调用该方法:
if let ssidInfo = fetchSSIDInfo() as? [String:AnyObject], ssID = ssidInfo["SSID"] as? String { println("SSID: \(ssID)") } else { println("SSID not found") }
如别处所述,这只适用于您的iDevice。 当不使用WiFi时,该方法将返回零 – 因此可选。