Самый простой способ обнаружить интернет-соединение на iOS? - PullRequest
146 голосов
/ 11 января 2012

Я знаю, что этот вопрос будет обманом многих других, однако я не чувствую, что простой случай хорошо объяснен здесь. Исходя из Android и BlackBerry, отправка запросов через HTTPUrlConnection мгновенно завершается сбоем, если нет доступного соединения. Это похоже на совершенно нормальное поведение, и я был удивлен, обнаружив, что NSURLConnection в iOS не эмулирует его.

Я понимаю, что Apple (и другие, кто ее расширил) предоставляют класс Reachability для определения состояния сети. Я был счастлив сначала увидеть это и полностью ожидал увидеть что-то вроде bool isNetworkAvailable(), но вместо этого к своему удивлению я обнаружил сложную систему, требующую регистрации уведомлений и обратных вызовов, и кучу, казалось бы, ненужных деталей. Должен быть лучший способ.

Мое приложение уже корректно обрабатывает сбои подключения, включая отсутствие подключения. Пользователь уведомляется о сбое, и приложение перемещается.

Таким образом, мои требования просты: одиночная синхронная функция, которую я могу вызвать перед всеми HTTP-запросами, чтобы определить, стоит ли мне беспокоиться об отправке запроса или нет. В идеале он не требует настройки и просто возвращает логическое значение.

Это действительно невозможно на iOS?

Ответы [ 16 ]

1 голос
/ 24 мая 2015

Вот хорошее решение для проверки подключения с помощью Swift, без использования Reachability.Я нашел его в этом блоге .

Создайте новый файл Swift в вашем проекте с именем Network.swift (например).Вставьте этот код в этот файл:

import Foundation

public class Network {

    class func isConnectedToNetwork()->Bool{

        var Status:Bool = false
        let url = NSURL(string: "http://google.com/")
        let request = NSMutableURLRequest(URL: url!)
        request.HTTPMethod = "HEAD"
        request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
        request.timeoutInterval = 10.0

        var response: NSURLResponse?

        var data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: nil) as NSData?

        if let httpResponse = response as? NSHTTPURLResponse {
            if httpResponse.statusCode == 200 {
                Status = true
            }
        }

        return Status
    }
}

Затем вы можете проверить подключение в любом месте вашего проекта, используя:

if Network.isConnectedToNetwork() == true {
    println("Internet connection OK")
} else {
    println("Internet connection FAILED")
}
0 голосов
/ 02 апреля 2018

Alamofire

Если вы уже используете Alamofire для всех RESTful Api, вы можете извлечь из этого пользу.

Вы можете добавить следующий класс в свое приложение и вызвать MNNetworkUtils.main.isConnected(), чтобы получить логическое значение, независимо от того, подключен он или нет.

#import Alamofire

class MNNetworkUtils {
  static let main = MNNetworkUtils()
  init() {
    manager = NetworkReachabilityManager(host: "google.com")
    listenForReachability()
  }

  private let manager: NetworkReachabilityManager?
  private var reachable: Bool = false
  private func listenForReachability() {
    self.manager?.listener = { [unowned self] status in
      switch status {
      case .notReachable:
        self.reachable = false
      case .reachable(_), .unknown:
        self.reachable = true
      }
    }
    self.manager?.startListening()
  }

  func isConnected() -> Bool {
    return reachable
  }
}

Это одноэлементный класс. Каждый раз, когда пользователь подключается или отключается от сети, он переопределяет self.reachable на true / false, потому что мы начинаем прослушивать NetworkReachabilityManager при инициализации синглтона.

Кроме того, для мониторинга достижимости вам необходимо предоставить хост, в настоящее время я использую google.com, при необходимости вы можете сменить его на любой другой хост или один из ваших.

0 голосов
/ 09 октября 2017

Замена для Apple Reachability переписана в Swift с замыканиями , вдохновлено tonymillion: https://github.com/ashleymills/Reachability.swift

  1. Перетащите файл Reachability.swift в ваш проект. В качестве альтернативы используйте CocoaPods или Carthage - см. Раздел Установка в README проекта.

  2. Получение уведомлений о подключении к сети:

    //declare this property where it won't go out of scope relative to your listener
    let reachability = Reachability()!
    
    reachability.whenReachable = { reachability in
        if reachability.isReachableViaWiFi {
            print("Reachable via WiFi")
        } else {
            print("Reachable via Cellular")
        }
    }
    
    reachability.whenUnreachable = { _ in
        print("Not reachable")
    }
    
    do {
        try reachability.startNotifier()
    } catch {
        print("Unable to start notifier")
    }
    

    и для остановки уведомлений

    reachability.stopNotifier()
    
0 голосов
/ 17 декабря 2015

Проверка доступности интернет-соединения в (iOS) Xcode 8.2, Swift 3.0

Это простой метод проверки доступности сети. Мне удалось перевести его на Swift 2.0 и вот окончательный код. Существующий класс Apple Reachability и другие сторонние библиотеки казались слишком сложными для перевода в Swift.

Работает как для 3G, так и для WiFi подключений.

Не забудьте добавить «SystemConfiguration.framework» в конструктор проектов.

//Create new swift class file Reachability in your project.

import SystemConfiguration

public class Reachability {
class func isConnectedToNetwork() -> Bool {
    var zeroAddress = sockaddr_in()
    zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
    zeroAddress.sin_family = sa_family_t(AF_INET)
    let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
        $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
            SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
        }
    }
    var flags = SCNetworkReachabilityFlags()
    if !SCNetworkReachabilityGetFlags(defaultRouteReachability! , &flags) {
        return false
    }
    let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
    let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
    return (isReachable && !needsConnection)
   }
}

// Check network connectivity from anywhere in project by using this code.

if Reachability.isConnectedToNetwork() == true {
     print("Internet connection OK")
} else {
 print("Internet connection FAILED")
}
0 голосов
/ 22 августа 2015

Мне также не понравились доступные варианты проверки в Интернете (Почему это не нативный API?!?!)

Моя собственная проблема была со 100% потерей пакетов - когда устройство подключено к маршрутизатору, но маршрутизатор не подключен к Интернету. Достижимость и другие будут зависать целую вечность. Я создал вспомогательный одноэлементный класс, чтобы справиться с этим, добавив время ожидания асинхронности. Это прекрасно работает в моем приложении. Надеюсь, поможет. Вот ссылка на github:

https://github.com/fareast555/TFInternetChecker

0 голосов
/ 28 января 2012

РЕДАКТИРОВАТЬ: Это не будет работать для сетевых URL-адресов (см. Комментарии)

Начиная с iOS 5, существует новый метод экземпляра NSURL:

- (BOOL)checkResourceIsReachableAndReturnError:(NSError **)error

Укажите его на интересующий вас веб-сайт или укажите на apple.com; Я думаю, что это новый однострочный звонок, чтобы проверить, работает ли интернет на вашем устройстве.

...