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.
Related
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.
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
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!
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) {
...
}
how to check if iPad has ability to route out to the Internet? i want two different things one is to check if wifi is reachable for which i use following Rechability code, but now i want to Check if iPad has ability to route out to the Internet. How can i do that?
Reachability *networkReachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [networkReachability currentReachabilityStatus];
if (networkStatus == NotReachable) {
NSLog(#"There IS NO internet connection");
} else {
NSLog(#"There IS internet connection");
}
You can use that code to find out type of connection you have on the device.
wan = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [wan currentReachabilityStatus];
if (networkStatus == ReachableViaWWAN) {
}
wifi = [Reachability reachabilityForLocalWiFi];
NetworkStatus networkStatus = [wifi currentReachabilityStatus];
if (networkStatus == ReachableViaWiFi) {
}