Reachability return ReachableViaWiFi when connected to 3G - ios

In iPhone 5S WiFi detected as 3G and in my iPhone 4 it's normal.
Both in iOS 7.1.
In some devices it happens as well.
WiFi disabled and 3G connected, I double checked to see if internet connection is ok and indeed it's ok in device itself.
Any idea why?
Edit 1:
Code below:
- (void)registerReachabilityNotification
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(checkNetworkStatus:)
name:kReachabilityChangedNotification object:nil];
Reachability *reach = [Reachability reachabilityForInternetConnection];
[reach startNotifier];
NSNotification *note = [[NSNotification alloc] initWithName:kReachabilityChangedNotification object:reach userInfo:nil];
[self checkNetworkStatus:note];
}
- (void)checkNetworkStatus:(NSNotification*)notification
{
Reachability *reach = notification.object;
NSParameterAssert([reach isKindOfClass: [Reachability class]]);
NetworkStatus internetStatus = [reach currentReachabilityStatus];
switch (internetStatus)
{
case NotReachable:
{
NSLog(#"No internet connection.");
break;
}
case ReachableViaWiFi:
{
NSLog(#"The internet is working via WIFI.");
break;
}
case ReachableViaWWAN:
{
NSLog(#"The internet is working via WWAN.");
break;
}
}
}
Edit 1:
This code:
NetworkStatus nStats = [[Reachability reachabilityForLocalWiFi] currentReachabilityStatus];
if (nStats != ReachableViaWiFi) {
NSLog(#"nStats != ReachableViaWiFi");
}
if (nStats == ReachableViaWiFi) {
NSLog(#"WIFI");
}
else if (nStats == ReachableViaWWAN) {
NSLog(#"WWAN");
}
else if (nStats == NotReachable) {
NSLog(#"not reachable");
}
else {
NSLog(#"undetermined reachability.");
}
Give me this:
Reachability Flag Status: WR t------ localWiFiStatusForFlags
nStats != ReachableViaWiFi
not reachable

My method was completely wrong, below code for correct way:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSLog(#"CONNECTION: %#", NSStringFromNetworkStatus([MobileControlHandler checkConnection]));
return YES;
}
+ (NetworkStatus)checkConnection
{
NetworkStatus wifiStatus = [[Reachability reachabilityForLocalWiFi] currentReachabilityStatus];
NetworkStatus internetStatus = [[Reachability reachabilityForInternetConnection] currentReachabilityStatus];
if (wifiStatus == ReachableViaWiFi) {
return ReachableViaWiFi;
}
else if (wifiStatus != ReachableViaWiFi && internetStatus == ReachableViaWWAN) {
return ReachableViaWWAN;
}
else {
return NotReachable;
}
}
FOUNDATION_EXPORT NSString *NSStringFromNetworkStatus(NetworkStatus netStatus)
{
if (netStatus == ReachableViaWiFi) {
return #"ReachableViaWiFi";
} else if (netStatus == ReachableViaWWAN) {
return #"ReachableViaWWAN";
} else if (netStatus == NotReachable) {
return #"NotReachable";
} else {
return #"Undetermined reachbility flag";
}
}
Plot:
Reachability Flag Status: WR t------ localWiFiStatusForFlags
Reachability Flag Status: WR t----l- networkStatusForFlags
CONNECTION: ReachableViaWWAN

Just download new Reachability class from Apple
https://developer.apple.com/library/ios/samplecode/Reachability/Introduction/Intro.html
it will work on ios 8 too.
For more interacting things about iOS app development, Checkout
https://appengineer.in/

#import <Reachability.h>
It's a singleton so you can start using it right away.
Ex:
if ([Reachability currentReachabilityStatus] == NotReachable) {
...
}

Related

Check Internet connection in iOS

In some applications, like WhatsApp, when I send a message with no internet connection then close(terminate) the app, the message will be sent when internet comes back.
I'm trying to do the same thing and I wonder if there is any way to check for an internet connection when my app is not running and in the foreground in order to do a specific task.
Reachability
Example:
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];
if (remoteHostStatus == NotReachable) {
// not reachable
} else if (remoteHostStatus == ReachableViaWiFi) {
// reachable via Wifi
} else if (remoteHostStatus == ReachableViaWWAN) {
// reachable via WWAN
}
Edit
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Initialize Reachability
Reachability *reachability = [Reachability reachabilityWithHostname:#"www.google.com"];
// Start Monitoring
[reachability startNotifier];
//your code
return YES;
}
Every time the network interface changes, reachabilityDidChange: is invoked
- (void)reachabilityDidChange:(NSNotification *)notification{
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];
if (remoteHostStatus == NotReachable) {
// not reachable
} else if (remoteHostStatus == ReachableViaWiFi) {
// reachable via Wifi
} else if (remoteHostStatus == ReachableViaWWAN) {
// reachable via WWAN
}
}
This will solve your problem.

Check for UIAlertViews on the screen from App Delegate

I have an issue with UIAlertView.
In my AppDelegate I check the reachability of the application:
If it is not reachable I call the alert from Utils class.
- (void)reachabilityChanged:(NSNotification *)note
{
Reachability* currentReachabilityObject = [note object];
NSParameterAssert([currentReachabilityObject isKindOfClass:[Reachability class]]);
NetworkStatus status = [currentReachabilityObject currentReachabilityStatus];
if (status == NotReachable)
{
[Utils showAlert:#"NotReachableNetwork") title:#"Error")];
}
}
And if I turn on/turn off Wi-Fi two-three times I get three alerts.
But I want to show only one.
Please tell me how to check is there any alerts on the screen from AppDelegate.
Why don't you keep a reference to the alert?
That way you just have to check if the alert is nil, if it is nil you can create a new alert. In case it isn't nil, it means you already have one showing and there's no need to show another. Easy as pie.
Please try below code and I think it will work for you.
#pragma mark - Internet Reachability Handlers -
- (void) updateInterfaceWithReachability: (Reachability*) curReach
{
NetworkStatus netStatus = [curReach currentReachabilityStatus];
if (_changeReachability)
{
if(netStatus==NotReachable)
{
[Utils showAlert:#"NotReachableNetwork") title:#"Error")];
_isNetAvailable = NO;
_changeReachability = NO;
}
else
{
_isNetAvailable = YES;
_changeReachability = NO;
}
}
}
//Called by Reachability whenever status changes.
- (void) reachabilityChanged: (NSNotification* )note
{
_changeReachability = YES;
Reachability* curReach = [note object];
NSParameterAssert([curReach isKindOfClass: [Reachability class]]);
[self updateInterfaceWithReachability: curReach];
}
-(void)checkallTypesofInternet
{
// For 3G Connection
hostReach = [Reachability reachabilityWithHostName:#"www.apple.com"];
[hostReach startNotifier];
[self updateInterfaceWithReachability: hostReach];
// For Individual Net Connection
internetReach = [Reachability reachabilityForInternetConnection];
[internetReach startNotifier];
[self updateInterfaceWithReachability: internetReach];
// For WiFi
wifiReach = [Reachability reachabilityForLocalWiFi];
[wifiReach startNotifier];
[self updateInterfaceWithReachability: wifiReach];
}
Let me know if you are still facing any issue.

Reachability for Today Widget

I got a Notification Center Widget that contains some UISwitches that work only if connected to a Wi-Fi network.
I tried to do this with Reachability (that works in the normal app code), like this
#import "Reachability.h"
Reachability *reachability = [Reachability reachabilityForInternetConnection];
[reachability startNotifier];
NetworkStatus status = [reachability currentReachabilityStatus];
if(status == NotReachable) {
switch.enabled = NO;
} else if (status == ReachableViaWiFi) {
} else if (status == ReachableViaWWAN) {
switch.enabled = NO;
}
But I got these errors
Probably your not add Reachability.m as Target Membership of your widget

reachability alway return NotReach

i use reachability to detect network change. the first time its ok with wifi available. but then i turn off wifi then turn on, it alway return NotReach
Reachability *internetChecker;
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(myMethod:) name:kReachabilityChangedNotification object:nil];
internetChecker = [Reachability reachabilityWithHostName:#"www.24h.com.vn"];
[internetChecker startNotifier];
in mymethod:
NetworkStatus status = [internetChecker currentReachabilityStatus];
switch (status) {
case NotReachable:
{
NSLog(#"no wifi");
break;
}
default:
{
NSLog(#"wifi");
break;
}
}
Do you have separate Reachability properties for the Internet and the Host?
#property (nonatomic) Reachability *internetReachability;
#property (nonatomic) Reachability *hostReachability;
Then do this:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(myMethod:) name:kReachabilityChangedNotification object:nil];
self.internetReachability = [Reachability reachabilityForInternetConnection];
[self.internetReachability startNotifier];
[self updateInterfaceWithReachability:self.internetReachability];
self.hostReachability = [Reachability reachabilityWithHostName:#"www.24h.com.vn"];
[self.hostReachability startNotifier];
[self updateInterfaceWithReachability:self.hostReachability];
Then myMethod:
- (void)myMethod:(NSNotification *)note
{
Reachability* curReach = [note object];
NSParameterAssert([curReach isKindOfClass:[Reachability class]]);
[self updateInterfaceWithReachability:curReach];
}
And updateInterfaceWithReachability:
- (void)updateInterfaceWithReachability:(Reachability *)reachability {
NetworkStatus netStatus = [reachability currentReachabilityStatus];
if (reachability == self.internetReachability) {
switch (netStatus) {
case NotReachable:
NSLog(#"no internet");
break;
case ReachableViaWWAN:
case ReachableViaWiFi:
NSLog(#"with internet");
break;
}
}
if (reachability == self.hostReachability) {
switch (netStatus) {
case NotReachable:
NSLog(#"www.24h.com.vn unavailable");
break;
case ReachableViaWWAN:
case ReachableViaWiFi:
NSLog(#"www.24h.com.vn available");
break;
}
}
Try below solution
+ (BOOL)checkInternetConnection
{
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];
if (remoteHostStatus == NotReachable)
{
return FALSE;
}
else
{
return TRUE;
}
}
you have to modify this line
Reachability * internetChecker = [Reachability reachabilityForInternetConnection];
Hope it helps you..!
done! i dont know how but its seem notification center only detect when network change. When it notice the status is still NotReachable. So i check for the network after 2s delay. It work!

AFNetworking reachability is always unknown

I start monitoring like this in my AppDelegate:
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
On my root controller I then need to check if reachability is available and I perform this action to decide how to draw my UI:
AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
NSLog(#"%s - %#", __FUNCTION__, AFStringFromNetworkReachabilityStatus([manager networkReachabilityStatus]));
switch ([manager networkReachabilityStatus]){
case AFNetworkReachabilityStatusNotReachable:
[self showNetworkUnreachable];
break;
default:
[self hideNetworkUnreachable];
}
My issue is that here status is always unknown even if the device has connection.
Possibly AfNetworking is not the right tool to be used here. Any suggestion?
Not working in my case too. I used that instead:
- (BOOL)isInternetConnectionAvailable
{
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus internetStatus = [reachability currentReachabilityStatus];
if (internetStatus != NotReachable) {
return YES;
}
else
{
NSLog(#"NO INTERNET CONNECTION");
return NO;
}
}

Resources