Location authorization issue in Objective C - objective-c

I have an issue showing user locations in objective C.
I tried everything i could find here in stackoverflow, aaaand, didn't work.
So I have that code :
-(void)setLocation
{
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
MKPointAnnotation *myAnnotation = [[MKPointAnnotation alloc]init];
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
locationManager.distanceFilter = 10.0;
[locationManager startUpdatingLocation];
[locationManager requestWhenInUseAuthorization];
[locationManager requestAlwaysAuthorization];
myAnnotation.coordinate = mapView.userLocation.location.coordinate;
myAnnotation.title = #"Test";
myAnnotation.subtitle = #"I am a test Subtitle";
[self.mapView addAnnotation:myAnnotation];
}
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
[self.mapView setCenterCoordinate:userLocation.coordinate animated:YES];
}
Everything is in ViewController.m, more precisely in a mapView declared in my .h file:
#property (strong, nonatomic) IBOutlet MKMapView *mapView;
Does anyone have any idea ? The error i have is that:
Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.
Thanks :)

I can't post this as a comment so i'll post it here.
You can simply open your Info.plist file in TextEdit and add these lines.
<key>UIBackgroundModes</key>
<array>
<string>location</string>
<string>external-accessory</string>
<string>remote-notification</string>
</array>
<key>NSLocationUsageDescription</key>
<string>App needs to use GPS to keep track of your activity</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>App needs to use GPS to keep track of your activity</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
<string>gps</string>
</array>
EDIT:
I see that your locationManager is a local method variable. It should declared be as an instance variable or as a property.

Look at the following lines
[locationManager startUpdatingLocation];
[locationManager requestWhenInUseAuthorization];
[locationManager requestAlwaysAuthorization];
An error says that you just started the location updates without prompting for location authorization.
Your starting the location update before prompting for the location authorization. So just order of these lines is wrong.
1) Prompt user for location update
2) And then start update location
So your code should be in following order.
//1
[locationManager requestWhenInUseAuthorization];
[locationManager requestAlwaysAuthorization];
//2
[locationManager startUpdatingLocation];
Don't forget to add NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription key in Info.plist

Related

objective c find out my location?

