निजी पुस्तकालय के बिना iPhone SSID मिलता है


154

मेरे पास एक व्यावसायिक ऐप है जो नेटवर्क के SSID को देखने के लिए एक पूरी तरह से वैध कारण है जो इससे जुड़ा हुआ है: यदि यह एक 3rd पार्टी हार्डवेयर डिवाइस के लिए Adhoc नेटवर्क से जुड़ा है तो इसे अलग तरीके से कार्य करने की आवश्यकता होती है, जैसे कि यह है इंटरनेट से जुड़ा हुआ।

SSID प्राप्त करने के बारे में मैंने जो कुछ भी देखा है वह बताता है कि मुझे Apple80211 का उपयोग करना है, जो मुझे लगता है कि एक निजी पुस्तकालय है। मैंने यह भी पढ़ा कि अगर मैं एक निजी पुस्तकालय का उपयोग करता हूं तो ऐप्पल ऐप को मंजूरी नहीं देगा।

क्या मैं एक Apple और एक कठिन जगह के बीच फंस गया हूं, या कुछ ऐसा है जो मैं यहां याद कर रहा हूं?


जवाबों:


186

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

ध्यान दें कि कोई भी आइकॉन सिम्युलेटर पर समर्थित नहीं है। अपने डिवाइस पर परीक्षण करें।

iOS 12

आपको क्षमताओं से वाईफ़ाई जानकारी को सक्षम करना होगा।

महत्वपूर्ण iOS 12 में और बाद में इस फ़ंक्शन का उपयोग करने के लिए, Xcode में अपने ऐप के लिए Access WiFi सूचना क्षमता को सक्षम करें। जब आप इस क्षमता को सक्षम करते हैं, तो Xcode स्वचालित रूप से आपकी एंटाइटेलमेंट फ़ाइल और ऐप आईडी में प्रवेश वाईफाई सूचना का अधिकार जोड़ता है। डॉक्यूमेंटेशन लिंक

स्विफ्ट 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

}

8
धन्यवाद! यदि आप ARC का उपयोग कर रहे हैं, तो यहां पर यह कैसा दिखना चाहिए: - (id) fetchSSIDInfo {NSArray * ifs = ( bridge_transfer id) सीएनसीकोपर्सअपइन्टरफेस (); NSLog (@ "% s: समर्थित इंटरफेस:% @", _func , ifs ); आईडी जानकारी = नील; for (NSString * ifnam in ifs) {जानकारी = ( Bridge_transfer id) सीएनसीकोपर्सनल नेटवर्क्सइन्फो (( _bridge CFStringRef) ifnam); NSLog (@ "% s:% @ =>% @", __func , ifnam, info); अगर (जानकारी && [जानकारी गणना]) {विराम; }} जानकारी वापस; }
elsurudo

1
+1 महान काम करता है! अपनी परियोजना में [+] ढांचे को जोड़ने / जोड़ने के लिए मत भूलना। यदि आप इस विधि का उपयोग करते समय अजीब संकलन त्रुटियों को देखते हैं जो संभवतः आपकी समस्या है। उदाहरण के लिए, लौटाए गए शब्दकोश उपयोग से SSID प्राप्त करने के लिए // एक ऐसी वस्तु वस्तु प्राप्त करना जिसमें नेटवर्क की जानकारी हो, जिसमें iPhone NSDictionary * networkDict = [self fetchSSIDInfo] से जुड़ा हो; // नेटवर्क जानकारी से SSID का चयन करें NSString * iPhoneNetworkSSID = [networkDict objectForKey: @ "SSID"];
ग्रोत

क्या किसी को पता है कि बीएसएसआईडी क्या है? यह एक रूटर के मैक पते जैसा दिखता है, लेकिन यह वास्तव में नहीं है। न तो यह डिवाइस का मैक एड्रेस है।
5

1
@Filip अद्यतित एआरसी के अनुकूल कोड पता मॉड्यूलर का उपयोग करके इसे शामिल करता है (@import इसके बजाय #import)। क्लैंग स्वचालित रूप से आवश्यक ढांचे में लिंक करेगा जब एक मॉड्यूल, बल्कि केवल हेडर से आयात किया जाता है।
जेरेमी डब्ल्यू।

1
iOS 13 बीटा को अब CNCopyCurrentNetworkInfoउपयोगी जानकारी वापस करने की क्षमता के अलावा स्थान अनुमति की आवश्यकता है ; अन्यथा यह वापस आ जाता है nil। देखें: stackoverflow.com/questions/56583650/…
RedMatt

61

यहां @ 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;
}

1
एआरसी का उपयोग करने के बाद से यह वास्तव में पसंदीदा उत्तर होना चाहिए। मैं इसे शुरू से ही याद कर रहा था, क्योंकि यह जवाब नहीं था।
जोहान कार्ल्ससन

@mindbomb सही है, यहाँ उस मुद्दे के बारे में एक सवाल है: stackoverflow.com/questions/31555640/…
newenglander

हाँ, Apple ने iOS9 बेटस में अपग्रेड करने के बाद CaptiveNetwork API को फिर से सक्षम किया।
माइंडबॉम्ब

@mindbomb क्या अब भी यही है? मैं इसे लागू करने के मुद्दे हैं।
सम्यग्नि

@SamYoungNY ध्यान दें कि यह केवल डिवाइस पर काम करता है, सिम्युलेटर पर एक खाली लौटा है
esad

60

