web-dev-qa-db-fra.com

iPhone obtenir SSID sans bibliothèque privée

J'ai une application commerciale qui a une raison tout à fait légitime de voir le SSID du réseau auquel elle est connectée: si elle est connectée à un réseau Adhoc pour un périphérique matériel tiers, elle doit fonctionner de manière différente de celle utilisée s'il est connecté. connecté à Internet.

Tout ce que j'ai vu sur l'obtention du SSID m'indique que je dois utiliser Apple80211, qui est une bibliothèque privée. J'ai également lu que si j'utilise une bibliothèque privée Apple n'approuvera pas l'application.

Suis-je coincé entre un Apple et un lieu difficile, ou y at-il quelque chose qui me manque ici?

149
Steve Reed Sr

À partir d'iOS 7 ou 8, vous pouvez le faire, en tirant parti d'ARC et de modules, qui se lieront automatiquement au cadre requis:

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

(Il s'agit d'une modernisation d'un exemple de code écrit pour iOS 4.1+. Les seuls changements ont été l'introduction de noms de variables plus clairs et l'adoption d'ARC et de modules.)

Exemple de sortie:

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

Notez qu'aucun if n'est pris en charge sur le simulateur. Testez sur votre appareil.

Avant la version 4.1, vous pourriez avoir un peu de chance grâce au dictionnaire de configuration système. Par exemple, en utilisant scutil sur mon Mac:

$ 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

Vous devez activer les informations d'accès wifi à partir des capacités.

Important Pour utiliser cette fonction dans iOS 12 et versions ultérieures, activez la fonctionnalité Accéder aux informations WiFi de votre application dans Xcode. Lorsque vous activez cette fonctionnalité, Xcode ajoute automatiquement le droit d'accès Informations WiFi à votre fichier de droits et à votre identifiant d'application. Lien vers la documentation

Swift 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

}
182

Voici la version ARC nettoyée, basée sur le code de @ 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
esad

MISE À JOUR POUR iOS 10 et plus

CNCopySupportedInterfaces n'est plus obsolète dans iOS 10. ( Référence de l'API )

Vous devez importer SystemConfiguration/CaptiveNetwork.h et ajouter SystemConfiguration.framework dans les bibliothèques liées de votre cible (dans les phases de construction).

Voici un extrait de code dans Swift (Réponse de 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
    }
}

( Important: CNCopySupportedInterfaces renvoie la valeur nil sur le simulateur.)

Pour Objective-c, voir réponse d'Esad ici et ci-dessous

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

MISE À JOUR POUR iOS 9

À partir d'iOS 9, Captive Network est obsolète *. ( source )

* N'est plus obsolète dans iOS 10, voir ci-dessus.

Il est recommandé d'utiliser NEHotspotHelper ( source )

Vous devrez envoyer un e-mail à Apple à l'adresse [email protected] et demander les droits.) ( source )

Exemple de code ( Pas mon code. Voir la réponse de 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;
}

Note latérale: Oui, ils ont déconseillé d'utiliser CNCopySupportedInterfaces dans iOS 9 et inversé leur position dans iOS 10. J'ai parlé à un ingénieur réseau Apple). problème sur le Apple pour les développeurs.

58
Emin Israfil iOS

Cela fonctionne pour moi sur l'appareil (pas de simulateur). Assurez-vous que vous ajoutez le framework de configuration système.

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

Ce code fonctionne bien pour obtenir le 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;
}

Et voici les résultats:

Connected at:{
BSSID = 0;
SSID = "Eqra'aOrange";
SSIDDATA = <45717261 27614f72 616e6765>;

}

10
Jameel

Si vous utilisez iOS 12, vous devrez effectuer une étape supplémentaire. J'ai eu du mal à faire fonctionner ce code et je l'ai enfin trouvé sur le site d'Apple: "Important Pour utiliser cette fonction dans iOS 12 et versions ultérieures, activez la fonctionnalité Informations d'accès WiFi de votre application dans Xcode. Lorsque vous activez cette fonctionnalité, Xcode automatiquement ajoute le droit d'accès aux informations WiFi à votre fichier de droits et votre identifiant d'application. " https://developer.Apple.com/documentation/systemconfiguration/1614126-cncopycurrentnetworkinfo

9
Muvimotv
7
onnoweb

Voici la version courte & douce Swift.

N'oubliez pas de lier et d'importer le Framework:

import UIKit
import SystemConfiguration.CaptiveNetwork

Définir la méthode:

func fetchSSIDInfo() -> CFDictionary? {
    if let
        ifs = CNCopySupportedInterfaces().takeUnretainedValue() as? [String],
        ifName = ifs.first,
        info = CNCopyCurrentNetworkInfo((ifName as CFStringRef))
    {
        return info.takeUnretainedValue()
    }
    return nil
}

Appelez la méthode quand vous en avez besoin:

if let
    ssidInfo = fetchSSIDInfo() as? [String:AnyObject],
    ssID = ssidInfo["SSID"] as? String
{
    println("SSID: \(ssID)")
} else {
    println("SSID not found")
}

Comme mentionné ailleurs, cela ne fonctionne que sur votre iDevice. En dehors du WiFi, la méthode retournera nil - d'où l'option.

5
n.Drake