iPhone получает SSID без частной библиотеки

У меня есть коммерческое приложение, которое имеет совершенно законную причину, чтобы увидеть SSID сети, к которой он подключен: если он подключен к сети Adhoc для стороннего аппаратного устройства, он должен работать по-другому, чем если бы он был подключенных к Интернету.

Все, что я видел о получении SSID, говорит мне, что я должен использовать Apple80211, который, как я понимаю, является частной библиотекой. Я также читал, что если я использую частную библиотеку, Apple не одобрит приложение.

Я застрял между Apple и тяжелым местом, или там что-то мне не хватает?

Начиная с iOS 7 или 8, вы можете сделать это, используя преимущества ARC и модhive, которые автоматически свяжутся в необходимой структуре:

@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 и модhive.)

Пример вывода:

 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. Тест на вашем устройстве.

До версии 4.1 у вас может быть определенная удача через словарь конфигурации системы. Например, используя scutil на моем Mac:

 $ scutil > show State:/Network/Interface/en1/AirPort  { Power Status : 1 SecureIBSSEnabled : FALSE BSSID :  0xcafecafecafe SSID_STR : XXXX SSID :  0x012345670123456701234567 Busy : FALSE CHANNEL :  { CHANNEL : 1 CHANNEL_FLAGS : 10 } } > exit 

Вот очищенная версия 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; } 

ОБНОВЛЕНИЕ ДЛЯ iOS 10 и выше

CNCopySupportedInterfaces больше не устарел в iOS 10. ( Справочник по API )

Вам необходимо импортировать SystemConfiguration / CaptiveNetwork.h и добавить SystemConfiguration.framework в связанные библиотеки ваших целей (в фазах сборки).

Вот fragment кода в swift (RikiRiocma’s Answer) :

 import Foundation import SystemConfiguration.CaptiveNetwork public class SSID { class func fetchSSIDInfo() -> String { var currentSSID = "" if let interfaces = CNCopySupportedInterfaces() { for i in 0.. = 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 см . Ответ Эсады здесь и ниже

 + (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 ( источник )

Вам нужно будет отправить электронное письмо по адресу [email protected] и запросить разрешения. ( источник )

Пример кода ( не мой код. См. Ответ Пабло А ):

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

Замечание: Да, они отказались от CNCopySupportedInterfaces в iOS 9 и отменили свою позицию в iOS 10. Я поговорил с инженером по сети Apple, и разворот пришел после того, как так много людей подали Radars и высказались об этой проблеме на форумах разработчиков Apple.

Это работает для меня на устройстве (не симуляторе). Убедитесь, что вы добавили фреймворк systemconfiguration.

 #import  + (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  @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>; 

}

Вот короткая и сладкая версия Swift.

Не забудьте связать и импортировать 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. Когда не на Wi-Fi, метод вернет nil – следовательно, необязательный.

Если вы используете iOS 12, вам нужно сделать дополнительный шаг. Я пытаюсь сделать этот код работой и, наконец, нашел это на сайте Apple: «Важно. Чтобы использовать эту функцию в iOS 12 и более поздних версиях, включите возможность доступа к информации о WiFi для вашего приложения в Xcode. Когда вы включите эту возможность, Xcode автоматически добавляет право доступа к беспроводной сети доступа к вашему файлу прав и идентификатору приложения. ” https://developer.apple.com/documentation/systemconfiguration/1614126-cncopycurrentnetworkinfo

  • Можно ли ориентироваться на более старые версии iOS при использовании Xcode 4.2 и iOS 5 SDK?
  • Подавление устаревших предупреждений в Xcode
  • Homebrew не находит XCode 4.3
  • Как представить модальный поверх текущего вида в Swift
  • Преобразовать десятичную дробную часть в Objective-C?
  • Xcode 6 / Beta 4: использование заголовков мостов с объектами инфраструктуры не поддерживается
  • Что такое Objective C ++?
  • Как найти свое текущее местоположение с помощью CoreLocation
  • Xcode: удалить горячую клавишу
  • iOS 8.1 Симулятор всегда использует раскладку клавиатуры США, несмотря на немецкую аппаратную клавиатуру
  • Как обновить iPhone SDK без повторной загрузки Xcode?
  • Давайте будем гением компьютера.