Как проверить локальный Wi-Fi (не только сотовую связь) с помощью iPhone SDK?

В настоящее время я использую следующее, чтобы проверить, доступен ли Wi-Fi для моего приложения:

#import  static inline BOOL addressReachable(const struct sockaddr_in *hostAddress); BOOL localWiFiAvailable() { struct sockaddr_in localWifiAddress; bzero(&localWifiAddress, sizeof(localWifiAddress)); localWifiAddress.sin_len = sizeof(localWifiAddress); localWifiAddress.sin_family = AF_INET; // IN_LINKLOCALNETNUM is defined in  as 169.254.0.0 localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM); return addressReachable(&localWifiAddress); } static inline BOOL addressReachable(const struct sockaddr_in *hostAddress) { const SCNetworkReachabilityRef target = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)hostAddress); if (target != NULL) { SCNetworkReachabilityFlags flags = 0; const BOOL reachable = SCNetworkReachabilityGetFlags(target, &flags); CFRelease(target); return reachable && (flags & kSCNetworkFlagsReachable); } return NO; } 

Это, однако, не возвращает NO, как это должно быть, когда iPhone подключен только к сотовой сети, но не к сети Wi-Fi. Кто-нибудь знает, как это исправить?

редактировать

Так вот что я в итоге использовал:

 #import  // For AF_INET, etc. #import  // For getifaddrs() #import  // For IFF_LOOPBACK BOOL localWiFiAvailable() { struct ifaddrs *addresses; struct ifaddrs *cursor; BOOL wiFiAvailable = NO; if (getifaddrs(&addresses) != 0) return NO; cursor = addresses; while (cursor != NULL) { if (cursor -> ifa_addr -> sa_family == AF_INET && !(cursor -> ifa_flags & IFF_LOOPBACK)) // Ignore the loopback address { // Check for WiFi adapter if (strcmp(cursor -> ifa_name, "en0") == 0) { wiFiAvailable = YES; break; } } cursor = cursor -> ifa_next; } freeifaddrs(addresses); return wiFiAvailable; } 

Спасибо «непрощенный» (и, по-видимому, Мэтт Браун).

Во-первых, измените свой метод addressReachable. Вместо

 return reachable && (flags & kSCNetworkFlagsReachable); 

добавьте следующее:

 BOOL isReachable = ((flags & kSCNetworkFlagsReachable) != 0); BOOL needsConnection = ((flags & kSCNetworkFlagsConnectionRequired) != 0); return (isReachable && !needsConnection) ? YES : NO; 

Это правильный способ проверить доступность соединения. Теперь, если вы хотите четко различать сотовую и Wi-Fi, измените свой метод, чтобы вернуть int и использовать следующие

 BOOL isReachable = ((flags & kSCNetworkFlagsReachable) != 0); BOOL needsConnection = ((flags & kSCNetworkFlagsConnectionRequired) != 0); if(isReachable && !needsConnection) // connection is available { // determine what type of connection is available BOOL isCellularConnection = ((flags & kSCNetworkReachabilityFlagsIsWWAN) != 0); NSString *wifiIPAddress = [self getWiFiIPAddress]; if(isCellularConnection) return 1; // cellular connection available if(wifiIPAddress) return 2; // wifi connection available } else return 0; // no connection at all 

Метод getWiFiIPAddress любезно предоставлен Мэттом Брауном, и его можно найти здесь .

Еще кое-что. Флаг kSCNetworkReachabilityFlagsIsDirect может рассказать вам, проходит ли сетевой трафик через шлюз или поступает напрямую. Это может быть полезно в некоторых случаях.

Код работает правильно на устройстве. На симуляторе будет объявлено, что вы подключены через Wi-Fi при подключении через кабель Ethernet и не укажете соединения, если вы подключены через Wi-Fi.

См. Эту ссылку: http://developer.apple.com/iphone/library/samplecode/Reachability/

