iPhone app, alert users when they aren't connected to the internet? - iphone

What's an easy way to code an alert that warns users when they aren't connected to the Internet? I'm using Xcode, right now when there is no connection it is just a white screen in uiwebview.

Here you can check if wifi has connection, 3g,or none atall:
if ([[Reachability reachabilityWithHostName:#"google.com"] currentReachabilityStatus] == ReachableViaWiFi) {
// Do something that requires wifi
} else if ([[Reachability reachabilityWithHostName:#"google.com"] currentReachabilityStatus] == ReachableViaWWAN) {
// Do something that doesnt require wifi
} else if ([[Reachability reachabilityWithHostName:#"google.com"] currentReachabilityStatus] == NotReachable) {
// Show alert because no wifi or 3g is available..
}
Apple provides all the necessary Reachability api/source here: Reachability Reference
I have made these custom convenience functions for myself in all my projects:
+ (BOOL)getConnectivity {
return [[Reachability reachabilityWithHostName:#"google.com"] currentReachabilityStatus] != NotReachable;
}
+ (BOOL)getConnectivityViaWiFiNetwork {
return [[Reachability reachabilityWithHostName:#"google.com"] currentReachabilityStatus] == ReachableViaWiFi;
}
+ (BOOL)getConnectivityViaCarrierDataNetwork {
return [[Reachability reachabilityWithHostName:#"google.com"] currentReachabilityStatus] == ReachableViaWWAN;
}
And used like so:
if ([ServerSupport getConnectivity]) {
// do something that requires internet...
else {
// display an alert
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:#"Network Unavailable"
message:#"App content may be limited without a network connection!"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil] autorelease];
[alert show];
}

If your application requires persistent internet connection, you can include the key UIRequiresPersistentWiFi in your plist file. Using this, iOS will automatically display an alert to the user in the airport mode.
Also, iOS will ensure that the wifi radio isn't switched off/hibernated while your app is in the foreground.

Note that internet connectivity is very dynamic on a mobile device (multiple radios, multiple access points, multiple cell towers, travel, competing radio interference, "your holding it wrong", etc.), and thus Reachability is not a perfect solution, as the net connectivity can very often can change just before, during or after Reachability performs its checks. Reachability can outright lie (yes we're connected to an access point, true even if broadband is dead on the other side of the access point). It's also quite common for Reachability to report no connectivity, just as its own request turns the radios on to get a great connection a couple seconds later.
Best thing to do is to just try to access data from the network, spin an activity indicator while waiting, and offer the user some API element to give up if they end up waiting too long, in their opinion, not some developer's opinion... They know better than you do how long it takes for a (re)connection to come up in their area, and how long they are willing to wait.

Related

(iOS) How do I check an iPhone's paired Bluetooth devices?

I want to use CoreBluetooth (as my app must be eligible for the App Store) to check all of the currently paired and connected Bluetooth devices. This should not require any Bluetooth scanning, right? I just want to see what the system is paired with. If I can't do that, a scan is the second option.
What I'm trying is not working. It says that Bluetooth is not powered on and crashes, but the CBCentralManager's state is on! Any ideas on how to fix this, or am I totally off track?
All of this in ViewController for now:
- (void)viewDidLoad{
[super viewDidLoad];
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue()];
[self.centralManager retrieveConnectedPeripherals]; //makes the system call didRetrieveConnectedPeripherals
}
- (void)centralManager:(CBCentralManager *)central didRetrieveConnectedPeripherals:(NSArray *)peripherals{
NSLog(#"didRetrieveConnectedPeripherals called");
for (CBPeripheral *a in peripherals){
NSLog(a.name); //just log the name for now to see if it recognized it
} //but it never ends up logging anything, and I have a BT keyboard paired/connected with the iPhone 5
} //and I get an error at some point, <CBConcreteCentralManager: 0x71ab020> is not powered on
- (void)centralManagerDidUpdateState:(CBCentralManager *)manager{
if ([manager state] == CBCentralManagerStatePoweredOff) NSLog(#"CBCentralManagerStatePoweredOff");
if ([manager state] == CBCentralManagerStatePoweredOn) NSLog(#"CBCentralManagerStatePoweredOn"); //this is what gets logged when I run it on an iPhone 5
if ([manager state] == CBCentralManagerStateResetting) NSLog(#"CBCentralManagerStateResetting");
if ([manager state] == CBCentralManagerStateUnauthorized) NSLog(#"CBCentralManagerStateUnauthorized");
if ([manager state] == CBCentralManagerStateUnknown) NSLog(#"CBCentralManagerStateUnknown");
if ([manager state] == CBCentralManagerStateUnsupported) NSLog(#"CBCentralManagerStateUnsupported");
}
I've been working on this also, and hopefully some of what I've learned will help.
Couple of things:
1) You're likely getting the "Bluetooth not powered on" error because you're calling [self.central retrieveConnectedPeripherals] immediately after initializing the CBCentralManager. You need to give the CBCentralManager enough time to connect to the bluetooth hardware.
Try this instead,
- (void)viewDidLoad{
[super viewDidLoad];
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)manager {
switch (manager.state) {
case CBCentralManagerStatePoweredOn:
NSLog(#"CBCentral Manager powered on");
[self.centralManager retrieveConnectedPeripherals];
break;
case CBCentralManagerStatePoweredOff:
...etc.
}
Also, be aware that CBCentralManager works for iOS devices with Bluetooth 4.0. Currently, Bluetooth 4 is installed on iPhone 4S/5, iPod 4, and iPad 3/4/mini. So, be aware that your App will not work on iPad 1/2, iPhone 2/3, and iPod 2/3.
Still figuring this out, but it is also possible that you may not see your keyboard because it is not a Bluetooth 4 device. Let me know what you find out.

How to check if sim card is installed or not

I am developing an app which has call and message functionality , i want to check if sim card is installed or not coz i am facing problem with messaging as it gives alerts for " Message Sent Successful"
Please help me out.
There might be different ways but one way is by using MFMessageComposeViewController class to see if you can send the text message. If you can then sim is available otherwise not.
if ([MFMessageComposeViewController canSendText]) {
NSLog(#"SIM Available");
} else {
NSLog(#"no SIM card installed");
}
In cases you have iMessage available then this might return you true, you could also check if you can make a call, you might want to use CTTelephonyNetworkInfo for that purpose.
You can also check using like this.... First read this doc
http://developer.apple.com/library/ios/#DOCUMENTATION/NetworkingInternet/Reference/CTCarrier/Reference/Reference.html#//apple_ref/doc/uid/TP40009596-CH1-SW1
NSString *_code = [[[CTCarrier alloc] init] mobileCountryCode];
The value for this property is nil if any of the following apply:
The device is in Airplane mode.
There is no SIM card in the device.
The device is outside of cellular service range.
First you have to be sure that device is iPhone (not iPod or iPad) then check if device can make call or not, just like this............
if([[UIDevice currentDevice].model isEqualToString:#"iPhone"])
{
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:#"tel:123456"]])
{
NSLog(#"Device can make call or send message");
}
else
{
NSLog(#"Device can not make call or send message");
}
}
else
{
NSLog(#"Device can not make call or send message");
}
Hope it will help you........

iOS Native Facebook Share no internet callback

I'm trying to implement the native facebook share for iOS 6 and need check if a share did succeed or not. This is the code I have used:
BOOL displayedNativeDialog =
[FBNativeDialogs
presentShareDialogModallyFrom:delegate
initialText:#"test"
image:nil
url:nil
handler:^(FBNativeDialogResult result, NSError *error) {
if (error) {
/* handle failure */
NSLog(#"error:%#, %#", error, [error localizedDescription]);
} else {
if (result == FBNativeDialogResultSucceeded) {
/* handle success */
NSLog(#"handle success");
} else {
/* handle user cancel */
NSLog(#"user cancel");
}
}
}];
if (!displayedNativeDialog) {
/* handle fallback to native dialog */
}
My problem is when I try this with no internet connection available I still get the FBNativeDialogResultSucceeded
It looks like you should get an error when no internet connection is available but it seems that it doesn't work like that.
If there are some solution where I don't need to use the reachability SDK that would be great.
You'll likely have to use the reachability SDK at this point. The Facebook SDK builds on top of the SLComposeViewController for the native functionality. That view controller returns two possible choices:
SLComposeViewControllerResultCancelled
SLComposeViewControllerResultDone
SLComposeViewControllerResultDone: The view controller is dismissed and the message is being sent in the background. This occurs when the user selects Done.
So since Facebook mirrors this the success case means the user clicked done and the message has been sent in the background.
However if you run this and there is no internet connection, the user should still see a pop-up indicating that the post could not be sent due to a connection failure.

Reachability status message appears only once

I am popping a message alerting the user that he/she has lost WIFI/intenet connection. For that, i followed the Reachability example given by apple.
I added the 2 reachability classes, Rechability.h and .m, and i added the codes given in its app delegate to mine as well (an exact replica). This works perfectly.
My problem is that, this message appears only once, i want it to be displayed when it goes to each and every view.
All codes that i am using can be found here. Help
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!!!
I have an application where I have tabs. The root controller registers for reachability messages. An UIAlertView is used to display a warning. This is shown in all parts of the application.
You could call [Reachability reachabilityForInternetConnection] in each view's viewDidAppear method...
But like others have mentioned, it could be kind of annoying to see the same message over and over.

Iphone Internet Connection Verification - Reachability

I read there were many problem with the Reachability sample app that apple provided, but now with their new 2.2 implementation it's suppose to work fine.
So I just want an advice before I integrate it into my app instead of my current implementation.
Basically I'm asking 2 question:
Will this code work ? I need to know if internet is available through 3G or WIFI. (If there is a WIFI with no internet, of course I need it to return false)
2.I'm planning to deploy my app on ios 3.0 and above, do I need to perform any adjustments so it won't crash on ios below 4.0 (cause Reachability 2.2 said to be working on ios 4) ?
Thanks alot!!
+ (BOOL) isInternetReachable
{
NetworkStatus status = [[Util sharedReachability] currentReachabilityStatus];
return (status != NotReachable);
}
+ (Reachability*) sharedReachability
{
if (reachability == nil)
{
reachability = [[Reachability reachabilityForInternetConnection] retain];
[reachability startNotifier];
}
return reachability;
}
Yes this code is gonna work. It is right.