Подтвердить что ты не робот

Обнаружение изменений в сетевом подключении с использованием возможностей развертывания, NSNotification и Network Link Conditioner в Swift

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

Как упоминалось в сообщении, в настоящее время я использую следующие классы и инструменты для работы:

  • Достижимость {.h, .m}
  • NSNotificationCenter
  • Сетевой концентратор

код

В AppDelegate.Swift я установил NSNotificationCenter для обнаружения изменений:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// ... 
// A: Checks if the device is connected to the internet

    var defaultCenter: Void = NSNotificationCenter().addObserver(self, selector:"checkForReachability", name: kReachabilityChangedNotification, object: nil)

}

В том же классе AppDelegate я также создал эту функцию для запуска при каждом изменении:

func checkForReachability () {

    var networkReachability = Reachability.reachabilityForInternetConnection()
    networkReachability.startNotifier()

    var remoteHostStatus = networkReachability.currentReachabilityStatus()
    if (remoteHostStatus.value == NotReachable.value) {
        println("Not Reachable")
    } else if (remoteHostStatus.value == ReachableViaWiFi.value) {
        println("Reachable via Wifi")
    } else {
        println("Reachable")
    }
}

Однако при использовании средства Network Link Conditioner для управления и моделирования изменений условий я не смог увидеть ни одно из этих изменений, отраженных в консоли. Любая помощь будет набухать!

4b9b3361

Ответ 1

Вы должны создать объект Reachability , прежде чем вы сможете получать от него уведомления. Также обязательно вызовите метод startNotifier() для создаваемого вами объекта Reachability. Вот пример того, как это сделать внутри вашего делегата приложения:

class AppDelegate: UIResponder, UIApplicationDelegate
{
    private var reachability:Reachability!;

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool
    {
        NSNotificationCenter.defaultCenter().addObserver(self, selector:"checkForReachability:", name: kReachabilityChangedNotification, object: nil);

        self.reachability = Reachability.reachabilityForInternetConnection();
        self.reachability.startNotifier();
    }

    @objc func checkForReachability(notification:NSNotification)
    {
        // Remove the next two lines of code. You cannot instantiate the object
        // you want to receive notifications from inside of the notification
        // handler that is meant for the notifications it emits.

        //var networkReachability = Reachability.reachabilityForInternetConnection()
        //networkReachability.startNotifier()

        let networkReachability = notification.object as Reachability;
        var remoteHostStatus = networkReachability.currentReachabilityStatus()

        if (remoteHostStatus.value == NotReachable.value)
        {
            println("Not Reachable")
        }
        else if (remoteHostStatus.value == ReachableViaWiFi.value)
        {
            println("Reachable via Wifi")
        }
        else
        {
            println("Reachable")
        }
    }
}

Я рекомендую вам взглянуть на документацию для NSNotificationCenter и NSNotification. Таким образом, в следующий раз вы узнаете, как работать с уведомлениями.

Swift 3

NotificationCenter.default.addObserver(self, selector:Selector(("checkForReachability:")), name: NSNotification.Name.reachabilityChanged, object: nil)
let reachability: Reachability = Reachability.forInternetConnection()
reachability.startNotifier()

Ответ 2

Обновлено для Swift 4/Swift 5 в соответствии с @Hardik.T

1. Импортируйте файл Reachability.swift из https://github.com/ashleymills/Reachability.swift/archive/master.zip в свой проект XCode

2. Создайте новый класс Swift: ConnectionManager.swift

class ConnectionManager {

static let sharedInstance = ConnectionManager()
private var reachability : Reachability!

func observeReachability(){
    self.reachability = Reachability()
    NotificationCenter.default.addObserver(self, selector:#selector(self.reachabilityChanged), name: NSNotification.Name.reachabilityChanged, object: nil)
    do {
        try self.reachability.startNotifier()
    }
    catch(let error) {
        print("Error occured while starting reachability notifications : \(error.localizedDescription)")
    }
}

@objc func reachabilityChanged(note: Notification) {
    let reachability = note.object as! Reachability
    switch reachability.connection {
    case .cellular:
        print("Network available via Cellular Data.")
        break
    case .wifi:
        print("Network available via WiFi.")
        break
    case .none:
        print("Network is not available.")
        break
    }
  }
}

3. Используйте его в своем файле AppDelegate:

func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    ConnectionManager.sharedInstance.observeReachability()
    return true
}

Ответ 3

Вместо того, чтобы загрязнять AppDelegate.swift с помощью обратных вызовов наблюдателя, я бы рекомендовал добавлять наблюдателей только в соответствующие контроллеры представлений.

AppDelegate.swift

import ReachabilitySwift


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate
{
    var reachability: Reachability?


    func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? ) -> Bool
    {
       self.reachability = Reachability()

       do
       {
          try reachability?.startNotifier()
       }
       catch
       {
          print( "ERROR: Could not start reachability notifier." )
       }

       return true
    }


    class func sharedAppDelegate() -> AppDelegate?
    {
        return UIApplication.shared.delegate as? AppDelegate
    }


    // Remaining functions
}

Пример ViewController:

class ExampleVC: UIViewController
{
    override func viewDidLoad()
    {
        // Add reachability observer
        if let reachability = AppDelegate.sharedAppDelegate()?.reachability
        {
            NotificationCenter.default.addObserver( self, selector: #selector( self.reachabilityChanged ),name: ReachabilityChangedNotification, object: reachability )
        }
    }


    @objc private func reachabilityChanged( notification: NSNotification )
    {
        guard let reachability = notification.object as? Reachability else
        {
            return
        }

        if reachability.isReachable
        {
            if reachability.isReachableViaWiFi
            {
                print("Reachable via WiFi")
            }
            else
            {
                print("Reachable via Cellular")
            }
        }
        else
        {
            print("Network not reachable")
        }
    }
}

Ответ 4

Ускоренный для быстрого 2.1 и XCode 7:

попробуйте эту третью сторону. Оцененный Класс Reachablity

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool
    {
 // Allocate a reachability object
        self.reach = Reachability.reachabilityForInternetConnection()

        // Tell the reachability that we DON'T want to be reachable on 3G/EDGE/CDMA
        self.reach!.reachableOnWWAN = false

        // Here we set up a NSNotification observer. The Reachability that caused the notification
        // is passed in the object parameter
        NSNotificationCenter.defaultCenter().addObserver(self,
            selector: "reachabilityChanged:",
            name: kReachabilityChangedNotification,
            object: nil)

        self.reach!.startNotifier()

return true
}

//Reachbality Notification Response

    func reachabilityChanged(notification: NSNotification) {
        if self.reach!.isReachableViaWiFi() || self.reach!.isReachableViaWWAN() {
            print("Service avalaible!!!")
        } else {
            print("No service avalaible!!!")

            AppHelper.showALertWithTag(0, title: constants.AppName.rawValue, message: "Please Check Your Internet Connection!", delegate: self, cancelButtonTitle: "OK", otherButtonTitle: nil)
        }
    }

Ответ 5

Обновлен ответ A. R. Younce для Swift 2:

func checkForReachability(notification:NSNotification) {
    if let networkReachability = notification.object as? Reachability {
        let remoteHostStatus = networkReachability.currentReachabilityStatus()

        if (remoteHostStatus == NotReachable) {
            print("Not Reachable")
        }
        else if (remoteHostStatus == ReachableViaWiFi) {
            print("Reachable via Wifi")
        }
        else {
            print("Reachable")
        }
    } else {
        print("Unknown")
    }
}

Ответ 6

На основе этого решения с открытым исходным кодом Завёрнутый в класс

Swift 5

import Foundation

final class ReachabilityHandler {

  private var reachability: Reachability? = Reachability()

  // MARK: - LifeCycle

  init() {
    configure()
  }

  deinit {
    NotificationCenter.default.removeObserver(self)
    reachability?.stopNotifier()
  }

  // MARK: - Private

  private func configure() {
    NotificationCenter.default.addObserver(self,
                                           selector: #selector(ReachabilityHandler.checkForReachability(notification:)),
                                           name: Notification.Name.reachabilityChanged,
                                           object: nil)
    try? reachability?.startNotifier()

  }

  @objc private func checkForReachability(notification: NSNotification) {
    let networkReachability = notification.object as? Reachability
    if let remoteHostStatus = networkReachability?.connection {
      switch remoteHostStatus {
        case .none:

        case .wifi,
             .cellular:

      }
    }
  }
}

В AppDelegate

class AppDelegate: UIResponder, UIApplicationDelegate {

  private var rechabilityObserver: ReachabilityHandler?

  var window: UIWindow?

  // MARK: - LifeCycle

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    rechabilityObserver = ReachabilityHandler()

    return true
  }
}

Ответ 7

Swift 2.0 - Проверка сети с помощью возможности масштабируемости, NSNotification

AppDelegate.swift

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 
{
    NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(self.checkNetworkStatus(_:)), name: "ReachabilityChangedNotification", object: nil);

    do{self.reachability = try Reachability.reachabilityForInternetConnection()}catch{}
    do{try self.reachability.startNotifier()}catch{}
    self.checkNetworkStatus()

    return true
}

Объявить переменную networkStatus

var networkStatus : Reachability.NetworkStatus!

checkNetworkStatus() Функция

func checkNetworkStatus()
{
    networkStatus = reachability.currentReachabilityStatus

    if (networkStatus == Reachability.NetworkStatus.NotReachable)
    {
        print("Not Reachable")
    }
    else
    {
        print("Reachable")
    }
}

OtherClass.Swift

let delegate = UIApplication.sharedApplication().delegate as! AppDelegate

if (delegate.networkStatus!=Reachability.NetworkStatus.NotReachable)
{
   // Call Webservice     
}
else
{
   delegate.checkNetworkStatus()  //Not Reachable print  
}

Ответ 8

1) Установите модуль или добавьте ReachabilitySwift в свой проект

2) в AppDelegate.swift

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(self.checkForReachability(_:)), name: "ReachabilityChangedNotification", object: nil);

        do {
            try self.reachability = Reachability.reachabilityForInternetConnection()
        }
        catch {
            print(error)
        }

        do {
            try self.reachability.startNotifier()
        }
        catch {
            print(error)
        }

        return true
    }

3)

func checkForReachability(notification:NSNotification) {
        let networkReachability = notification.object as! Reachability;
        let remoteHostStatus = networkReachability.currentReachabilityStatus

        if (remoteHostStatus == .NotReachable) {
            print("Not Reachable")
        }
        else if (remoteHostStatus == .ReachableViaWiFi || remoteHostStatus == .ReachableViaWWAN) {
            print("Reachable via Wifi or via WWAN")
        }
    }