Вы должны быть зарегистрированным разработчиком, чтобы загрузить образец кода. Также и это важно! API API для повышения производительности работает для SDK 3.0+, он выходит из строя для более низких версий.

BTW, новым HIG, все приложения, которые полагаются на соединение WiFi, должны предупредить пользователя об его отсутствии, то есть, если устройство не подключено к Wi-Fi, сообщите об этом пользователю.

Быстрая версия

 import Foundation import SystemConfiguration public class Reachability { class func isInternetAvailable() -> Bool { let IPaddress = "google.com"//WebServicesUtil.sharedInstance.getHostIPAddress() if let host_name = IPaddress.cStringUsingEncoding(NSASCIIStringEncoding) { let reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, host_name).takeRetainedValue() var flags: SCNetworkReachabilityFlags = 0 if SCNetworkReachabilityGetFlags(reachability, &flags) == 0 { return false } let isReachable = (flags & UInt32(kSCNetworkFlagsReachable)) != 0 let needsConnection = (flags & UInt32(kSCNetworkFlagsConnectionRequired)) != 0 return (isReachable && !needsConnection) } else { return false } } } 

Ознакомьтесь с classом Reachability, предоставляемым Apple. Это позволяет вам проверить, какое подключение имеет устройство в настоящее время, между Wi-Fi, сотовой или нет. Вы можете даже зарегистрироваться для уведомлений при изменении связи.

К сожалению, Google сейчас для меня не работает, но Googling «Достижение iPhone» поможет вам в том, что вам нужно.

 -(Bool)isDataSourceAvailableNow { BOOL isDataSourceAvailable; bool success = false; const char *host_name = [@"www.google.com" cStringUsingEncoding:NSASCIIStringEncoding]; SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, host_name); if (reachability) { SCNetworkReachabilityFlags flags; success = SCNetworkReachabilityGetFlags(reachability, &flags); isDataSourceAvailable = success && (flags & kSCNetworkFlagsReachable) && !(flags & kSCNetworkFlagsConnectionRequired); CFRelease(reachability); } return isDataSourceAvailable; } 
  • Что такое двойная звезда (например, NSError **)?
  • как отобразить тестовый баннер IAd в симуляторе
  • Как обрабатывать дублируемую символьную ошибку от сторонних библиотек?
  • Пейзажный режим ТОЛЬКО для iPhone или iPad
  • Как Apple знает, что вы используете частный API?
  • С ARC, что лучше: alloc или autorelease инициализаторы?
  • Как я смогу удалить объекты из NSMutableArray?
  • UISwitch в ячейке UITableView
  • Как установить получателей для UIActivityViewController в iOS 6?
  • Можно ли показать изображение в UIAlertView?
  • Воспроизведение музыки в фоновом режиме с помощью AVAudioplayer
  • Interesting Posts

    Рост объема Amazon EBS Объем

    SpringBoot – создание файлов jar – нет classов автоматической настройки, найденных в META-INF / spring.factories

    Абстракция VS Информация, скрывающая VS Encapsulation

    Исключить определенную подпапку в библиотеке проигрывателя Windows Media

    Laravel – Route :: resource vs Route :: controller

    Как запустить eclipse в чистом режиме? и что произойдет, если мы это сделаем?

    Есть ли более быстрый способ изменить приложения по умолчанию, связанные с типами файлов в OS X?

    Есть ли эмулятор консоли Windows?

    Content Type text / xml; charset = utf-8 не поддерживается службой

    Какова лучшая страtagsя для модульных приложений, управляемых базами данных?

    Как записать файл в папку ресурсов / изображений приложения?

    Успешная assembly с множеством ошибок в машинописных файлах с машинописными текстами

    Как запустить функцию jquery в Angular 2 после каждой загрузки компонента

    Сообщение INSUFFICENT_STORAGE_MEMORY при установке 50 мб apk в эмуляторе

    C getline () – как работать с буферами / как читать неизвестное количество значений в массиве

    Давайте будем гением компьютера.