I'm trying to get my location in simulator. A couple of time it worked but... Now I always get 0.000000 as my location. There is code that I used:
#import <CoreLocation/CoreLocation.h>
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
[locationManager startUpdatingLocation];
CLLocation *location = [locationManager location];
CLLocationCoordinate2D coordinate = [location coordinate];
NSLog(#"%f",location.coordinate.latitude);
NSLog(#"%f",location.coordinate.longitude);
After running app I change in the simulator Debug -> Location -> Custom Location... Does somebody can explain why does it stop working?
This will never work, except by accident:
[locationManager startUpdatingLocation];
CLLocation *location = [locationManager location];
When you call startUpdatingLocation you get delegate messages (assuming you have a location manager delegate, which you should, always) — in particular, locationManager:didUpdateLocations:. That is where you receive information about your location.

Latitude and Longitude 0 when called second time in Objective-C

I am using the below code to get coordinates on click of a button
-(CLLocationCoordinate2D) getLocation{
CLLocationCoordinate2D coordinate;
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
if ([CLLocationManager locationServicesEnabled]) {
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
[locationManager startUpdatingLocation];
CLLocation *location = [locationManager location];
coordinate = [location coordinate];
}
else {
coordinate.latitude = 0.0;
coordinate.longitude = 0.0;
}
return coordinate;
}
When the button is clicked for the first time, I do get my valid coordinates, but if I click the button again, The latitude and longitude values are 0.0000
Any suggestions
Please initialize the CLLocationManager outside the method.Take the You can initialize in viewdidload method.
It may helps to you
You cannot expect [locationManager location] to return anything useful immediately after activating a location manager with [locationManager startUpdatingLocation] .
CLLocationManager takes time to acquire a location. You need to set the CLLocationManager's delegate (eg, to 'self') and then use the delegate method - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations; to get notified when the location manager has got a location that you can use.
See: https://developer.apple.com/reference/corelocation/cllocationmanagerdelegate/1423615-locationmanager?language=objc
(If you only want one location, and not a continuous stream of location updates, instead of calling 'startUpdatingLocation' call [locationManager requestLocation] - but even then you still need to use the delegate method to be notified when a location has been acquired).
You need to split out the code for creating and starting the location manager to where it is only run once (only need one location manager for the app) - eg, viewDidLoad. Then the rest of the code, to process the locations acquired, should go in the delegate method.
In reality, if you want you button click to have a location immediately, you need to have your location manager running and updating locations before your button is available to be clicked. Eg, make your button enabled=NO and when you start getting locations via the delegate method, set the button enabled=YES.

Why requestWhenInUseAuthorization doesn't prompt the user for access to the location?

In my viewDidLoad method I have
locationManager = [[CLLocationManager alloc]init]; // initializing locationManager
locationManager.delegate = self; // we set the delegate of locationManager to self.
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
if([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
[locationManager requestWhenInUseAuthorization];
}
And the request is called, but the user is not prompted? Why?
You probably need to update your plist file. Here's a tutorial how to do it, quick & dirty:
You need to do is to add one of the following keys to your Info.plist file:
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
You also need to request authorization for the corresponding location method, WhenInUse or Background. Use one of these calls:
[self.locationManager requestWhenInUseAuthorization]
[self.locationManager requestAlwaysAuthorization]
There's also a post that I found helpful:
Location Services not working in iOS 8
This answer details how to update your plist file:
Add one of the following lines to your info.plist
<key>NSLocationWhenInUseUsageDescription</key>
<string>The spirit of stack overflow is coders helping coders</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>I have learned more on stack overflow than anything else</string>
You'll probably want to customize and spell-check the strings of the dictionary entry that goes in the info.plist file before shipping the code.

CoreLocation , MapKit Error

I Tried To Show My Current Location In Mapkit and this is code
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//Make this controller the delegate for the map view.
self.MapView.delegate = self;
// Ensure that you can view your own location in the map view.
[self.MapView setShowsUserLocation:YES];
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
}
and I wrote This Delegate Of Mapkit
#pragma mark - MKMapViewDelegate methods.
- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views {
MKCoordinateRegion region;
region = MKCoordinateRegionMakeWithDistance(locationManager.location.coordinate,2000,2000);
[mv setRegion:region animated:YES];
}
But I Get Wrong Location Iam In Egypt And This Give ME iam in UnitedStates
Any One Can Hep ME ???
Just in case: if you are using the simulator, the position will not be your real position. You have to set your location in the simulator:
Debug -> Location -> Custom Location (or anything else)
First of all.
You didnt used
[locationManager startUpdatingLocation];
Please add this line after you initiate the location manager variable. Also please let me know if you are seeing this location USA in Simulator.
If it is: Your simulator simulates the location given by user preferences. Get to the simulator window, there you'll get the option to show custom location as per your selection. By default it is selected as USA.
Hope it resolves your issue.

Scope of an object, objective-c, CLLocationManager

I'm still pretty new to programming so I have somewhat of a noob question. When you have an instance variable, in my case of type CLLocationManager, in my appDelegate.m file, I thought I could allocate and initialize my CLLocationManager instance variable in the applicationDidFinishLaunching method. And then I could use a button to startUpdatingLocation in a different method (since I'm calling it from another class). This doesn't seem to work and I'm thinking that I needed to alloc/init in the same method I startUpdatingLocation. Is that true? Do I need to stopUpdatingLocation in the same method? My code is below:
(locationManager is declared as a property)
- (void)stopUpdating {
[locationManager stopUpdatingLocation];
}
- (double)distanceTraveled {
return distanceTraveled;
}
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after application launch
[window addSubview:rootController.view];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[window makeKeyAndVisible];
}
- (void)startUpdating {
[locationManager startUpdatingLocation];
}
It seems like I should be doing it more like:
- (void)startUpdating {
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
If I am supposed to do it this second way, is it because that the scope of the CLLocationManager object is only for the method it is in? I thought having it as an instance variable I would be able to use it in other methods and I could have a separate method for startUpdatingLocation and stopUpdatingLocation. Thanks.
What you originally thought is correct. If you have an instance variable that variable remains available to you throughout the life of the object (in this case your app delegate).
If what you're doing isn't working, it's because of some other issue. you don't need to allocate a new CLLocationManager each time you call startUpdating.