首页 文章

iPhone获得没有私人图书馆的SSID

提问于
浏览
147

我有一个商业应用程序有一个完全正当的理由看到它所连接的网络的SSID:如果它连接到第三方硬件设备的Adhoc网络,它需要以不同于它的方式运行连接到互联网 .

我所看到的有关获取SSID的所有内容都告诉我必须使用Apple80211,我理解这是一个私有库 . 我还读到,如果我使用私人图书馆Apple将不会批准该应用程序 .

我被困在苹果和硬地之间,还是我在这里缺少什么?

8 回答

  • 10

    从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编写的代码示例的现代化 . 唯一的变化是引入更清晰的变量名称并采用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 . 在您的设备上测试 .

    在4.1之前,您可能会通过系统配置字典获得一些运气 . 例如,在我的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
    

    iOS 12

    您必须从功能启用访问wifi信息 .

    重要事项要在iOS 12及更高版本中使用此功能,请在Xcode中为您的应用启用Access WiFi信息功能 . 启用此功能后,Xcode会自动将Access WiFi信息权利添加到您的权利文件和应用程序ID中 . 文档链接

  • 179

    这是清理过的ARC版本,基于@ elsurudo的代码:

    - (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;
    }
    
  • 60

    更新iOS 10及更高版本

    iOS 10中不再弃用CNCopySupportedInterfaces . (API Reference

    您需要导入 SystemConfiguration/CaptiveNetwork.h 并将 SystemConfiguration.framework 添加到目标的链接库(在构建阶段) .

    这是swift _2784385中的代码片段:

    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
        }
    }
    

    Important: CNCopySupportedInterfaces在模拟器上返回nil . )

    对于Objective-c,请参阅Esad's answer here and below

    + (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,Captive Network已被弃用* . (source

    *不再在iOS 10中弃用,请参见上文 .

    建议你使用NEHotspotHelper(source

    您需要通过networkextension@apple.com向Apple发送电子邮件并申请权利 . (source

    示例代码(Not my code. See Pablo A's answer):

    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中的地位 . 我与一位Apple网络工程师进行了交谈,之后很多人提交了Radars并在Apple Developer论坛上发表了这个问题 .

  • 5

    这适用于我的设备(不是模拟器) . 确保添加系统配置框架 .

    #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;
    }
    
  • 58

    此代码可以很好地获取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>;
    

    }

  • 8

    如果您运行的是iOS 12,则需要执行额外的步骤 . 我've been struggling to make this code work and finally found this on Apple'的网站:"Important To use this function in iOS 12 and later, enable the Access WiFi Information capability for your app in Xcode. When you enable this capability, Xcode automatically adds the Access WiFi Information entitlement to your entitlements file and App ID." https://developer.apple.com/documentation/systemconfiguration/1614126-cncopycurrentnetworkinfo

  • 7
  • 28

    这是简短而甜蜜的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上时,该方法将返回nil - 因此是可选的 .

相关问题