So I recently updated to the latest Parse SDK that's compatible with iOS 8 and I add the two keys NSLocationWhenInUseUsageDescription and NSLocationAlwaysUsageDescription...but for some reason [PFGeoPoint geopointForCurrentLocationInBackground] is not being called....and I don't understand why.
and here is a snippet of the code:
[PFGeoPoint geoPointForCurrentLocationInBackground:^(PFGeoPoint *geoPoint, NSError *error) {
if(!error){
NSLog(#"Got current geopoint!");
....
else{
UIAlertView *errorAlert = [[UIAlertView alloc]initWithTitle:#"Oops!" message:[error description] delegate:self cancelButtonTitle:nil otherButtonTitles:#"Okay", nil];
[errorAlert show]; }
}];
Can someone help please?
[PFGeoPoint geopointForCurrentLocationInBackground] will only be called if you have first called your CLLocationManager engaged and have asked the user for permission to show their location.
You also need to update the (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status method for iOS 8.
Something like this is what I use:
// Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7.
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
else {
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
//<<PUT YOUR CODE HERE AFTER LOCATION IS UPDATING>>
}
You also need to implement the locationmanager delegate method to handle changes is location authorization status, like so:
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
switch (status) {
case kCLAuthorizationStatusDenied:
NSLog(#"kCLAuthorizationStatusDenied");
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Location Services Not Enabled" message:#"The app can’t access your current location.\n\nTo enable, please turn on location access in the Settings app under Location Services." delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alertView show];
}
break;
case kCLAuthorizationStatusAuthorizedWhenInUse:
{
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
CLLocation *currentLocation = locationManager.location;
if (currentLocation) {
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate setCurrentLocation:currentLocation];
}
}
break;
case kCLAuthorizationStatusAuthorizedAlways:
{
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
CLLocation *currentLocation = locationManager.location;
if (currentLocation) {
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate setCurrentLocation:currentLocation];
}
}
break;
case kCLAuthorizationStatusNotDetermined:
NSLog(#"kCLAuthorizationStatusNotDetermined");
break;
case kCLAuthorizationStatusRestricted:
NSLog(#"kCLAuthorizationStatusRestricted");
break;
}
}
Related
I require location of the user in my application if in case the user has device location services disabled I am checking like this.
if([CLLocationManager locationServicesEnabled])
{
if([locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
{
[locationManager requestWhenInUseAuthorization];
}
}
else if(![CLLocationManager locationServicesEnabled])
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Location Services are disabled please enable location services to enjoy nearby experience" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Settings", nil];
alert.tag = 103;
[alert show];
}
In my alert view I am directing the user to location settings like this
else if(alertView.tag == 103)
{
if(buttonIndex == 1)
{
NSURL*url=[NSURL URLWithString:#"prefs:root=LOCATION_SERVICES"];
[[UIApplication sharedApplication] openURL:url];
}
}
After the user comes back from settings how to get location again
You can manage your stuff in applicationWillEnterForeground because this method will get called when you come from setting app to your app.
You can write your code in this method like,
if([CLLocationManager locationServicesEnabled])
{
if([locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
{
[locationManager requestWhenInUseAuthorization];
}
}
Use Location Delegate method :-
if([CLLocationManager locationServicesEnabled])
{
if([locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
{
[locationManager requestWhenInUseAuthorization];
//Set Location Delegate
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
//Update Location start
[locationManager startUpdatingLocation];
}
}
else if(![CLLocationManager locationServicesEnabled])
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Location Services are disabled please enable location services to enjoy nearby experience" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Settings", nil];
alert.tag = 103;
[alert show];
}
#pragma mark CLLocationManager Delegate
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
//NSLog(#"OldLocation %f %f", oldLocation.coordinate.latitude, oldLocation.coordinate.longitude);
//NSLog(#"NewLocation %f %f", newLocation.coordinate.latitude, newLocation.coordinate.longitude);
[locationManager stopUpdatingLocation];
}
I have this code in my class ViewController:
CLLocationManager *locationManager;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
locationManager = [[CLLocationManager alloc] init];
[locationManager requestWhenInUseAuthorization];
}
- (IBAction)getCurrentLocation:(id)sender {
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
#pragma mark - CLLocationManagerDelegate
-(void) locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(#"Did finish with error - %#", error);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Failed to get your location" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSLog(#"did Update Location - %#", newLocation);
CLLocation *currentLocation = newLocation;
if(currentLocation != nil) {
_longitudeLabel.text = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.longitude];
_latitudeLabel.text = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.latitude];
}
}
But I am not getting the location or the popup for allowing access.
I am using the Core Location framework.
On button click I am printing latitude, longitude and address in labels.
I am testing this on the simulator.
Sometimes Simulator wont work with location enabled services use Apple Device for perfect testing.
Add the following keys inside your info.plist file to get allow access popup.
or add them as updating info.plist file source code.
<key>NSLocationAlwaysUsageDescription</key>
<string>message for location uses</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>message for location uses</string>
Try this code in viewDidLoad...
//---- For getting current gps location
locationManager = [CLLocationManager new];
locationManager.delegate = self;
if ([locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[locationManager requestWhenInUseAuthorization];
}
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
//------
You also have to add a string for the NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription keys to the app's Info.plist.
locationManager =[[CLLocationManager alloc] init];
[locationManager requestWhenInUseAuthorization];
locationManager.delegate=self;
locationManager.desiredAccuracy=kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
you can add in your plist:
<key>NSLocationAlwaysUsageDescription</key>
<key>NSLocationWhenInUseUsageDescription</key>
I have methods in viewDidLoad, and it seems like the order of methods getting called is weird.
- (void)viewDidLoad
{
[super viewDidLoad];
// Get Location
self.locationManager = [[CLLocationManager alloc] init];
self.geocoder = [[CLGeocoder alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
if([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
{
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
// Retrieve Data
[self retrieveData];
}
After viewDidLoad is called, it calls the retrieveData method before locationManager.
Shouldn't the locationManager be called before retrieveData because of the order?
I am new in Objective C, thank you for your help in advance.
as per your need call your method in inside the delegate methods, so remove the [self retrieveData]; from ViewDidLoad and add into inside the didFailWithError or didUpdateLocations methods.
- (void)viewDidLoad
{
[super viewDidLoad];
// Get Location
self.locationManager = [[CLLocationManager alloc] init];
self.geocoder = [[CLGeocoder alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
if([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
{
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
UIAlertView *errorAlert = [[UIAlertView alloc]
initWithTitle:#"Error"
message:#"Failed to Get Your Location"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[errorAlert show];
// call here
[self retrieveData];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// set or stop your location update
manager = nil;
[self.locationManager stopUpdatingLocation];
[manager stopUpdatingLocation];
CLLocation *newLocation = locations[[locations count] -1];
CLLocation *currentLocation = newLocation;
NSString *longitude = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.longitude];
NSString *latitude = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.latitude];
if (currentLocation != nil) {
NSLog(#"latitude: %#", latitude);
NSLog(#"longitude: #"%#", longitude);
}else {
UIAlertView *errorAlert = [[UIAlertView alloc]
initWithTitle:#"Error" message:#"Failed to Get Your Location"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[errorAlert show];
}
// call here
[self retrieveData];
}
Note
objective -C is the interpreter , it execute the every in step by step , so or may be your [self retrieveData]; is called in main thread, that is the reason it execute in prior.
I kept Guided Access for iPad app. When the app is launched it asks for user's current location using CLLocationManager.This is working under Normal mode and updates user current location. But under Guided Access, popup ("Allow to access your location") is not shown and authorizationStatus is always kCLAuthorizationStatusNotDetermined and doesn't update current location of user . Couldn't understand what could be the problem.Searched a lot but couldn't find it.
ViewController.m :
- (void)viewDidAppear:(BOOL)animated
{
[appDelegate startLocation];
[self performSelector:#selector(CheckLocationManger) withObject:nil afterDelay:0.1];
}
-(void)CheckLocationManger
{
AppAppDelegate *appDelegate=(AppAppDelegate*)[[UIApplication sharedApplication]delegate];
if(![CLLocationManager locationServicesEnabled])
{
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:#"Whoops we can’t find you!" message:#"Location services are disabled" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
if(activityIndictr)
[activityIndictr stopAnimating];
[alert1 show];
return;
}
if([CLLocationManager locationServicesEnabled])
{
if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusDenied)
{
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:#"Whoops we can’t find you!"message:#"Location services are disabled. You can fix this by going to Settings > Privacy > Location" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
if(activityIndictr)
[activityIndictr stopAnimating];
[alert1 show];
return;
}
if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusNotDetermined) //This is called
{
[self performSelector:#selector(CheckLocationManger) withObject:self afterDelay:0.1];
return;
}
}
if(![self connected])
{
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:#"Network Error" message:#"Please verify that you have internet connectivity" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
if(activityIndictr)
[activityIndictr stopAnimating];
[alert1 show];
[alert1 release];
return;
}
else {
//continue further process
}
}
AppDelegate.m
- (void)startLocation
{
self.locationManager = [[[CLLocationManager alloc] init]autorelease];
self.locationManager.pausesLocationUpdatesAutomatically=NO;
[self.locationManager setDelegate:self];
if([[[UIDevice currentDevice ]systemVersion] floatValue]>=8.0)
{
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization]; //is executed but popup never displays
}
}
[self.locationManager startUpdatingLocation];
}
Any suggestions would be helpful.Thank you !
At very first set NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription in your .plist.
Add CoreLocation.framework and import in your class.h file -> #import <CoreLocation/CoreLocation.h> then set CLLocationManagerDelegate to your class.
Declare #property (strong, nonatomic) CLLocationManager *locationManager;
Init locationManager and set default value to it.
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.pausesLocationUpdatesAutomatically = NO;
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBestForNavigation];
[self.locationManager setDistanceFilter:200.0f];
if ([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) // Or if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)])
[self.locationManager requestAlwaysAuthorization]; // Or [self.locationManager requestWhenInUseAuthorization];
[self.locationManager startUpdatingLocation];
Implement CLLocationMAnager delegate method
#pragma mark - Location Delegate
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(#"updated coordinate are %#", [locations lastObject]);
CLLocation *currentLocation = [locations lastObject];
// Your code.....
}
my program is working fine in iOS7 but not iOS8..
locationManager is object of CLLocationManager here.
In starting this code is working fine in iOS7,i can not understand why this happen to me.
- (void)getCurrentLocation{
locationManager = [[CLLocationManager alloc] init];
geocoder = [[CLGeocoder alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{
if (status == kCLAuthorizationStatusAuthorized) {
NSUserDefaults *notify = [NSUserDefaults standardUserDefaults];
[notify setObject:#"GPS" forKey:#"Notification"];
[notify synchronize];
appDelegate = (JobDiagnosisAppDelegate *)[[UIApplication sharedApplication] delegate];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:TRUE];
[appDelegate showIndicator];
[notify setObject:nil forKey:#"Notification"];
[notify synchronize];
}
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"didFailWithError: %#", error);
[appDelegate.objActivityAlertView close];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:FALSE];
appDelegate = (JobDiagnosisAppDelegate *)[[UIApplication sharedApplication] delegate];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:TRUE];
[appDelegate showIndicator];
[self callWebserviceLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(#"Resolving the Address");
[geocoder reverseGeocodeLocation: locationManager.location completionHandler:
^(NSArray *placemarks, NSError *error) {
//Get address
CLPlacemark *placemark = [placemarks objectAtIndex:0];
//String to address
NSString *locatedaddress =[placemark valueForKey:#"administrativeArea"] ;
//Print the location in the console
NSLog(#"Currently address is: %#",locatedaddress);
NSUserDefaults *notifyLocation = [NSUserDefaults standardUserDefaults];
[notifyLocation setObject:locatedaddress forKey:#"notifyLocation"];
[notifyLocation synchronize];
locationManager.delegate = nil;
[self callWebserviceUnRegistered];
}];
[locationManager stopUpdatingLocation];
}
please help to solve this location problem.I am new in location services.
thanks in advance!!
You Need to implement
[locationManager requestWhenInUseAuthorization];or
[locationManager requestAlwaysAuthorization];
If you do not make either of two request , iOS will ignore startUpdateLocation request.
Also,
Include NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription key in Info.plist depending upon which permission you are asking for. This string will be diaplayed by iOS to user so the user can get excat idea why does our app needs permission.
So change your methood to
- (void)getCurrentLocation{
locationManager = [[CLLocationManager alloc] init];
geocoder = [[CLGeocoder alloc] init];
locationManager.delegate = self;
[locationManager requestWhenInUseAuthorization];
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
And aslo add required key in info.plist.
Hope this helps.
First, don't forget, with IOS 8 you need to add NSLocationWhenInUseUsageDescription property to the info.plist file in order to prompt the alert to get the user's permission and use[locationManager requestWhenInUseAuthorization] plus [locationManager requestAlwaysAuthorization];
_locationManager = [CLLocationManager new];
if(SYSTEM_IS_OS_8_OR_LATER) {
[_locationManager requestWhenInUseAuthorization];
[_locationManager requestAlwaysAuthorization];
}
_locationManager.delegate = self;
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
_locationManager startUpdatingLocation];
and in your didUpdateLocations
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
_currentLocation = [locations objectAtIndex:0];
//do your stuff with the location
}