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

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

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

  1. доступность {.h, .m}
  2. NSNotificationCenter
  3. Сеть Ссылка Кондиционер

код

на AppDelegate.Свифт!--8-->, Я установил 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")
    }
}

однако при использовании кондиционера сетевого соединения для манипулирования и имитации изменений в условиях я не смог увидеть ни одного из этих изменений в консоли. Любая помощь будет великолепна!

7 ответов


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

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

    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()

Upadated для swift 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)
        }
    }

обновленный ответ 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")
    }
}

вместо того, чтобы загрязнять 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")
        }
    }
}

обновлено для Swift 4 в соответствии с @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. использовать его в :

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

Swift 2.0-Проверьте Сеть, Используя Достижимость, NSNotification

AppDelegate.Свифт!--6-->

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.Свифт!--6-->

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

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

Swift 3

1) установить pod 'ReachabilitySwift' в проекте

2) в AppDelegate.Свифт!--6-->

пусть ГД = ГД()!

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    //declare this property where it won't go out of scope relative to your listener

    //declare this inside of viewWillAppear

    NotificationCenter.default.addObserver(self, selector: #selector(self.reachabilityChanged),name: ReachabilityChangedNotification,object: reachability)
    do{
        try reachability.startNotifier()
    }catch{
        print("could not start reachability notifier")
    }

    return true
}

3)

 func reachabilityChanged(note: Notification) {

    let reachability = note.object as! Reachability

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