programing

iPhone이 개인 라이브러리 없이 SSID를 얻습니다.

starjava 2023. 5. 2. 22:13
반응형

iPhone이 개인 라이브러리 없이 SSID를 얻습니다.

연결된 네트워크의 SSID를 볼 수 있는 완전히 합법적인 이유가 있는 상용 앱이 있습니다. 타사 하드웨어 장치용 애드혹 네트워크에 연결된 경우 인터넷에 연결된 경우와는 다른 방식으로 작동해야 합니다.

SSID를 얻는 것에 대해 제가 본 모든 것은 제가 개인 도서관인 Apple80211을 사용해야 한다는 것을 알려줍니다.개인 도서관을 사용하면 애플이 앱을 승인하지 않는다는 것도 읽었습니다.

내가 애플과 하드 사이에 낀 것일까요, 아니면 내가 놓치고 있는 것일까요?

iOS 7 또는 8 이후에는 다음을 수행할 수 있습니다(아래 그림과 같이 iOS 12+에 대한 Entitlement 필요).

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

시뮬레이터에서는 if가 지원되지 않습니다.장치에서 테스트합니다.

iOS 12

기능에서 WiFi 정보에 액세스할 수 있도록 설정해야 합니다.

중요 iOS 12 이상에서 이 기능을 사용하려면 Xcode로 앱에 대한 WiFi 정보 액세스 기능을 활성화합니다.이 기능을 활성화하면 Xcode가 자동으로 사용자의 사용 권한 파일 및 앱 ID에 액세스 WiFi 정보 사용 권한을 추가합니다.문서 링크

스위프트 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

}

iOS 10 이상에 대한 업데이트

CNCopy 지원됨인터페이스는 iOS 10에서 더 이상 사용되지 않습니다. (API 참조)

SystemConfiguration/CaptiveNetwork.h를 가져와 대상의 Linked Libraries에 SystemConfiguration.framework를 추가해야 합니다(빌드 단계에서).

다음은 swift(리키 리오마의 답변) 코드 조각입니다.

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

(중요: CNCopy 지원)인터페이스는 시뮬레이터에서 0을 반환합니다.)

목표-c에 대해서는 아래와 아래의 에사드의 답변을 참조하십시오.

+ (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에서 더 이상 사용되지 않습니다(위 참조).

NE Hotspot을 사용하는 것이 좋습니다.도우미(소스)

networkextension@apple.com 으로 애플에 이메일을 보내고 사용 권한을 요청해야 합니다.(소스)

샘플 코드(코드가 아님). 파블로 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;
}

참고 사항:예, CNCopySupported를 더 이상 사용하지 않습니다.iOS 9에서 인터페이스를 사용하고 iOS 10에서 위치를 변경했습니다.저는 애플 네트워킹 엔지니어와 이야기를 나눴는데, 많은 사람들이 래더를 신고하고 애플 개발자 포럼에서 이 문제에 대해 목소리를 낸 후 반전이 일어났습니다.

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

이것은 시뮬레이터가 아닌 장치에서 작동합니다.시스템 구성 프레임워크를 추가해야 합니다.

#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를 실행하는 경우 추가 단계를 수행해야 합니다.저는 이 코드를 작동시키기 위해 고군분투했고 마침내 애플의 사이트에서 이것을 발견했습니다: "iOS 12 이상에서 이 기능을 사용하려면 Xcode로 앱에 대한 액세스 WiFi 정보 기능을 활성화하십시오.이 기능을 활성화하면 Xcode는 자동으로 사용자의 사용 권한 파일 및 앱 ID에 액세스 WiFi 정보 사용 권한을 추가합니다." https://developer.apple.com/documentation/systemconfiguration/1614126-cncopycurrentnetworkinfo

CaptiveNetwork: http://developer.apple.com/library/ios/ #documentation/SystemConfiguration/Reference/CaptiveNetworkRef/Reference/Reference.html의 CNCopyCurrentNetworkInfo를 참조하십시오.

여기 짧고 달콤한 스위프트 버전이 있습니다.

Framework를 연결하고 가져오는 것을 잊지 마십시오.

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가 아닌 경우 메서드가 0으로 반환되므로 선택 사항입니다.

iOS 13의 경우

iOS 13부터 당신의 앱은 또한 사용하기 위해 코어 위치 액세스가 필요합니다.CNCopyCurrentNetworkInfo 현재 네트워크를 구성하거나 VPN 구성이 없는 경우 다음과 같이 작동합니다.
https://developer.apple.com/documentation/systemconfiguration/1614126-cncopycurrentnetworkinfo?language=objc 에서 발췌한 내용

따라서 다음과 같이 해야 합니다(애플 설명서 참조).
링크CoreLocation.framework도서관
추가location-services로서UIRequiredDeviceCapabilitiesInfo.plist의 키/값
추가 aNSLocationWhenInUseUsageDescription앱에 핵심 위치가 필요한 이유를 설명하는 Info.plist의 키/값
앱에 대한 "WiFi 정보 액세스" 사용 권한 추가

이제 목표-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];
            }
        }
    }        
        ...
    ...
}

언급URL : https://stackoverflow.com/questions/5198716/iphone-get-ssid-without-private-library

반응형