IOS 10 और ऊपर के लिए अद्यतन

IOS 10 में अब सीएनसीोपीसॉर्पोर्टेडइन्टरफेस रिक्त नहीं किया गया है ( एपीआई संदर्भ )

आपको SystemConfiguration / CaptiveNetwork.h को आयात करने और अपने लक्ष्य के लिंक्ड लाइब्रेरीज़ (बिल्ड चरणों के तहत) में SystemConfiguration.framework जोड़ने की आवश्यकता है ।

यहाँ एक कोड स्निपेट स्विफ्ट में है (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
    }
}

( महत्वपूर्ण: सीएनसीकोपसुपर्र्डइंटरफ़ोर्स सिम्युलेटर पर शून्य देता है।)

ऑब्जेक्टिव-सी के लिए, यहां और नीचे एसाड का उत्तर देखें

+ (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 के रूप में कैप्टिव नेटवर्क * पदावनत है। ( स्रोत )

* अब iOS 10 में नहीं, ऊपर देखें

यह अनुशंसा की जाती है कि आप NEHotspotHelper का उपयोग करें ( स्रोत का ) का

आपको Apple को networkextension@apple.com पर ईमेल करना होगा और एंटाइटेलमेंट का अनुरोध करना होगा। ( स्रोत )

नमूना कोड ( मेरा कोड नहीं। पाब्लो ए का जवाब देखें ):

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 में सीएनसीोपीसुपरटीनटेरफेस को अपदस्थ कर दिया और iOS 10 में अपनी स्थिति को उलट दिया। मैंने एक Apple नेटवर्किंग इंजीनियर के साथ बात की और इतने सारे लोगों ने रैडर्स दायर किए और Apple डेवलपर मंचों पर इस मुद्दे के बारे में बात करने के बाद पलट दिया।


मुझे नेटवर्क एक्सटेंशन का उपयोग करने के लिए ऐप्पल द्वारा अनुमोदित किया गया था, लेकिन मुझे अभी भी [NEHotspotHelper समर्थितNetworkInterfaces] से खाली सरणी मिली है। क्या आप इसका संभावित कारण जानते हैं?
JZAU

28

यह मेरे लिए डिवाइस पर काम करता है (सिम्युलेटर नहीं)। सुनिश्चित करें कि आप systemconfiguration ढांचे को जोड़ते हैं।

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

10

यह कोड 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>;

}


1
पूरी तरह से काम किया।
योमो

9

यदि आप iOS 12 चला रहे हैं तो आपको एक अतिरिक्त कदम उठाने की आवश्यकता होगी। मैं इस कोड को काम करने के लिए संघर्ष कर रहा हूं और अंत में इसे Apple की साइट पर पाया गया: "महत्वपूर्ण iOS 12 में इस फ़ंक्शन का उपयोग करना और बाद में, Xcode में अपने ऐप के लिए एक्सेस वाईफाई सूचना क्षमता को सक्षम करना। जब आप इस क्षमता को सक्षम करते हैं, तो Xcode स्वचालित रूप से सक्षम होता है। आपकी एंटाइटेलमेंट फ़ाइल और ऐप आईडी में एक्सेस वाईफाई सूचना का अधिकार जोड़ता है। " https://developer.apple.com/documentation/systemconfiguration/1614126-cncopycurrentnetworkinfo


धन्यवाद, इसने मेरा मुद्दा तय कर दिया!
david72


5

यहाँ संक्षिप्त और मीठा स्विफ्ट संस्करण है।

फ्रेमवर्क लिंक और आयात करना याद रखें:

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 पर काम करता है। जब वाईफाई पर नहीं, तो विधि शून्य पर लौटेगी - इसलिए वैकल्पिक।


2

IOS 13 के लिए

IOS 13 से आपके ऐप को CNCopyCurrentNetworkInfo फ़ंक्शन का उपयोग करने के लिए कोर लोकेशन एक्सेस की भी आवश्यकता होती है जब तक कि यह वर्तमान नेटवर्क को कॉन्फ़िगर नहीं करता है या वीपीएन कॉन्फ़िगरेशन नहीं है:
https://developer.apple.com/documentation/systemconfiguration/1614126-cncopycurrentnetworkinfo?language=objc से उद्धरण

यह इसलिए है कि तुम क्या है (देखें जरूरत सेब प्रलेखन ):
- लिंक CoreLocation.frameworkपुस्तकालय
- जोड़ें location-servicesएक के रूप में UIRequiredDeviceCapabilitiesमें की / मान Info.plist
- एक जोड़े NSLocationWhenInUseUsageDescriptionमें कुंजी / मान Info.plist का वर्णन क्यों अपने अनुप्रयोग कोर स्थान की आवश्यकता है
- "प्रवेश वाईफाई जोड़े सूचना "आपके ऐप के लिए पात्रता

अब एक उद्देश्य-सी उदाहरण के रूप में, पहले जांच लें कि नेटवर्क एक्सेस का उपयोग करने से पहले स्थान का उपयोग स्वीकार कर लिया गया है या नहीं 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];
            }
        }
    }        
        ...
    ...
}

IOS13 पर इसकी आवश्यकता होती है, अन्यथा आपको सीएनसीोपीकैन्टर नेटवर्क्सइन्फो () के लिए शून्य मिला
फ्रांज वैंग

@Sugar हां वास्तव में iOS13 - मेरे जवाब की पहली पंक्ति देखें
फ्रैंकोइस बी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.