My Reachability Notifier Is Only Able to Be Called Once

reachabilityWithHostname return YES only once

It is a well known bug of simulators in xCode 6.

Try the same on your device in debug mode. It should work correctly as in case of mine.

Also I recommend to use the original version of Reachability from Apple.

Reachability reachable and unreachableBlock are called multiple times?

This is just what i have in mind, this should be a comment but it's too long.

Please let me explain what is happening in your code...

I'm not really sure about this one but i think iOS 9.0.1 and iOS 9.1 is keeping the variable because of this [reach startNotifier];..

When you call the method -(void)checkServerConnection you are creating a new Reachability* reach and so on..

IF you will call the method again, it will create a new Reachability* reach and there is an existing one..

Possible solution is to create a global variable (Reachability* reach) that will be reused everytime the method is called.


Probably something like this:

Reachability* reachVar;
// i've changed your variable name hope that's okay, just for example.

-(void)checkServerConnection{

NSLog(@"Check Server Connection");

if (reachVar == nil)
{
reachVar = [Reachability reachabilityWithHostname:@"www.google.com"];
[reachVar startNotifier];
}
reachVar.reachableBlock = ^(Reachability*reach)
{
NSLog(@"Reachability reachable block");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"REACHABLE!");
});
};

reachVar.unreachableBlock = ^(Reachability*reach)
{
NSLog(@"UNREACHABLE!");
}
}

reachability bug in Xcode 8 e Swift 3

You need to fix your method selector. Try like this.

AppDelegate

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
reachability = Reachability.forInternetConnection()
reachability.startNotifier()
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {

}
}

View Controller

import UIKit
import SystemConfiguration

var reachability = Reachability()

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

NotificationCenter.default.addObserver(self, selector: #selector(reachabilityStatusChanged(_:)), name: .reachabilityChanged, object: nil)

}

func updateInterfaceWithCurrent(networkStatus: NetworkStatus) {
switch networkStatus {
case NotReachable:
view.backgroundColor = .red
print("No Internet")
case ReachableViaWiFi:
view.backgroundColor = .green
print("Reachable Internet")
case ReachableViaWWAN:
view.backgroundColor = .yellow
print("Reachable Cellular")
default:
return
}

}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//
updateInterfaceWithCurrent(networkStatus: reachability.currentReachabilityStatus())

}
func reachabilityStatusChanged(_ sender: NSNotification) {
guard let networkStatus = (sender.object as? Reachability)?.currentReachabilityStatus() else { return }
updateInterfaceWithCurrent(networkStatus: networkStatus)
}
override func viewWillDisappear(_ animated: Bool) {
NotificationCenter.default.removeObserver(self, name: .reachabilityChanged, object: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

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

}
}

What is the issue with ReachabilitySwift?

I needed a strong reference to Reachability instance! So I should have declared it at a class level.

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.

Checking network status in Swift, observer does not get called

The Reachability object returned is an autoreleased object , so it has deallocated hence notification is not triggering . You can fix by keeping a strong reference to it.

create a property to hold Reachability object

var reachability:Reachability?

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
// Override point for customization after application launch.

NSNotificationCenter.defaultCenter().addObserver(self, selector: "reachabilityChanged:", name:kReachabilityChangedNotification, object: nil)

reachability = Reachability(hostName: "www.apple.com");
reachability?.startNotifier();

return true
}

This will fix your problem.

The observer's name is changed from ReachabilityChangedNotification to kReachabilityChangedNotification. Notice the "k"

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


Related Topics



Leave a reply



Submit