Reputation: 19592
I have a tabBarController with 2 tabs and a Reachability
class for the internet connection.
Inside the AppDelegate
's didFinishLaunching
method I have a checkReachability
function that checks the current network connection to see if wifi is on or off and it will broadcast a NSNotification
to the second tab in either case.
Inside the second tab there is label and inside viewDidLoad
there are 2 observers listening for the broadcasts. I also have 2 functions (triggered by the observers) that will change the label text based on the current network connection.
I'm using the simulator and when I toggle the wifi on/off from either the first or second tab the second tab's label text never changes.
Why is the text not changing and why are the observers not responding?
Reachability Class: FYI I got the Reachability Class from this youtube vid and I switched it from Swift 3 to 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)
}
}
Second Tab:
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)
}
}
Upvotes: 0
Views: 258
Reputation: 21381
You're posting the notification only once to the notification center, namely when your application starts:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Your method `checkReachability` will post notifications:
self.checkReachability()
return true
}
However your SecondTabController
is not yet created and thus it is not yet subscribed for receiving the notification that you send at app start. When notifications are posted, they are received immediately by any subscribers. Notifications "don't wait" until some subscriber is added at a later point in time.
What you probably need as a reachability manager that continues to live and posts notifications to the notification center whenever WiFi reachability changes.
You might want to use existing reachability managers, such as Alamofire's NetworkReachabilityManager as described in this question.
Upvotes: 1