Reachability change notification should be called only once
You can add a flags to prevent the code from being executed unless the state has changed like this:
var connectionState = "Connected"
let connectedState = "Connected"
let notConnectedState = "notConnected"
func checkForReachability(notification:NSNotification)
{
let networkReachability = notification.object as! Reachability;
var remoteHostStatus = networkReachability.currentReachabilityStatus()
if remoteHostStatus.value == NotReachable.value && connectedState == connectedState {
connectionState = notConnectedState
println("State Changed Not Connected")
} else if remoteHostStatus.value == ReachableViaWiFi.value && connectedState == notConnectedState {
connectionState = connectedState
println("State Changed Connected")
}
}
kReachabilityChangedNotification is called multiple times
Add the reachability notification in the appdelegate didFinishLaunchingWithOptions only and set the value of reachability in Bool variable isInternetAvailable in appDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(checkNetworkStatus:)
name:kReachabilityChangedNotification object:nil];
}
- (void)checkNetworkStatus:(NSNotification *)notice {
// called after network status changes
NetworkStatus internetStatus = [self.internetReachable currentReachabilityStatus];
switch (internetStatus)
{
case NotReachable:
{
//#######NSLog(@"The internet is down.");
self.isInternetAvailable = FALSE;
break;
}
case ReachableViaWiFi:
{
//#######NSLog(@"The internet is working via WIFI");
self.isInternetAvailable = TRUE;
break;
}
case ReachableViaWWAN:
{
//#######NSLog(@"The internet is working via WWAN!");
self.isInternetAvailable = TRUE;
break;
}
default:
{
//#######NSLog(@"The internet is working via mobile SIM!");
self.isInternetAvailable = FALSE;
break;
}
}
}
Reachability status message appears only once
Mmm... Not sure to understand what you expect Rechability does.
This class is designed to get any change in your rechability status. When a change is detected Reachability send a notification, but if nothing changes you won't get any notification.
EDIT: to get your reachability status and to use it later you can add a BOOL (internetIsDown) to the method where you read notification from Reachability.
- (void)checkNetworkStatus:(NSNotification *)notice {
NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
switch (internetStatus) {
case NotReachable: {
internetIsDown = YES;
break;
} case ReachableViaWiFi: {
internetIsDown = NO;
break;
} case ReachableViaWWAN: {
internetIsDown = NO;
break;
}
}
}
Now you can check for this BOOL value whenever needed and display an alert to the user.
N.B. internetIsDown should be a singleton if you want to access its value from any viewController!!!
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()
Check internet connection in iOS app only once
I solved this issue by creating an own HomeViewController.h/HomeViewController.m file for the ViewController where my homepage is integrated. There I added the alert-if-no-internet-connection code.
iOS: Reachability - startNotifier fails after returning to app
You should only need to call [self.hostReachability startNotifier]
once on init/load. Here's a rundown of your basic needs, using notifications rather than the block method on the linked thread:
Add the tonymillion/Reachability library to your project.
Create property for your Reachability object to make sure it's retained, eg.
@interface ViewController () {
NSString *_HOST;
}
@property Reachability *hostReachability;
@endRegister for change notifications, and start the notifier, eg.
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reachabilityChanged:)
name:kReachabilityChangedNotification
object:nil];
_HOST = @"www.google.com";
self.hostReachability = [Reachability reachabilityWithHostname:_HOST];
[self.hostReachability startNotifier];
}
- (void)viewDidUnload
{
[super viewDidUnload];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}Finally, create a
reachabilityChanged:
method to handle your response to Reachability changes, eg.- (void)reachabilityChanged:(NSNotification*)notification
{
Reachability *notifier = [notification object];
NSLog(@"%@", [notifier currentReachabilityString]);
}
Note: If you press the Home button and unload the app, changes in Reachability should fire a notification immediately upon returning to the app.
Reachability change notification works on iOS5 but not iOS4
Edit the code in reachability that posts the notification to post it on the main thread, and see if that changes the behavior you're seeing.
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:kReachabilityChangedNotification object:noteObject];
});
(assume you are listening for them on the main thread)
Related Topics
"This Class Is Not Key Value Coding-Compliant" Using Coreimage
Simulating Pressing The Home Button in Xcode 7 UI Automation
Performseguewithidentifier Not Working If Called from Viewdidload
Issue with Returning a Directory Enumerator from Nsfilemanager Using Enumeratoraturl in Swift
Set an Horizontal Scroll to My Barchart in Swift
How to Fix Cannot Find 'Firebaseapp' in Scope
Test Enum for Equality in for ... Where Clause
Getting Common Data from Two Different Types of Array
Can You Strict Generic Types or Give One Parameter More Than One Type
Is There a Way in Swiftui to Detect If a User Has Larger Text Size Enabled
What Was The Reason for Swift Assignment Evaluation to Void
Flipping The Positions of Items in a UIstackview
How to Find Realm File Location of a MAC App
Realm: Predicate Returning Lazyfiltercollection - How to Convert to Results<T>
Accessibility Custom Actions Aren't Announced in Swift