簡體   English   中英

iPhone無需私人圖書館即可獲得SSID

[英]iPhone get SSID without private library

我有一個商業應用程序,它有完全合法的理由來查看其連接到的網絡的SSID:如果將其連接到第三方硬件設備的Adhoc網絡,則其工作方式必須與正常情況不同。連接到互聯網。

我所看到的有關獲取SSID的所有信息都告訴我必須使用Apple80211,據我了解,這是一個私有庫。 我還讀到,如果我使用私有庫,Apple不會批准該應用程序。

我是被困在一個蘋果和一個困難的地方之間,還是在這里我缺少什么?

從iOS 7或8開始,您可以執行此操作(需要iOS 12+的權利,如下所示):

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

輸出示例:

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。 在您的設備上測試。

iOS 12

您必須從功能啟用訪問wifi信息。

重要提示要在iOS 12及更高版本中使用此功能,請在Xcode中為您的應用啟用訪問WiFi信息功能。 啟用此功能后,Xcode會自動將Access WiFi Information授權添加到您的授權文件和App ID中。 文檔鏈接

斯威夫特4.2

func getConnectedWifiInfo() -> [AnyHashable: Any]? {

    if let ifs = CFBridgingRetain( CNCopySupportedInterfaces()) as? [String],
        let ifName = ifs.first as CFString?,
        let info = CFBridgingRetain( CNCopyCurrentNetworkInfo((ifName))) as? [AnyHashable: Any] {

        return info
    }
    return nil

}

這是基於@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及更高版本的更新

iOS 10中不再棄用CNCopySupportedInterfaces。( API參考

您需要導入SystemConfiguration / CaptiveNetwork.h並將SystemConfiguration.framework添加到目標的鏈接庫(在構建階段)。

這是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開始,不提倡使用Captive Network *。 來源

* iOS 10中不再棄用,請參見上文。

建議您使用NEHotspotHelper( 源代碼

您將需要向apple發送電子郵件至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中的位置。我與一位蘋果網絡工程師進行了交談,在有很多人提交Radars並在Apple Developer論壇上討論了該問題之后,情況發生了逆轉。

這對我在設備(而不是模擬器)上有效。 確保添加系統配置框架。

#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>;

}

如果您運行的是iOS 12,則需要執行額外的步驟。 我一直在努力使此代碼起作用,並最終在Apple網站上找到了該代碼:“重要要在iOS 12及更高版本中使用此功能,請在Xcode中為您的應用啟用Access WiFi Information功能。啟用此功能時,Xcode會自動將訪問WiFi信息權利添加到您的權利文件和應用ID中。” https://developer.apple.com/documentation/systemconfiguration/1614126-cncopycurrentnetworkinfo

這是簡短而可愛的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-因此是可選的。

對於iOS 13

從iOS 13 CNCopyCurrentNetworkInfo除非您配置了當前網絡或具有VPN配置,否則您的應用還需要訪問核心位置才能使用CNCopyCurrentNetworkInfo 函數
摘自https://developer.apple.com/documentation/systemconfiguration/1614126-cncopycurrentnetworkinfo?language=objc

這就是您所需要的(請參閱Apple文檔 ):
-鏈接CoreLocation.framework
-在Info.plist中將location-services添加為UIRequiredDeviceCapabilities鍵/值
-在Info.plist中添加NSLocationWhenInUseUsageDescription鍵/值,以描述您的應用為何需要核心位置的原因
-為您的應用添加“訪​​問WiFi信息”權利

現在作為一個Objective-C示例,首先使用CNCopyCurrentNetworkInfo讀取網絡信息之前,先檢查是否已接受位置訪問:

- (void)fetchSSIDInfo {
    NSString *ssid = NSLocalizedString(@"not_found", nil);

    if (@available(iOS 13.0, *)) {
        if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) {
            NSLog(@"User has explicitly denied authorization for this application, or location services are disabled in Settings.");
        } else {
            CLLocationManager* cllocation = [[CLLocationManager alloc] init];
            if(![CLLocationManager locationServicesEnabled] || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined){
                [cllocation requestWhenInUseAuthorization];
                usleep(500);
                return [self fetchSSIDInfo];
            }
        }
    }

    NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
    id info = nil;
    for (NSString *ifnam in ifs) {
        info = (__bridge_transfer id)CNCopyCurrentNetworkInfo(
            (__bridge CFStringRef)ifnam);

        NSDictionary *infoDict = (NSDictionary *)info;
        for (NSString *key in infoDict.allKeys) {
            if ([key isEqualToString:@"SSID"]) {
                ssid = [infoDict objectForKey:key];
            }
        }
    }        
        ...
    ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM