CLLocationManager not getting location without WIFI and Cellular Data - objective-c

I have implemented Location module by using CLLocationManager but gets some problems.
Getting location finely if device has WIFI or Cellular Data(3G) but when i turn both of them off. Location stop updating i mean on GPS not working.
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.distanceFilter = 100.0f;
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
self.locationManager.delegate = self;
[self.locationManager startUpdatingLocation];
EDIT:
Problem facing on iPhone.

You need to enable cellular data for GPS to work. You don't have to have a cellular signal but the system requires that cellular data be enabled in order to allow location services.
In iOS 4 you used to be able to use location services even in Airplane Mode, by enabling Location Services in Settings after switching to Airplane mode, but this broke in iOS 5.
I've filed a bug report with Apple but they say this is how it is supposed to work now. They try to use cellular and wifi signals triangulation to make corrections to the GPS position.

Related

background location iOS 8

Hello Devs: I am working on an app where I would like to fetch users location in background and send push notifications to him as soon as the user arrives at that particular location. Here is what I have done so far with my locatioManager in my app delegate
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
if (IS_OS_8_OR_LATER) [locationManager requestAlwaysAuthorization];
[locationManager startUpdatingLocation];
I have set up my info.plist to always request location. I also get the message that my app will be using location in the background when I install the app on my device. However when I close the app and arrive at the specific location I don't get any push notifications or alerts until I launch the app. I turned on Background mode --> location updates under capabilities section and then everything works absolutely fine. I receive notification seamlessly without launching the app. This is all good but when I close the app I see a blue bar on my status bar saying that my app is tracking the location in background. How do I hide that blue bar on the top? I am pretty sure this is going to scare away my users and they will remove my app instantly. To make long story short how do I accomplish this? I know this question has been asked and answered several times in past but all those answers are 2-3 years old and don't seem to work with new iOS 8. I need to get the user location in background in order for my app to work or else its useless. I will really appreciate any help or suggestions to this.
Thanks!
What you want to do is called (background) Geofencing. Your app doesn't need to calculate it by itself since CoreLocation already offers this feature.
Please have a look at this answer from Daniel.
The Geofencing feature will wake up your app when the users gets into the target zone, and will not display the blue bar.

CLBeacon - how to change rssi, major and minor?

My question is basically - how do I get to modify iBeacon's default settings like major, minor and RSSI?
There are different ways to set these values depending on what you mean by an iBeacon:
Hardware iBeacons
Each Beacon vendor has different ways of setting these values. Some are changed via a bluetooth service that is typically managed with a proprietary iOS or Android app. (Examples include Radius Networks' battery-powered and USB beacons and TwoCanoes beacons.) Radius Networks' PiBeacon includes an SD card with an editable file containing the identifiers. Other vendors like Estimote create beacons with fixed UUIDs that cannot be changed. Because there is no standard mechanism, there is no universal tool for setting identifiers on all beacon types.
iOS Software iBeacons:
You set these values with code like below:
CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:#"2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6"] major:1 minor:1 identifier:#"com.radiusnetworks.iBeaconExample"];
NSDictionary *peripheralData = [region peripheralDataWithMeasuredPower:-55];
[_peripheralManager startAdvertising:peripheralData];
The iOS CLBeacon class
The CLBeacon class is not designed to be created or modified by the user -- it is supposed to be constructed by CoreLocation when it detects iBeacons. That said, you can force writing to its read-only properties using KVO syntax like so:
CLBeacon * iBeacon = [[CLBeacon alloc] init];
[iBeacon setValue:[NSNumber numberWithInt:1] forKey:#"major"];
[iBeacon setValue:[NSNumber numberWithInt:1] forKey:#"minor"];
[iBeacon setValue:[NSNumber numberWithInt:-55] forKey:#"rssi"];
[iBeacon setValue:[[NSUUID alloc] initWithUUIDString:#"2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6"] forKey:#"proximityUUID"];
NSLog(#"I constructed this iBeacon manually: %#", iBeacon);
However, if you are forcing the CLBeacon class to be used in ways it was not designed to be used that might mean you are doing something wrong.
Full disclosure: I work for Radius Networks.
When you initialize a CLBeaconRegion object you can specify Major and Minor variables. Took a look at initWithProximityUUID:major:minor:identifier method.
As far as am aware ones a beacon active your cannot change it value unless you recreate that object. Rssi represents signal strength of the beacon which is only read-only and depends on the environment.
Here the link for the (documentation](https://developer.apple.com/library/iOs/documentation/CoreLocation/Reference/CLBeaconRegion_class/Reference/Reference.html#//apple_ref/doc/uid/TP40013054)

Are there iOS devices that can monitor iBeacons but not range them?

Or asked another way will
[CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]]
and
[CLLocationManager isRangingAvailable]
ever return different values?
Short answer: No, there are not any iOS devices that can monitor iBeacons but not range them. Both methods will return the same value if isMonitoringAvailableForClass is given a CLBeaconRegion instance.
The reason the API looks this way is because the isMonitoringAvailableForClass method can be called with classes other than a CLBeaconRegion class. CLCircularRegion is used for monitoring geofence regions. The method might return NO when passed CLBeaconRegion on a device without LE Bluetooth, and return YES when passed a CLCircularRegion on the same device.
I believe there is one case when [CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]] will return NO and [CLLocationManager isRangingAvailable] will return YES.
If Background App Refresh is turned off [CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]] should return NO.
In Apple's Location and Maps Programming Guide under the "Determining the Availability of Region Monitoring" section:
Before attempting to monitor any regions, your app should check
whether region monitoring is supported on the current device. Here are
some reasons why region monitoring might not be available:
The device doesn’t have the necessary hardware to support region monitoring.
The user denied the app the authorization to use region monitoring.
The user disabled location services in the Settings app.
The user disabled Background App Refresh in the Settings app, either for the device or for your app.
The device is in Airplane mode and can’t power up the necessary hardware.
(I've bolded the fourth bullet point, because it's the case I'm talking about.)
Ranging is, however, only a foreground activity so Background App Refresh settings aren't important.
In this one case region monitoring will not be available, but ranging will be available.
Note: Currently, when Background App Refresh is turned [[CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]] returns YES, but when you start monitoring you'll never get notification and if you call requestStateForRegion: then locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error will be called on the CLLocationManager's delegate.
The error message will be "The operation couldn't be completed." with an error code of 4, which translates via CLError.h to kCLErrorRegionMonitoringDenied.
I hope Apple will fix the false positive in [[CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]] in one the next few updates.

How do you programmatically detect your iPad's generation?

I'm working on a program that needs to be able to detect whether or not camera hardware is present in the iPad. I assumed that the easiest way to do this was to determine what generation the device was, but if there is a simpler way to detect the hardware that works too. The iPads that this application is being designed for will likely be recently purchased and running on a standard updated version of iOS.
Nope You can simply check what device is being used!
For checking all iOS devices:
NSString *deviceType = [UIDevice currentDevice].model;
NSLog(deviceType);
In order to check for a camera
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera])
//there is a camera

iOS keep gps permission during the session

My app loads a jquery + google maps file into webview and when viewDidLoad activates an alert asking for gps accessing (as normal). After validating it, if this view is reloaded later, still pushing the alert! how to keep gps permissions in order to avoid multiple alerts asking for permission? Thank you.
I would try to access the GPS from native Obj-C code first, and after that let the webview to load:
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
[locationManager startUpdatingLocation];
[locationManager stopUpdatingLocation];
This should validate your app to use the GPS, and therefore the Webview to use it (at least if it is a local webview, not sure if it is remote).