Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 8 Map Kit Obj-C Cannot Get Users Location

I am working with Map Kit in iOS 8 using Obj-C NOT SWIFT. I cannot get the device location it is set a 0.00, 0.00 and I am getting the error:

Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first. 

I have implemented: ( I have tried only one at a time and no luck )

if(IS_OS_8_OR_LATER) {     [self.locationManager requestWhenInUseAuthorization];     [self.locationManager requestAlwaysAuthorization]; } [self.locationManager startUpdatingLocation];  

And in info.plist

NSLocationWhenInUseUsageDescription  :   App would like to use your location. NSLocationAlwaysUsageDescription  :  App would like to use your location. 

I do get prompted to allow the app to use my location but after I agree nothing changes. The location is being showed as 0.00, 0.00.

Code for displaying users location:

//Get Location self.locationManager = [[CLLocationManager alloc] init]; self.locationManager.distanceFilter = kCLDistanceFilterNone; self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; [self.locationManager startUpdatingLocation];  MKCoordinateRegion region = { { 0.0, 0.0 }, { 0.0, 0.0 } }; region.center.latitude = self.locationManager.location.coordinate.latitude; region.center.longitude = self.locationManager.location.coordinate.longitude; region.span.longitudeDelta = 0.005f; region.span.longitudeDelta = 0.005f; [mapView setRegion:region animated:YES]; 

Mike.

**EDIT: View Answer Below.

like image 282
MBarton Avatar asked Jul 12 '14 21:07

MBarton


2 Answers

I got it working. I've posted my code below to help anyone else having issues.

Here is my full code to get the MapKit Map View working in iOS 8.

In your AppName-Info.plist Add a new row with the key name being:

NSLocationWhenInUseUsageDescription 

Or

NSLocationAlwaysUsageDescription 

With the value being a string of the message that you want to be displayed:

YourAppName would like to use your location. 

In your header file. (I use App Name-Prefix.pch but YourViewController.h will work too)

#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) 

YourViewController.h

#import <MapKit/MapKit.h> #import <MapKit/MKAnnotation.h>  @interface YourViewController : UIViewController <MKMapViewDelegate,  CLLocationManagerDelegate> {  }   @property(nonatomic, retain) IBOutlet MKMapView *mapView; @property(nonatomic, retain) CLLocationManager *locationManager; 

YourViewController.m

- (void)viewDidLoad {     [super viewDidLoad];     // Do any additional setup after loading the view.       mapView.delegate = self;     self.locationManager = [[CLLocationManager alloc] init];     self.locationManager.delegate = self;     #ifdef __IPHONE_8_0     if(IS_OS_8_OR_LATER) {          // Use one or the other, not both. Depending on what you put in info.plist         [self.locationManager requestWhenInUseAuthorization];         [self.locationManager requestAlwaysAuthorization];     }     #endif     [self.locationManager startUpdatingLocation];      mapView.showsUserLocation = YES;     [mapView setMapType:MKMapTypeStandard];     [mapView setZoomEnabled:YES];     [mapView setScrollEnabled:YES]; }  -(void)viewDidAppear:(BOOL)animated {     [super viewDidAppear:YES];      self.locationManager.distanceFilter = kCLDistanceFilterNone;     self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;     [self.locationManager startUpdatingLocation];     NSLog(@"%@", [self deviceLocation]);      //View Area     MKCoordinateRegion region = { { 0.0, 0.0 }, { 0.0, 0.0 } };     region.center.latitude = self.locationManager.location.coordinate.latitude;     region.center.longitude = self.locationManager.location.coordinate.longitude;     region.span.longitudeDelta = 0.005f;     region.span.longitudeDelta = 0.005f;     [mapView setRegion:region animated:YES];  }  - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {     MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);     [self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES]; } - (NSString *)deviceLocation {     return [NSString stringWithFormat:@"latitude: %f longitude: %f", self.locationManager.location.coordinate.latitude, self.locationManager.location.coordinate.longitude]; } - (NSString *)deviceLat {     return [NSString stringWithFormat:@"%f", self.locationManager.location.coordinate.latitude]; } - (NSString *)deviceLon {     return [NSString stringWithFormat:@"%f", self.locationManager.location.coordinate.longitude]; } - (NSString *)deviceAlt {     return [NSString stringWithFormat:@"%f", self.locationManager.location.altitude]; } 

Enjoy!

--Mike

like image 101
MBarton Avatar answered Oct 15 '22 07:10

MBarton


It's not written anywhere, but if your app starts with MapKit, you will still receive the error message "Trying to start MapKit location updates without prompting for location authorization" even after implementing MBarton's answer. To avoid it, you have to create a new view controller before the MapKit, and implement the location manager delegates there. I called it AuthorizationController.

So, in AuthorizationController.h:

#import <UIKit/UIKit.h> #import <CoreLocation/CoreLocation.h>  @interface MCIAuthorizationController : UIViewController <CLLocationManagerDelegate>  @property (strong, nonatomic) CLLocationManager *locationManager;  @end 

And in AuthorizationController.m:

- (void)viewDidLoad {     [super viewDidLoad];      // Location manager     self.locationManager = [[CLLocationManager alloc] init];     self.locationManager.delegate = self;      // 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];     } }  #pragma mark - Location Manager delegates  - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {     NSLog(@"didUpdateLocations: %@", [locations lastObject]); }   - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {     NSLog(@"Location manager error: %@", error.localizedDescription); }  - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {     if (status == kCLAuthorizationStatusAuthorizedWhenInUse) {         [self.locationManager startUpdatingLocation];         [self performSegueWithIdentifier:@"startSegue" sender:self];     } else if (status == kCLAuthorizationStatusDenied) {         UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Location services not authorized"                                                         message:@"This app needs you to authorize locations services to work."                                                        delegate:nil                                               cancelButtonTitle:@"OK"                                               otherButtonTitles:nil];         [alert show];     } else         NSLog(@"Wrong location status"); } 
like image 26
Rodrigo Pinto Avatar answered Oct 15 '22 06:10

Rodrigo Pinto