How to get battery status? - iphone

How do I get the battery status on an iPhone?

UIDevice *myDevice = [UIDevice currentDevice];
[myDevice setBatteryMonitoringEnabled:YES];
float batLeft = [myDevice batteryLevel];
int i=[myDevice batteryState];
int batinfo=(batLeft*100);
NSLog(#"Battry Level is :%d and Battery Status is :%d",batinfo,i);
switch (i)
{
case UIDeviceBatteryStateUnplugged:
{
[BCStatus setText:NSLocalizedString(#"UnpluggedKey", #"")];
break;
}
case UIDeviceBatteryStateCharging:
{
[BCStatus setText:NSLocalizedString(#"ChargingKey", #"")];
break;
}
case UIDeviceBatteryStateFull:
{
[BCStatus setText:NSLocalizedString(#"FullKey", #"")];
break;
}
default:
{
[BCStatus setText:NSLocalizedString(#"UnknownKey", #"")];
break;
}
}
BCStatus is uilabel.

Iphone SDK 3.0 beta supports this.

The answers above are very good, but they are all in Obj-C, I have used these with other examples to do the same task on MonoTouch, so I am putting my code here in case anybody needs it:
try
{
UIDevice.CurrentDevice.BatteryMonitoringEnabled = true;
_Battery.Level = (int)(UIDevice.CurrentDevice.BatteryLevel * IOSBatteryLevelScalingFactor);
_Battery.State = UIDevice.CurrentDevice.BatteryState;
}
catch (Exception e)
{
ExceptionHandler.HandleException(e, "BatteryState.Update");
throw new BatteryUpdateException();
}
finally
{
UIDevice.CurrentDevice.BatteryMonitoringEnabled = false;
}
I also have a full post on my blog to give all the details in here

Here's what I used for my string as a quick utility method, note that you have to enable battery monitoring to get a value, and then if you don't want to get the notifications (obviously some efficiency to be gained there, since they give you the ability to turn it off) then you should turn it off again after (like I do in this function):
NSString *statusString(void)
{
UIDevice *device = [UIDevice currentDevice];
NSString *batteryStateString = nil;
switch(device.batteryState)
{
case UIDeviceBatteryStateUnplugged: batteryStateString = #"Unplugged"; break;
case UIDeviceBatteryStateCharging: batteryStateString = #"Charging"; break;
case UIDeviceBatteryStateFull: batteryStateString = #"Full"; break;
default: batteryStateString = #"Unknown"; break;
}
[device setBatteryMonitoringEnabled:YES];
NSString *statusString = [NSString stringWithFormat:#"Battery Level - %d%%, Battery State - %#",
(int)round(device.batteryLevel * 100), batteryStateString];
[device setBatteryMonitoringEnabled:NO];
return statusString;
}

Now that the 3.1 SDK is released look for the Getting the Device Battery State section in UIDevice's documentation. It is abunch of battery* properties.

Related

Get last 10 photos from iPhone using AssetLibrary, Corelocation deprecation issue on ios 6.1.3

App tries to access photos from phone library. Works well on ipod (5.1.something) iPhone5 (6.1.4), all simulators, but crashes on iPhone 4S(6.1.3).
All checks (location services, photo library access) are there w.r.t ios version.
Console LOG:
: libMobileGestalt copySystemVersionDictionaryValue: Could not lookup ReleaseType from system version dictionary
Jul 31 12:03:00 ABC's-iPhone awdd[296] : CoreLocation: CLClient is deprecated. Will be obsolete soon.
BTW below code fetches last 10 photos from the photo library. If exist. Before calling this method check for location is made using [CLLocationManager authorizationStatus].
- (void) getRecentPhotos
{
if(! oneTimeFetch) // to prevent location delegate from calling this method.
{
oneTimeFetch = TRUE;
NSLog(#"getRecentPhotos");
recenPicScroll.userInteractionEnabled = FALSE;
[self.recentPicsArr removeAllObjects];
if ([[[UIDevice currentDevice] systemVersion] doubleValue] >= 6.0)
{
NSLog(#"IOS version 6.0 and above, need to check for photo access");
if ([ALAssetsLibrary authorizationStatus] == ALAuthorizationStatusAuthorized)
{
NSLog(#"Photo ACCESS ALLOWED");
// just execute the code after loop ends. Else return :).
}
else
{
recentPicView.hidden = TRUE;
NSLog(#"PLEASE ALLLOW PHOTO ACCESS");
return;
}
}
recentPicView.hidden = FALSE;
loadingAI.hidden = FALSE;
ALAssetsLibrary *al = [[ALAssetsLibrary alloc] init];
[al enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos
usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop)
{
if([group numberOfAssets] == 0)
{
recentPicView.hidden = TRUE;
return;
}
int startIdx = [group numberOfAssets]- 10; // Start from 10th last
if (asset)
{
//NSLog(#"asset Index: %d",index);
ALAssetRepresentation *rep = [asset defaultRepresentation];
CGImageRef imgRef = [rep fullResolutionImage];
if(group.numberOfAssets > 10) // upto 10
{
if(index >= startIdx)
{
[self.recentPicsArr addObject:[UIImage imageWithCGImage:imgRef]];
if(index == [group numberOfAssets] - 1)
{
[self addPicsToScrollV];
}
}
}
else if (group.numberOfAssets <= 10) // get less than 10 photos
{
[self.recentPicsArr addObject:[UIImage imageWithCGImage:imgRef]];
if(index + 1 == group.numberOfAssets)
{
[self addPicsToScrollV];
}
}
else
{
recentPicView.hidden = TRUE;
}
}
}];
}
failureBlock:^(NSError *error)
{
NSLog(#"You must allow the app to fetch your photos");
}
] ;
}
}
Since AlAsset library requires location services to be enabled, I couldn't ignore the location check.
And Since iOS 6.0 user can even prevent the app from accessing the photo library so AssetLibrary authorisation was also required.
Solution for me was to use [self.locMgr stopUpdatingLocation] in the below delegate:
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
if(status == 1 || status == 2)
{
NO_LOCATION_ALERT // User denied location. Don't start the activity for fetching photos
}
else if (status == kCLAuthorizationStatusAuthorized)
{
//Start fetching fotos
}
else
{
// This is for the first time, when user hasn't made any choice. So leave it blank.
}
[self.locMgr stopUpdatingLocation]; // SOLUTION
}

Pair with a bluetooth peripheral using ios 5

I am developing a proximity sensing application using bluetooth technology 4.0. I am able to discover the devices. But I am not able to pair with them. Nor can i call [peripheral readRssi] method. The way I want to achieve this is that if the central scans for say 10 devices and after finding those many, it should stop the scan and then pair the devices and then constantly read the RSSI values.
My piece of code.
- (void) centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
BOOL (^test)(id obj, NSUInteger idx, BOOL *stop);
test = ^ (id obj, NSUInteger idx, BOOL *stop) {
if([[[obj peripheral] name] compare:peripheral.name] == NSOrderedSame)
return YES;
return NO;
};
PeripheralCell* cell;
NSUInteger t=[peripherals indexOfObjectPassingTest:test];
if(t!= NSNotFound)
{
cell=[peripherals objectAtIndex:t];
cell.peripheral=peripheral;
cell.rssi=RSSI;
//NSLog(#"%#",RSSI);
[scanResultTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:t inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
}
else{
cell=[[PeripheralCell alloc] init];
[peripherals addObject: cell];
[myPeripheral addObject: peripheral];
cell.peripheral=peripheral;
cell.rssi=RSSI;
NSLog(#"UUID===%#",[peripheral UUID]);
[scanResultTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:[peripherals count]-1 inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
if([myPeripheral count]==3)
{
[manager stopScan];
for(CBPeripheral *p in myPeripheral)
{
[manager connectPeripheral:p options:nil]; //this calls didConnectPeripheral but gets disconnected after some time
[p readRssi]; //this does not work even after connecting
}
}
}
}
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
//self.cBReady = false;
switch (central.state) {
case CBCentralManagerStatePoweredOff:
NSLog(#"CoreBluetooth BLE hardware is powered off");
break;
case CBCentralManagerStatePoweredOn:
NSLog(#"CoreBluetooth BLE hardware is powered on and ready");
//self.cBReady = true;
break;
case CBCentralManagerStateResetting:
NSLog(#"CoreBluetooth BLE hardware is resetting");
break;
case CBCentralManagerStateUnauthorized:
NSLog(#"CoreBluetooth BLE state is unauthorized");
break;
case CBCentralManagerStateUnknown:
NSLog(#"CoreBluetooth BLE state is unknown");
break;
case CBCentralManagerStateUnsupported:
NSLog(#"CoreBluetooth BLE hardware is unsupported on this platform");
break;
default:
break;
}
}
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
NSLog(#"connected peripheral");
}
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;
{
NSLog(#"peripheral disconnected");
}
- (void)peripheralDidUpdateRSSI:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog(#"updated rssi");
}
how can i pair the devices...
After much searching and trail and error I found out that my code is correct. I just had to remove the devices from the ipad's Setting.
Goto Settings > General > Bluetooth > Devices.
Select the device by clicking the accessory indicator. In the next screen just click on "Forget this Device".
Running the application again solved my problem.

iTunes isRunning with NSTask

So I am trying to make an if based on if iTunes is running or not. I need this because my application gets the track name. This track name has already been accomplished and works but I do not want iTunes always running...
So I decided to try a NSTask with setLaunchPath instance to check if iTunes.app isRunning. The code below is self explanatory but for some reason it keeps hitting my else if when iTunes is open. I call this method in my awakeFromnib by an nstimer every 5 seconds.
-(IBAction)ifRunning:(id)pID; {
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:#"/Applications/iTunes.app/Contents/MacOS/iTunes"];
if ([task isRunning]==TRUE) {
NSLog(#"iTunes is Running, hit if");
NSString *track = ([self getCurrentTrack]);
//getCurrentTrack another one of my methods
}
else if ([task isRunning] == FALSE) {
NSLog(#"iTunes is not running, hit else if");\
[trackName setTitle:(#"iTunes is Not Playing")];
}
else {
NSLog(#"Hit else");
}
}
I figured it out using the code below. Hope this post is useful!
-(IBAction)ifRunning:(id)pID; {
NSLog(#"Process check ");
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
NSArray *runningAppDictionaries = [ws launchedApplications];
NSDictionary *aDictionary;
for (aDictionary in runningAppDictionaries)
{
// NSLog(#"Open App: %#", [aDictionary valueForKey:#"NSApplicationName"]);
if ([[aDictionary valueForKey:#"NSApplicationName"] isEqualToString:#"iTunes"])
{
NSLog(#"iTunes is Is Running");
[self getCurrentTrack:nil];
break;
}
else {
NSLog(#"iTunes is not running.");
}
}
}

How can I determine whether my iOS device has a torch light?

In my application I have the option for a torch light. Howevver, only iPhone 4 and iPhone 4S have torch lights. Other devices do not have the torch light. How can I find the current device model? Please help me. Thanks in advance.
You should not use the device model as an indicator of whether a feature is present. Instead, use the API that tells you exactly if the feature is present.
In your case, you want to use AVCaptureDevice's -hasTorch property:
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
NSMutableArray *torchDevices = [[NSMutableArray alloc] init];
BOOL hasTorch = NO;
for (AVCaptureDevice *device in devices) {
if ([device hasTorch]) {
[torchDevices addObject:device];
}
}
hasTorch = ([torchDevices count] > 0);
More information is available in the AV Foundation Programming Guide and the AVCaptureDevice Class Reference
You can have less code and use less memory than the code above:
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
BOOL hasTorch = NO;
for (AVCaptureDevice *device in devices) {
if ([device hasTorch]) {
hasTorch = YES;
break;
}
}
hasTorch will now contains the correct value
Swift 4
var deviceHasTorch: Bool {
return AVCaptureDevice.default(for: AVMediaType.video)?.hasTorch == true
}
This code will give your device the ability to turn on the flashlight. But it will also detect if the flashlight is on or off and do the opposite.
- (void)torchOnOff: (BOOL) onOff {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch]) {
[device lockForConfiguration:nil];
if (device.torchMode == AVCaptureTorchModeOff) {
device.torchMode = AVCaptureTorchModeOn;
NSLog(#"Torch mode is on.");
} else {
device.torchMode = AVCaptureTorchModeOff;
NSLog(#"Torch mode is off.");
}
[device unlockForConfiguration];
}
}
Swift 4
if let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) {
if (device.hasTorch) {
// Device has torch
} else {
// Device does not have torch
}
} else {
// Device does not support video type (and so, no torch)
}
devicesWithMediaType: is now deprecated.
Swift 4:
let discoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: .video, position: .back)
for device in discoverySession.devices {
if device.hasTorch {
return true
}
}
return false

Check if iPhone Internet Tethering is Active [duplicate]

I would like to check to see if I have an Internet connection on iOS using the Cocoa Touch libraries or on macOS using the Cocoa libraries.
I came up with a way to do this using an NSURL. The way I did it seems a bit unreliable (because even Google could one day be down and relying on a third party seems bad), and while I could check to see for a response from some other websites if Google didn't respond, it does seem wasteful and an unnecessary overhead on my application.
- (BOOL)connectedToInternet {
NSString *URLString = [NSString stringWithContentsOfURL:[NSURL URLWithString:#"http://www.google.com"]];
return ( URLString != NULL ) ? YES : NO;
}
Is what I have done bad, (not to mention stringWithContentsOfURL is deprecated in iOS 3.0 and macOS 10.4) and if so, what is a better way to accomplish this?
Important: This check should always be performed asynchronously. The majority of answers below are synchronous so be careful otherwise you'll freeze up your app.
Swift
Install via CocoaPods or Carthage: https://github.com/ashleymills/Reachability.swift
Test reachability via closures
let reachability = Reachability()!
reachability.whenReachable = { reachability in
if reachability.connection == .wifi {
print("Reachable via WiFi")
} else {
print("Reachable via Cellular")
}
}
reachability.whenUnreachable = { _ in
print("Not reachable")
}
do {
try reachability.startNotifier()
} catch {
print("Unable to start notifier")
}
Objective-C
Add SystemConfiguration framework to the project but don't worry about including it anywhere
Add Tony Million's version of Reachability.h and Reachability.m to the project (found here: https://github.com/tonymillion/Reachability)
Update the interface section
#import "Reachability.h"
// Add this to the interface in the .m file of your view controller
#interface MyViewController ()
{
Reachability *internetReachableFoo;
}
#end
Then implement this method in the .m file of your view controller which you can call
// Checks if we have an internet connection or not
- (void)testInternetConnection
{
internetReachableFoo = [Reachability reachabilityWithHostname:#"www.google.com"];
// Internet is reachable
internetReachableFoo.reachableBlock = ^(Reachability*reach)
{
// Update the UI on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"Yayyy, we have the interwebs!");
});
};
// Internet is not reachable
internetReachableFoo.unreachableBlock = ^(Reachability*reach)
{
// Update the UI on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"Someone broke the internet :(");
});
};
[internetReachableFoo startNotifier];
}
Important Note: The Reachability class is one of the most used classes in projects so you might run into naming conflicts with other projects. If this happens, you'll have to rename one of the pairs of Reachability.h and Reachability.m files to something else to resolve the issue.
Note: The domain you use doesn't matter. It's just testing for a gateway to any domain.
I like to keep things simple. The way I do this is:
//Class.h
#import "Reachability.h"
#import <SystemConfiguration/SystemConfiguration.h>
- (BOOL)connected;
//Class.m
- (BOOL)connected
{
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [reachability currentReachabilityStatus];
return networkStatus != NotReachable;
}
Then, I use this whenever I want to see if I have a connection:
if (![self connected]) {
// Not connected
} else {
// Connected. Do some Internet stuff
}
This method doesn't wait for changed network statuses in order to do stuff. It just tests the status when you ask it to.
Using Apple's Reachability code, I created a function that'll check this correctly without you having to include any classes.
Include the SystemConfiguration.framework in your project.
Make some imports:
#import <sys/socket.h>
#import <netinet/in.h>
#import <SystemConfiguration/SystemConfiguration.h>
Now just call this function:
/*
Connectivity testing code pulled from Apple's Reachability Example: https://developer.apple.com/library/content/samplecode/Reachability
*/
+(BOOL)hasConnectivity {
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)&zeroAddress);
if (reachability != NULL) {
//NetworkStatus retVal = NotReachable;
SCNetworkReachabilityFlags flags;
if (SCNetworkReachabilityGetFlags(reachability, &flags)) {
if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
{
// If target host is not reachable
return NO;
}
if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
{
// If target host is reachable and no connection is required
// then we'll assume (for now) that your on Wi-Fi
return YES;
}
if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
(flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
{
// ... and the connection is on-demand (or on-traffic) if the
// calling application is using the CFSocketStream or higher APIs.
if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
{
// ... and no [user] intervention is needed
return YES;
}
}
if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
{
// ... but WWAN connections are OK if the calling application
// is using the CFNetwork (CFSocketStream?) APIs.
return YES;
}
}
}
return NO;
}
And it's iOS 5 tested for you.
This used to be the correct answer, but it is now outdated as you should subscribe to notifications for reachability instead. This method checks synchronously:
You can use Apple's Reachability class. It will also allow you to check if Wi-Fi is enabled:
Reachability* reachability = [Reachability sharedReachability];
[reachability setHostName:#"www.example.com"]; // Set your host name here
NetworkStatus remoteHostStatus = [reachability remoteHostStatus];
if (remoteHostStatus == NotReachable) { }
else if (remoteHostStatus == ReachableViaWiFiNetwork) { }
else if (remoteHostStatus == ReachableViaCarrierDataNetwork) { }
The Reachability class is not shipped with the SDK, but rather a part of this Apple sample application. Just download it, and copy Reachability.h/m to your project. Also, you have to add the SystemConfiguration framework to your project.
Here's a very simple answer:
NSURL *scriptUrl = [NSURL URLWithString:#"http://www.google.com/m"];
NSData *data = [NSData dataWithContentsOfURL:scriptUrl];
if (data)
NSLog(#"Device is connected to the Internet");
else
NSLog(#"Device is not connected to the Internet");
The URL should point to an extremely small website. I use Google's mobile website here, but if I had a reliable web server I'd upload a small file with just one character in it for maximum speed.
If checking whether the device is somehow connected to the Internet is everything you want to do, I'd definitely recommend using this simple solution. If you need to know how the user is connected, using Reachability is the way to go.
Careful: This will briefly block your thread while it loads the website. In my case, this wasn't a problem, but you should consider this (credits to Brad for pointing this out).
Here is how I do it in my apps: While a 200 status response code doesn't guarantee anything, it is stable enough for me. This doesn't require as much loading as the NSData answers posted here, as mine just checks the HEAD response.
Swift Code
func checkInternet(flag:Bool, completionHandler:(internet:Bool) -> Void)
{
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
let url = NSURL(string: "http://www.google.com/")
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "HEAD"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
request.timeoutInterval = 10.0
NSURLConnection.sendAsynchronousRequest(request, queue:NSOperationQueue.mainQueue(), completionHandler:
{(response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
UIApplication.sharedApplication().networkActivityIndicatorVisible = false
let rsp = response as! NSHTTPURLResponse?
completionHandler(internet:rsp?.statusCode == 200)
})
}
func yourMethod()
{
self.checkInternet(false, completionHandler:
{(internet:Bool) -> Void in
if (internet)
{
// "Internet" aka Google URL reachable
}
else
{
// No "Internet" aka Google URL un-reachable
}
})
}
Objective-C Code
typedef void(^connection)(BOOL);
- (void)checkInternet:(connection)block
{
NSURL *url = [NSURL URLWithString:#"http://www.google.com/"];
NSMutableURLRequest *headRequest = [NSMutableURLRequest requestWithURL:url];
headRequest.HTTPMethod = #"HEAD";
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration ephemeralSessionConfiguration];
defaultConfigObject.timeoutIntervalForResource = 10.0;
defaultConfigObject.requestCachePolicy = NSURLRequestReloadIgnoringLocalAndRemoteCacheData;
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue: [NSOperationQueue mainQueue]];
NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:headRequest
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
if (!error && response)
{
block([(NSHTTPURLResponse *)response statusCode] == 200);
}
}];
[dataTask resume];
}
- (void)yourMethod
{
[self checkInternet:^(BOOL internet)
{
if (internet)
{
// "Internet" aka Google URL reachable
}
else
{
// No "Internet" aka Google URL un-reachable
}
}];
}
Apple supplies sample code to check for different types of network availability. Alternatively there is an example in the iPhone developers cookbook.
Note: Please see #KHG's comment on this answer regarding the use of Apple's reachability code.
You could use Reachability by  (available here).
#import "Reachability.h"
- (BOOL)networkConnection {
return [[Reachability reachabilityWithHostName:#"www.google.com"] currentReachabilityStatus];
}
if ([self networkConnection] == NotReachable) { /* No Network */ } else { /* Network */ } //Use ReachableViaWiFi / ReachableViaWWAN to get the type of connection.
Apple provides a sample app which does exactly this:
Reachability
Only the Reachability class has been updated. You can now use:
Reachability* reachability = [Reachability reachabilityWithHostName:#"www.apple.com"];
NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];
if (remoteHostStatus == NotReachable) { NSLog(#"not reachable");}
else if (remoteHostStatus == ReachableViaWWAN) { NSLog(#"reachable via wwan");}
else if (remoteHostStatus == ReachableViaWiFi) { NSLog(#"reachable via wifi");}
When using iOS 12 or macOS v10.14 (Mojave) or newer, you can use NWPathMonitor instead of the pre-historic Reachability class. As a bonus you can easily detect the current network connection type:
import Network // Put this on top of your class
let monitor = NWPathMonitor()
monitor.pathUpdateHandler = { path in
if path.status != .satisfied {
// Not connected
}
else if path.usesInterfaceType(.cellular) {
// Cellular 3/4/5g connection
}
else if path.usesInterfaceType(.wifi) {
// Wi-Fi connection
}
else if path.usesInterfaceType(.wiredEthernet) {
// Ethernet connection
}
}
monitor.start(queue: DispatchQueue.global(qos: .background))
More info here: https://developer.apple.com/documentation/network/nwpathmonitor
A version on Reachability for iOS 5 is darkseed/Reachability.h. It's not mine! =)
There's a nice-looking, ARC- and GCD-using modernization of Reachability here:
Reachability
If you're using AFNetworking you can use its own implementation for internet reachability status.
The best way to use AFNetworking is to subclass the AFHTTPClient class and use this class to do your network connections.
One of the advantages of using this approach is that you can use blocks to set the desired behavior when the reachability status changes. Supposing that I've created a singleton subclass of AFHTTPClient (as said on the "Subclassing notes" on AFNetworking docs) named BKHTTPClient, I'd do something like:
BKHTTPClient *httpClient = [BKHTTPClient sharedClient];
[httpClient setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status)
{
if (status == AFNetworkReachabilityStatusNotReachable)
{
// Not reachable
}
else
{
// Reachable
}
}];
You could also check for Wi-Fi or WLAN connections specifically using the AFNetworkReachabilityStatusReachableViaWWAN and AFNetworkReachabilityStatusReachableViaWiFi enums (more here).
I've used the code in this discussion, and it seems to work fine (read the whole thread!).
I haven't tested it exhaustively with every conceivable kind of connection (like ad hoc Wi-Fi).
Very simple.... Try these steps:
Step 1: Add the SystemConfiguration framework into your project.
Step 2: Import the following code into your header file.
#import <SystemConfiguration/SystemConfiguration.h>
Step 3: Use the following method
Type 1:
- (BOOL) currentNetworkStatus {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
BOOL connected;
BOOL isConnected;
const char *host = "www.apple.com";
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, host);
SCNetworkReachabilityFlags flags;
connected = SCNetworkReachabilityGetFlags(reachability, &flags);
isConnected = NO;
isConnected = connected && (flags & kSCNetworkFlagsReachable) && !(flags & kSCNetworkFlagsConnectionRequired);
CFRelease(reachability);
return isConnected;
}
Type 2:
Import header : #import "Reachability.h"
- (BOOL)currentNetworkStatus
{
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [reachability currentReachabilityStatus];
return networkStatus != NotReachable;
}
Step 4: How to use:
- (void)CheckInternet
{
BOOL network = [self currentNetworkStatus];
if (network)
{
NSLog(#"Network Available");
}
else
{
NSLog(#"No Network Available");
}
}
-(void)newtworkType {
NSArray *subviews = [[[[UIApplication sharedApplication] valueForKey:#"statusBar"] valueForKey:#"foregroundView"]subviews];
NSNumber *dataNetworkItemView = nil;
for (id subview in subviews) {
if([subview isKindOfClass:[NSClassFromString(#"UIStatusBarDataNetworkItemView") class]]) {
dataNetworkItemView = subview;
break;
}
}
switch ([[dataNetworkItemView valueForKey:#"dataNetworkType"]integerValue]) {
case 0:
NSLog(#"No wifi or cellular");
break;
case 1:
NSLog(#"2G");
break;
case 2:
NSLog(#"3G");
break;
case 3:
NSLog(#"4G");
break;
case 4:
NSLog(#"LTE");
break;
case 5:
NSLog(#"Wifi");
break;
default:
break;
}
}
- (void)viewWillAppear:(BOOL)animated
{
NSString *URL = [NSString stringWithContentsOfURL:[NSURL URLWithString:#"http://www.google.com"]];
return (URL != NULL ) ? YES : NO;
}
Or use the Reachability class.
There are two ways to check Internet availability using the iPhone SDK:
1. Check the Google page is opened or not.
2. Reachability Class
For more information, please refer to Reachability (Apple Developer).
Use http://huytd.github.io/datatify/. It's easier than adding libraries and write code by yourself.
First: Add CFNetwork.framework in framework
Code: ViewController.m
#import "Reachability.h"
- (void)viewWillAppear:(BOOL)animated
{
Reachability *r = [Reachability reachabilityWithHostName:#"www.google.com"];
NetworkStatus internetStatus = [r currentReachabilityStatus];
if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN))
{
/// Create an alert if connection doesn't work
UIAlertView *myAlert = [[UIAlertView alloc]initWithTitle:#"No Internet Connection" message:NSLocalizedString(#"InternetMessage", nil)delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[myAlert show];
[myAlert release];
}
else
{
NSLog(#"INTERNET IS CONNECT");
}
}
Swift 3 / Swift 4
You must first import
import SystemConfiguration
You can check the Internet connection with the following method:
func isConnectedToNetwork() -> Bool {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
}
}
var flags = SCNetworkReachabilityFlags()
if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
return false
}
let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
return (isReachable && !needsConnection)
}
First download the reachability class and put reachability.h and reachabilty.m file in your Xcode.
The best way is to make a common Functions class (NSObject) so that you can use it any class. These are two methods for a network connection reachability check:
+(BOOL) reachabiltyCheck
{
NSLog(#"reachabiltyCheck");
BOOL status =YES;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(reachabilityChanged:)
name:kReachabilityChangedNotification
object:nil];
Reachability * reach = [Reachability reachabilityForInternetConnection];
NSLog(#"status : %d",[reach currentReachabilityStatus]);
if([reach currentReachabilityStatus]==0)
{
status = NO;
NSLog(#"network not connected");
}
reach.reachableBlock = ^(Reachability * reachability)
{
dispatch_async(dispatch_get_main_queue(), ^{
});
};
reach.unreachableBlock = ^(Reachability * reachability)
{
dispatch_async(dispatch_get_main_queue(), ^{
});
};
[reach startNotifier];
return status;
}
+(BOOL)reachabilityChanged:(NSNotification*)note
{
BOOL status =YES;
NSLog(#"reachabilityChanged");
Reachability * reach = [note object];
NetworkStatus netStatus = [reach currentReachabilityStatus];
switch (netStatus)
{
case NotReachable:
{
status = NO;
NSLog(#"Not Reachable");
}
break;
default:
{
if (!isSyncingReportPulseFlag)
{
status = YES;
isSyncingReportPulseFlag = TRUE;
[DatabaseHandler checkForFailedReportStatusAndReSync];
}
}
break;
}
return status;
}
+ (BOOL) connectedToNetwork
{
// Create zero addy
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
// Recover reachability flags
SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
SCNetworkReachabilityFlags flags;
BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
CFRelease(defaultRouteReachability);
if (!didRetrieveFlags)
{
NSLog(#"Error. Could not recover network reachability flags");
return NO;
}
BOOL isReachable = flags & kSCNetworkFlagsReachable;
BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection;
NSURL *testURL = [NSURL URLWithString:#"http://www.apple.com/"];
NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
NSURLConnection *testConnection = [[NSURLConnection alloc] initWithRequest:testRequest delegate:self];
return ((isReachable && !needsConnection) || nonWiFi) ? (testConnection ? YES : NO) : NO;
}
Now you can check network connection in any class by calling this class method.
There is also another method to check Internet connection using the iPhone SDK.
Try to implement the following code for the network connection.
#import <SystemConfiguration/SystemConfiguration.h>
#include <netdb.h>
/**
Checking for network availability. It returns
YES if the network is available.
*/
+ (BOOL) connectedToNetwork
{
// Create zero addy
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
// Recover reachability flags
SCNetworkReachabilityRef defaultRouteReachability =
SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
SCNetworkReachabilityFlags flags;
BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
CFRelease(defaultRouteReachability);
if (!didRetrieveFlags)
{
printf("Error. Could not recover network reachability flags\n");
return NO;
}
BOOL isReachable = ((flags & kSCNetworkFlagsReachable) != 0);
BOOL needsConnection = ((flags & kSCNetworkFlagsConnectionRequired) != 0);
return (isReachable && !needsConnection) ? YES : NO;
}
To do this yourself is extremely simple. The following method will work. Just be sure to not allow a hostname protocol such as HTTP, HTTPS, etc. to be passed in with the name.
-(BOOL)hasInternetConnection:(NSString*)urlAddress
{
SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [urlAddress UTF8String]);
SCNetworkReachabilityFlags flags;
if (!SCNetworkReachabilityGetFlags(ref, &flags))
{
return NO;
}
return flags & kSCNetworkReachabilityFlagsReachable;
}
It is quick simple and painless.
I found it simple and easy to use library SimplePingHelper.
Sample code: chrishulbert/SimplePingHelper (GitHub)
I think this one is the best answer.
"Yes" means connected. "No" means disconnected.
#import "Reachability.h"
- (BOOL)canAccessInternet
{
Reachability *IsReachable = [Reachability reachabilityForInternetConnection];
NetworkStatus internetStats = [IsReachable currentReachabilityStatus];
if (internetStats == NotReachable)
{
return NO;
}
else
{
return YES;
}
}
Download the Reachability file, https://gist.github.com/darkseed/1182373
And add CFNetwork.framework and 'SystemConfiguration.framework' in framework
Do #import "Reachability.h"
First: Add CFNetwork.framework in framework
Code: ViewController.m
- (void)viewWillAppear:(BOOL)animated
{
Reachability *r = [Reachability reachabilityWithHostName:#"www.google.com"];
NetworkStatus internetStatus = [r currentReachabilityStatus];
if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN))
{
/// Create an alert if connection doesn't work
UIAlertView *myAlert = [[UIAlertView alloc]initWithTitle:#"No Internet Connection" message:NSLocalizedString(#"InternetMessage", nil)delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[myAlert show];
[myAlert release];
}
else
{
NSLog(#"INTERNET IS CONNECT");
}
}
For my iOS projects, I recommend using
Reachability Class
Declared in Swift. For me, it works simply fine with
Wi-Fi and Cellular data
import SystemConfiguration
public class Reachability {
class func isConnectedToNetwork() -> Bool {
var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
}
}
var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
return false
}
let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
let ret = (isReachable && !needsConnection)
return ret
}
}
Use a conditional statement,
if Reachability.isConnectedToNetwork() {
// Enter your code here
}
}
else {
print("NO Internet connection")
}
This class is useful in almost every case your app uses the Internet connection.
Such as if the condition is true, API can be called or task could be performed.
The Reachability class is OK to find out if the Internet connection is available to a device or not...
But in case of accessing an intranet resource:
Pinging the intranet server with the reachability class always returns true.
So a quick solution in this scenario would be to create a web method called pingme along with other webmethods on the service.
The pingme should return something.
So I wrote the following method on common functions
-(BOOL)PingServiceServer
{
NSURL *url=[NSURL URLWithString:#"http://www.serveraddress/service.asmx/Ping"];
NSMutableURLRequest *urlReq=[NSMutableURLRequest requestWithURL:url];
[urlReq setTimeoutInterval:10];
NSURLResponse *response;
NSError *error = nil;
NSData *receivedData = [NSURLConnection sendSynchronousRequest:urlReq
returningResponse:&response
error:&error];
NSLog(#"receivedData:%#",receivedData);
if (receivedData !=nil)
{
return YES;
}
else
{
NSLog(#"Data is null");
return NO;
}
}
The above method was so useful for me, so whenever I try to send some data to the server I always check the reachability of my intranet resource using this low timeout URLRequest.
Apart from reachability you may also use the Simple Ping helper library. It works really nice and is simple to integrate.