2017-01-01 3 views
0

У меня есть tabBarController с 2 вкладками и Reachability класс для подключения к Интернету.Swift2 iOS Reachability Class и NSNotificatonCenter не принимает широковещательную рассылку

Внутри didFinishLaunching метода AppDelegate «s У меня есть checkReachability функцию, которая проверяет текущее подключение к сети, чтобы увидеть, если WiFi включен или выключен, и он будет транслировать NSNotification на второй вкладке в любом случае.

Внутри второй вкладки есть этикетка и внутри viewDidLoad есть 2 наблюдателя, которые слушают трансляции. У меня также есть 2 функции (вызванные наблюдателями), которые изменят текст меток на основе текущего сетевого соединения.

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

Почему текст не меняется и почему наблюдатели не отвечают?

достижимости Класс: FYI я получил достижимости Class от этого YouTube VID и я переключил его от Swift 3 к Swift 2.3: https://www.youtube.com/watch?v=IlsfXjESatg&t=532s

import Foundation 
import UIKit 
import SystemConfiguration 

protocol Utilities { 
} 

extension NSObject:Utilities{ 

    enum ReachabilityStatus { 
     case notReachable 
     case reachableViaWWAN 
     case reachableViaWiFi 
    } 

    var currentReachabilityStatus: ReachabilityStatus { 

     var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0)) 

     zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress)) 
     zeroAddress.sin_family = sa_family_t(AF_INET) 

     guard let defaultRouteReachability = withUnsafePointer(&zeroAddress, { 
      SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0)) 
     }) else { 
      return .notReachable 
     } 

     var flags: SCNetworkReachabilityFlags = [] 
     if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) { 
      return .notReachable 
     } 

     if flags.contains(SCNetworkReachabilityFlags.Reachable) == false{ 
      // The target host is not reachable. 
      return .notReachable 
     } 
     else if flags.contains(SCNetworkReachabilityFlags.IsWWAN) == true{ 
      // WWAN connections are OK if the calling application is using the CFNetwork APIs. 
      return .reachableViaWWAN 
     } 

     else if flags.contains(.ConnectionRequired) == false { 
      // If the target host is reachable and no connection is required then we'll assume that you're on Wi-Fi... 
      return .reachableViaWiFi 
     } 
     else if (flags.contains(.ConnectionOnDemand) == true || flags.contains(.ConnectionOnTraffic) == true) && flags.contains(.InterventionRequired) == false { 
      // The connection is on-demand (or on-traffic) if the calling application is using the CFSocketStream or higher APIs and no [user] intervention is needed 
      return .reachableViaWiFi 
     } 
     else { 
      return .notReachable 
     } 
    } 
} 

AppDelegate:

class AppDelegate: UIResponder, UIApplicationDelegate { 

var window: UIWindow? 

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 

    self.checkReachability() 

    return true 
} 
//This function is declared inside AppDelegate 
func checkReachability(){ 
    if currentReachabilityStatus == .reachableViaWiFi { 
      NSNotificationCenter.defaultCenter().postNotificationName("wifi", object: nil) 
    }else if currentReachabilityStatus == .reachableViaWWAN{ 
      print("WWAN.") 
    }else{ 
      NSNotificationCenter.defaultCenter().postNotificationName("noWifi", object: nil) 
    } 
} 

Вторая вкладка:

class SecondTabController: UIViewController { 

@IBOutlet weak var labelTwo: UILabel! 

override func viewDidLoad() { 
    super.viewDidLoad() 
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(wifiConnection), name: "wifi", object: nil) 

    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(noConnection), name: "noWifi", object: nil) 
} 

func wifiConnection(){ 
    self.labelTwo.text = "Wifi Connection" 
} 

func noConnection(){ 
    self.labelTwo.text = "No Connection" 
} 

deinit{ 
    NSNotificationCenter.defaultCenter().removeObserver(self, name: "wifi", object: nil) 
    NSNotificationCenter.defaultCenter().removeObserver(self, name: "noWifi", object: nil) 
} 
} 

ответ

1

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

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 
    // Your method `checkReachability` will post notifications: 
    self.checkReachability() 
    return true 
} 

Однако ваш SecondTabController еще не создан, и, таким образом, он еще не подписался на получение уведомления, что вы отправляете на старте приложения. Когда уведомления отправляются, они получают немедленно от любых подписчиков. Уведомления «не ждут», пока какой-либо абонент не будет добавлен позднее.

Возможно, вам нужен менеджер по достижению, который продолжает жить и отправляет уведомления в центр уведомлений всякий раз, когда изменяется доступность WiFi.

Возможно, вы захотите использовать существующих менеджеров достижимости, such as Alamofire's NetworkReachabilityManager as described in this question.

+0

Bumberg Спасибо за совет и HNY! Посмотрите на это видео. Он не использует tabBar, но устанавливает функцию checkStatus в файле didFinish (мин. 12:09) и имеет подписчика в другом представлении vc viewDidLoad (хотя одно приложение vc не является вкладкой). Когда он переключает Wi-Fi вкл/выкл, он работает нормально (мин. 29:35). Если моя вторая вкладка еще не создана, как только я ее нажал, она живая, в этот момент не следует включать/отключать wifi, пока все еще внутри этой вкладки работают как его? Я также ввел тот же код абонента в tabOne, поскольку он имеет только метку. Он загружается сразу при запуске, и там ничего не происходит. https://youtu.be/BlBhHgoW9wM - –

Смежные вопросы