Detecting Network Connectivity Changes using Reachability, NSNotification and Network Link Conditioner in Swift
You must create a Reachability object before you can receive notifications from it. Also, be sure to call the startNotifier()
method on the Reachability object you create. This would be an example of how to do so inside of your application delegate:
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")
}
}
}
I recommend you take a look at the documentation for NSNotificationCenter and NSNotification. That way you'll be more familiar with how to work with notifications next time something like this comes up.
Swift 3
NotificationCenter.default.addObserver(self, selector:Selector(("checkForReachability:")), name: NSNotification.Name.reachabilityChanged, object: nil)
let reachability: Reachability = Reachability.forInternetConnection()
reachability.startNotifier()
How to check network connectivity changes for internet connection at run time with Reachability?
Faced the same issue before, to resolve it you need to declare
let reachability = Reachability()!
outside viewWillAppear
function and your code will look like:
let reachability = Reachability()!
override func viewWillAppear(_ animated: Bool) {
NotificationCenter.default.addObserver(self, selector: #selector(reachabilityChanged(note:)), name: .reachabilityChanged, object: reachability)
do{
try reachability.startNotifier()
}catch{
print("could not start reachability notifier")
}
getUserDetail()
}
Using network link conditioner with Reachability
Reachability observes the state of the network connection, not the quality of it.
Since you are using network link conditioner you are only affecting the quality of the network like the speed or packet loss.
The only way reachability notifies you about a change is in fact when the network connection is lost or restored, as you have stated in your tests.
Is it safe to use 'com.apple.system.config.network_change' notification to detect network reachability changes?
That is considered to be a public API for now. For more details please see this thread:
https://forums.developer.apple.com/message/334035#334035
Detect the network at launch & resuming to avoid crash with ReachabilitySwift
Reachability is not guaranteed that will bring you the results at the exact moment, since it's totally asynchronous. Your app shouldn't wait for Reachability results to perform connection, there is something wrong because it shouldn't crash.
What you need to do it's add an NSNotification
on your AppDelegate
, to get notified when your Reachability changes.
From the documentation
You can add this on your didFinishLaunchingWithOptions
let reachability = Reachability.reachabilityForInternetConnection()
NSNotificationCenter.defaultCenter().addObserver(self,
selector: "reachabilityChanged:",
name: ReachabilityChangedNotification,
object: reachability)
reachability.startNotifier()
And this to show a banner, or anything you'd like to do:
func reachabilityChanged(note: NSNotification) {
let reachability = note.object as! Reachability
if reachability.isReachable() {
if reachability.isReachableViaWiFi() {
println("Reachable via WiFi")
} else {
println("Reachable via Cellular")
}
} else {
println("Not reachable")
}
}
Does iOS reachability detect network changes when app is brought to foreground
I have an app which has to be connected to WiFi and detect when the access point changes or it disconnects on all view controllers which depend on it. I use the Reachability notification mechanism.
For my app, Reachability detects the WiFi changes when I bring the app back into the foreground. So it does do what you want.
I do have to say though that I have not found Reachability to be 100% reliable. The majority of the time it works as you expect, but its not perfect.
As a backup, I check the current network anyway in viewWillAppear
on most view controllers. This does not help when an app comes back to the foreground as viewWillAppear
is not called as far as I know. You can detect the change in the app delegate though.
iPhone - catching system events if Internet is available or not
Ok, I found a simple answer:
1) create file .swift and paste it there:
import Foundation
import SystemConfiguration
var internetAvailable: Bool = true
let ReachabilityStatusChangedNotification = "ReachabilityStatusChangedNotification"
func isInternetAvailable() {
let hostToConnect = "google.com"
var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
let isAvailable = SCNetworkReachabilityCreateWithName(nil, hostToConnect)!
SCNetworkReachabilitySetCallback(isAvailable, { (_, flags, _) in
var reachabilityFlags = SCNetworkReachabilityFlags()
reachabilityFlags = flags
if (reachabilityFlags.contains(.Reachable)) && !(reachabilityFlags.contains(.ConnectionRequired)) {
if reachabilityFlags.contains(.IsWWAN) {
internetAvailable = true
print("Online Cellular")
} else {
internetAvailable = true
print("Online WiFi")
}
} else {
internetAvailable = false
print("Offline")
}
NSNotificationCenter.defaultCenter().postNotificationName(ReachabilityStatusChangedNotification, object: nil)
}, &context)
SCNetworkReachabilityScheduleWithRunLoop(isAvailable, CFRunLoopGetMain(), kCFRunLoopCommonModes)
}
2) In AppDelegate.swift find function application and replace it or add it with this:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("networkStatusChanged:"), name: ReachabilityStatusChangedNotification, object: nil)
isInternetAvailable()
return true
}
3) In AppDelegate.swift also add this function:
func networkStatusChanged(notification: NSNotification) {
}
4) Done! Function networkStatusChanged will be executed any time somethings changes in network connection! And if you need something to do which requires Internet do it like this:
if internetAvailable {
//Do what you need, for example send JSON request on server
}
Monitor the status of the Internet Swift
Swift 2.0 - Check Network Using Reachability, NSNotification
AppDelegate.swift
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
NSNotificationCenter.defaultCenter().addObserver(self, selector:"checkNetworkStatus", name: ReachabilityChangedNotification, object: nil);
do{self.reachability = try Reachability.reachabilityForInternetConnection()}catch{}
do{try self.reachability.startNotifier()}catch{}
self.checkNetworkStatus()
return true
}
Declare networkStatus variable
var networkStatus : Reachability.NetworkStatus!
checkNetworkStatus() Function
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
}
Related Topics
iOS 7 Status Bar with Phonegap
Auto Layout Constraints Issue on iOS7 in Uitableviewcell
Changing Root View Controller of a iOS Window
How to Create Percentage of Total Width Using Autolayout
How to Get List of Available Bluetooth Devices
Post Request with a Simple String in Body with Alamofire
Disable Gesture to Pull Down Form/Page Sheet Modal Presentation
Swift Days Between Two Nsdates
Xcode iOS 8 Keyboard Types Not Supported
Unique Values of Array in Swift
How to Increase the Height of Navigation Bar in Xcode
iOS (Iphone, iPad, Ipodtouch) View Real-Time Console Log Terminal
Save Custom Objects into Nsuserdefaults
Xcode 7 Error: "Missing iOS Distribution Signing Identity For ..."