Can anyone please help in getting fix for fetching location updates in ios8 xcode6 i am getting the crash at [locationManager requestAlwaysAuthorization];
if i place this line of code in
if ([locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[locationManager requestAlwaysAuthorization];
}
then Locationmanager delegates are not called.
I was having the exactly same problems.
Then I figured that I ran it on the wrong device (wrong iOS)
locationManager requestAlwaysAuthorization
availability iOS 8.0 and later
That's it. Run it on iOS 8 or later. You better use check version to use that method.
Related
For the latest ios version on the iPhone, I'm not getting the 'always' for always track your location on the iPhone. I'm getting while on the app and never. However this functionality seems to be working fine for every version previous. Any other suggestions than what I've done in XCode below would be great.
CDVLocation.m
if([[NSBundle mainBundle] objectForInfoDictionaryKey:#"NSLocationAlwaysUsageDescription"]){
[self.locationManager requestWhenInUseAuthorization];
} else if([[NSBundle mainBundle] objectForInfoDictionaryKey:#"NSLocationWhenInUseUsageDescription"]) {
[self.locationManager requestAlwaysAuthorization];
} else {
NSLog(#"[Warning] No NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription key is defined in the Info.plist file.");
}
in the plist file
<key>NSLocationAlwaysUsageDescription</key>
<string>This app requires constant access to your location in order to track your position, even when the screen is off.</string>
The code has the logic inverted, it should be this:
if ([[NSBundle mainBundle] objectForInfoDictionaryKey:#"NSLocationAlwaysUsageDescription"]){
[self.locationManager requestAlwaysAuthorization];
} else if([[NSBundle mainBundle] objectForInfoDictionaryKey:#"NSLocationWhenInUseUsageDescription"]) {
[self.locationManager requestWhenInUseAuthorization];
} else {
NSLog(#"[Warning] No NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription key is defined in the Info.plist file.");
}
Notice I switched these two lines:
[self.locationManager requestAlwaysAuthorization];
[self.locationManager requestWhenInUseAuthorization];
You can refer to the master source code.
Additionally, for iOS 11, when requesting always permission you should include the NSLocationAlwaysAndWhenInUseUsageDescription and the NSLocationWhenInUseUsageDescription key in your info plist.
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>When always is requested in iOS 11</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>When "when in use" is requested in iOS 11</string>
You are required to include the NSLocationWhenInUseUsageDescription and NSLocationAlwaysAndWhenInUseUsageDescription keys in your app's Info.plist file. (If your app supports iOS 10 and earlier, the NSLocationAlwaysUsageDescription key is also required.) If those keys are not present, authorization requests fail immediately.
UPDATE: THIS IS NOT A DUPLICATE. I have already added the required key to the info.plist as stated in my original question and the issue remains. I have tried all three keys in various combinations.
Before anyone gets upset, I have read through many Apple Dev forum posts and stack overflow posts and cannot figure out why my app refuses to prompt the user to allow When In Use authorization.
I've added the following key to my Info.plist file with an accompanying String value:
NSLocationWhenInUseUsageDescription
I've then written (both in Swift and Obj-C) the code that should prompt the user:
#property CLLocationManager *location;
...
#synthesize location;
...
location = [[CLLocationManager alloc] init];
location.delegate = self;
location.desiredAccuracy = kCLLocationAccuracyBest;
location.distanceFilter = kCLDistanceFilterNone;
[location requestWhenInUseAuthorization];
[location startUpdatingLocation];
I'm using the following CLLocationManagerDelegate methods.
- (void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
- (void) locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
This was basically copied straight from the Apple "LocateMe" sample code.
No matter what various sequences or minor changes I try, the app never prompts to allow authorization. I've used a switch statement to determine the state of [CLLocationManager authorizationStatus], but continually recieve a "Not Determined" response.
if ([CLLocationManager locationServicesEnabled]) {
switch ([CLLocationManager authorizationStatus]) {
case kCLAuthorizationStatusAuthorizedAlways:
NSLog(#"Always Authorized");
break;
case kCLAuthorizationStatusDenied:
NSLog(#"Denied");
break;
case kCLAuthorizationStatusAuthorizedWhenInUse:
NSLog(#"Authorized in Use");
break;
case kCLAuthorizationStatusNotDetermined:
NSLog(#"Not Determined");
break;
case kCLAuthorizationStatusRestricted:
NSLog(#"Restricted");
break;
}
}
Any help would be greatly appreciated. I'm running Xcode 6.2 (6C101) with iOS 8.1.2 physical device and iOS 8.2 (12D5452a) simulator for testing.
I faced the exact same problem, after digging in for two days, it turned out that the app does not read from the info.plist file that is included in the bundle in project navigator's pane, because it has been localized to another language and base internationalization is being used, that means in Finder there will be 3 info.plist files:
1- under Tests folder
2- under base.lproj folder
3- under ar.lprj (ar refers to Arabic language).
the project reads from base.lproj's version which is not included inside the bundle in the project navigator's pane.
what I did is that I took a backup copy of the plist file that I want (number 2 above), and removed localization on the info.plist file that is inside project navigator and chose delete from disk to delete it completely, then I took the back up copy and placed in under project's root in Finder and import it back in Xcode, and now the project reads from the new info.plist file and the key NSLocationWhenInUseUsageDescription fires up the user authorization alert at app launch.
hope this helps.
If you have changed the Location Settings in your iPhone simulator this may cause the prompt to not show. For example, if you are already set the Location permissions via Allow Locations access iOS prompt and made a decision this is stored in the Privacy settings for the iPhone simulator and so subsequent calls to locationManager.requestAlwaysAuthorization() or locationManager.requestWhenInUseAuthorization() will not display the iOS prompt because you already have defined your Privacy -> Location Settings for your app.
To clear settings for an iPhone simulator: "iOS Simulator" -> "Reset Content and Settings..."
Also I did a Clean build in Xcode and quit and restarted the iPhone simulator at some point, I could be wrong about this part being of any help...
Lots of useful comparisons here: http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/
Also, silly question time: you mix _location and self.location but you don't show your property/synthesize code. Are you sure you're operating on the same object?
I found that in your info.plst file you can't use the Privacy - Location Usage Description key, you have to have a key called NSLocationWhenInUseUsageDescription and a value. I was able to get your code working by adding this key into my info.plist
#import <MapKit/MapKit.h>
#interface ViewController ()
#property CLLocationManager * location;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_location = [[CLLocationManager alloc] init];
self.location.delegate = self;
self.location.desiredAccuracy = kCLLocationAccuracyBest;
self.location.distanceFilter = kCLDistanceFilterNone;
[_location requestWhenInUseAuthorization];
[self.location startUpdatingLocation];
}
It may be silly, but i just spent almost 2 hours double and triple checking all of the answers i could find about CLLocationManager permissions.
I felt stupid when i finally realized that i had 2 info.plist files and i was using the wrong one!
You can check in your project's build settings - there's a value called Info.plist File.
Just want to leave it here for future readers.
We are making an app to be compatible with iOS 8, but at the same time, some of our developers do not have Xcode 6 yet, so they are getting this error when trying to call
[self.locationManager requestAlwaysAuthorization];
Even if it is inside an if
if(floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) {
[self.locationManager requestAlwaysAuthorization];
}
How can we solve this to compile on Xcode 5?
The following is the proper way to deal with this. This assumes that your app has a "Deployment Target" of iOS 7.x or earlier and you need to compile the project with different values for the "Base SDK" (such as iOS 8 under Xcode 6 and iOS 7 under Xcode 5):
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
// Being compiled with a Base SDK of iOS 8 or later
// Now do a runtime check to be sure the method is supported
if ([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
} else {
// No such method on this device - do something else as needed
}
#else
// Being compiled with a Base SDK of iOS 7.x or earlier
// No such method - do something else as needed
#endif
Accepted answer didn't work for my particular situation. Due to build enviroment limitations (Phonegap/Cordova) I'm stuck on compiling against the iOS7 SDK only.
I implemented the following (as suggested in comments):
if([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
// Use performSelector: so compiler won't blow up on this
[self.locationManager performSelector:#selector(requestAlwaysAuthorization)];
}
It might show compiler warnings, but atleast it works in that specific case.
I'm using Xcode 6 beta (6A215l). I've referred this question and updated my code to:
use NSLocationWhenInUseUsageDescription in the .plist file,
call requestWhenInUseAuthorization in the source code
but neither didUpdateLocations: nor didFailWithError: was called. If I use NSLocationAlwaysUsageDescription and requestAlwaysAuthorization, my app works.
Does anyone have the same problem? I wonder if I should try with Xcode 6 beta 2..
In fact, if you want to use the requestWhenInUseAuthorization in your app and gets the didUpdateLocations: and didFailWithError: delegate methods to be called, you need to set in your .plist file BOTH NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription keys, to make it work.
Theses texts will then be displayed in the Settings/Privacy/Location Services/App section of your device.
So,
i'm trying to port my app to iPad.
I'm using CoreLocation.
Apple says the iPad does have
Location:
Wi-Fi
Digital compass
Assisted GPS (Wi-Fi + 3G model)
Cellular (Wi-Fi + 3G model)
so it should be possible to get the position of my ipad (at least with 3g model) about 3km radius would be enought.
but it doesnt work in simulator (3.2 ipad) (running 3.1.3 in simulator simulates me cupertino).
is there a way to get the position in simulator (3.2 ipad) ?
i live in germany and here the ipad isnt released yet, so i cannot test it on my device.
thanks!
edit
thats how i'm trying to get my connection
locationManager = [[CLLocationManager alloc] init];
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
locationManager.delegate = self;
[locationManager startUpdatingLocation];
and always on 3.2 locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error gets called. not on 3.1.3
error object looks like this:
Error Domain=kCLErrorDomain Code=0 "Operation could not be completed. (kCLErrorDomain error 0.)"
edit
so i handled it something like this:
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
#ifdef TARGET_IPHONE_SIMULATOR
// Cupertino
CLLocation *simulatorLocation = [[CLLocation alloc] initWithLatitude:37.33168900 longitude:-122.03073100];
[self locationManager:locationManager didUpdateToLocation:simulatorLocation fromLocation:nil];
[simulatorLocation release];
#else
[[NSNotificationCenter defaultCenter] postNotificationName:#"ErrorNotification" object:NSLocalizedString(#"GPS-coordinates could not be detected",#"")];
#endif
}
It is very messy but works.
edit2: try enabling your Airport, this could also solve the problem!!
Yes, see this question which has several good answers to this.
EDIT - I eventually decided to write my own CLLocationManager simulator for testing on the iPhone simulator. It's located on github here if you want to use it.
According to the iPhone Development Guide, the location in the simulator is fixed. Sorry!
You might also wanna check out my FTLocationSimulator.
It reads a KML file generated by Google Earth to provide continuous location updates. It also updates the blue userLocation dot in a MKMapView with the simulated location updates.