Basically half the time the delegate method
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
is not called at all. But the other half of the time it works perfectly! I've found that it usually happens when I first start up Xcode after closing and quitting it, but then after that or a couple runs after that it seems to work fine. I'm not 100% sure if it's just an Xcode problem or what, I'll be getting a developer's license soon so I'll see if it will work fine on an actual device.
Starting from the viewDidAppear (tried in viewDidLoad also, made no difference), I run a method to init my locationManager stuff:
locationManager = [[CLLocationManager alloc]init];
[locationManager setDelegate:self];
locationManager.distanceFilter = 20.0f;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.pausesLocationUpdatesAutomatically = NO;
if ([locationManager respondsToSelector:#selector(requestAlwaysAuthorization)])
[locationManager requestAlwaysAuthorization];
[locationManager startUpdatingLocation];
Sometimes this works, sometimes it doesn't. I even made a timer to re-run this every so-and-so seconds, and this doesn't work.
Is there something else I should do? Is there any answer to this problem?
Thanks.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
This delegate method is invoked only if new locations are available. Sometimes gps will not get satellite signal hence locations cannot be obtained. So in these situations the above mentioned method will not get triggered. Since you are testing in simulator,you should change or set the location. I think it will work fine on an actual device.
add in viewdidappear
_locamangr = [CLLocationManager new];
_locamangr.delegate = self;
// _locamangr.distanceFilter = kCLDistanceFilterNone;
_locamangr.desiredAccuracy = kCLLocationAccuracyBest;
if ([_locamangr respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[_locamangr requestAlwaysAuthorization] ;
[_locamangr requestWhenInUseAuthorization];
}
[_locamangr startUpdatingLocation];
and set in infoplist.
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
Related
I have a bluetooth device that triggers location services in my app when a button is pressed. And location services do run, but only for about 8 seconds. I have an NSLog outputting Location Found in the didUpdateToLocation delegate method. It outputs that NSLog for only that 8 seconds.
When I put the app in the foreground, location services continue again. Here is how I initialize the location manager:
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
[self.locationManager requestAlwaysAuthorization];
[self.locationManager requestWhenInUseAuthorization];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager setAllowsBackgroundLocationUpdates:YES];
[self.locationManager allowsBackgroundLocationUpdates];
When button is pressed, I run this:
[self.locationManager startUpdatingLocation];
You need enabling the background mode (location), as long as your location-manager is capable to receive location-updates, your app will receive all bluetooth data.
As #Paulw11 mentioned in comments, using significant-location-updates will drastically reduce battery usage.
Here is the link to Apple guide.
Here is the link to a question related to getting location updates in background.
I am developing the IOS app with location server. In the app I am checking the user location periodically, and send the location details to the server.
Following are the steps:
1: App registers for location updates( in plist).
2: added the code like:
-(void)startUpdating{
locationManager = [[CLLocationManager alloc]init];
locationManager.delegate = self;
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
locationManager.pausesLocationUpdatesAutomatically = YES;
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
locationManager.distanceFilter = kCLDistanceFilterNone;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
dispatch_async(dispatch_get_main_queue(), ^{
//call web service location
[self UpdateAppmyLocation:#"1"];
});
[locationManager allowDeferredLocationUpdatesUntilTraveled:200 timeout:(NSTimeInterval)90];
}
- (void)applicationWillResignActive:(UIApplication *)application
{
[locationManager startUpdatingLocation];
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[locationManager stopUpdatingLocation];
}
3: startUpdating method called in didFinishLaunchingWithOptions.
Everything is working, but the didUpdateLocations:locations method called every minute. I am trying to add delay for some time so it will not lead to battery issue.
Note: Testing the app on iPhone 5 with iOS 7.1
Please let me know the solution.
https://github.com/voyage11/Location
Use this code.you can set time after how much time you want to call it.
I have tried many codes, but i found this as most accurate and list battery issue.This is also awesome for background location service.
Since I updated to iOS SDK 8 and 8.1, there have been many problems, including that the method of CLLocationManager didUpdateLocations is no longer called.
Here the code:
In viewDidLoad:
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
[locationManager requestAlwaysAuthorization];
}
[locationManager startUpdatingLocation];
The method:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{ NSLog(#"Call?"); }
A couple of thoughts:
Are you testing this on simulator or on device? You must test this on actual device. FWIW, didUpdateLocations works fine on my iOS 8.1 device.
Make sure that you specified the NSLocationAlwaysUsageDescription string or else the app won't present the authorization message, and you won't be authorized.
Obviously, if you don't need "always usage", you should just requestWhenInUseAuthorization and then you must specify NSLocationWhenInUseUsageDescription string.
Have you checked [CLLocationManager authorizationStatus]? I do that before I even try to authorize or start location services, because if it's either kCLAuthorizationStatusDenied or kCLAuthorizationStatusRestricted, the location services won't work until the user goes to settings and remedies that. You may want to present them a message to that effect if you get either of these authorization codes.
Have you implemented locationManager:didFailWithError:? Does it report anything?
Have you implemented locationManager:didChangeAuthorizationStatus:? Are you getting this called with a successful authorization status?
Need include MapKit.framework from Capabilities:
I had the same problem, and my code (viewdidupdate method) was missing this:
_mapView.delegate = self;
For some reason the app worked in ios 7 without the line, but in ios 8.1 didUpdateUserLocation was never called.
Specify both NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription in your plist:
Also in code, request authorization:
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) { // or requestAlwaysAuthorization
[self.locationManager requestWhenInUseAuthorization]; // or requestAlwaysAuthorization
}
[self.locationManager startUpdatingLocation];
Spent few days trying to solve this but unable to find any solutions that works. I have checked all the post on stackoverflow and tried all their solutions and nothing seems to be working for. I have also tried the apple test project for CLLocation which works fine for me. I used bits and pieces from the apple test project
https://developer.apple.com/library/ios/samplecode/LocateMe/Listings/README_md.html
But my code is not working at all. The DidupdateToLocation never gets called.
Here is my code (in viewDidLoad)
_locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// This is the most important property to set for the manager. It ultimately determines how the manager will
// attempt to acquire location and thus, the amount of power that will be consumed.
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// Once configured, the location manager must be "started"
//
// for iOS 8, specific user level permission is required,
// "when-in-use" authorization grants access to the user's location
//
// important: be sure to include NSLocationWhenInUseUsageDescription along with its
// explanation string in your Info.plist or startUpdatingLocation will not work.
//
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
[self performSelector:#selector(stopUpdatingLocationWithMessage:)
withObject:#"Timed Out"
afterDelay:30];
I have checked to make sure locationServicesEnabled is enabled.
I have added NSLoationWhenInUseUsageDescription property to the info.plist file. Is there any other property I need to add or enable any services??
I cannot for the love of god figure out what i have done wrong. Can some one please help me with this.
You have to call the startUpdatingLocation after you received the didChangeAuthorizationStatus callback on iOS8.
//iOS 8 API change
if([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]){
[self.locationManager requestWhenInUseAuthorization];
}else{
[self.locationManager startUpdatingLocation];
}
implement this delegate method:
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
switch (status) {
case kCLAuthorizationStatusNotDetermined:
case kCLAuthorizationStatusRestricted:
case kCLAuthorizationStatusDenied:
{
// do some error handling
}
break;
default:{
[self.locationManager startUpdatingLocation];
}
break;
}
}
First, don't forget, with IOS 8 you need to do [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;
//and the problem with your code : don't forget to start
_locationManager startUpdatingLocation];
and in your didUpdateLocations
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
_currentLocation = [locations objectAtIndex:0];
//do your stuff with the location
}
Silly me. I added the keywords to the wrong plist file. I have got it working now. Thanks for your help guys.
I just spend an entire morning on this [in honestly I am relative new OOC], anyway the problem..
didUpdateLocation compiles and is never called
didUpdateLocations compiles and does work!!
Not the answer in this case it would seem, but it is in the question, an easy mistake to make. Using IOS 8.1.3 & Xcode 6.1.1
Simply add three properties in Info.plist.
To get the current location, if it is not calling didUpdateToLocation method
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
privacy - location usage description of type String.
I'm trying to build an app that gives GPS coordinates on regular time intervals for display on a label and for sending to a web server, but it's proving difficult. I've managed to get it to give me accurate live GPS coordinates, but I have to press a button to get the label to refresh.
I figure the didUpdateLocation method is an ok place for this for now, but it seems to never run. I'm testing this by including an NSLog post - when I do this with Apple's LocateMe example app it runs like it should.
Below is my method:
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
theLocation = [NSString stringWithFormat:#"latitude: %f
longitude: %f", locationManager.location.coordinate.latitude,
locationManager.location.coordinate.longitude];
NSLog(#"location manager did something!!!");
}
Though I'm guessing that the issue lies with something outside of the above method. I suppose I should include my viewDidLoad method as that's where I startUpdatingLocation:
- (void)viewDidLoad
{
[super viewDidLoad];
locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
[outletLabelData setText:(#"Loaded")];
}
I've also tried having the startUpdatingLocation in my button action method, and even having it work like a switch where you start and stop the updates (which should trigger the update event), but still no success.
Other details:
Xcode 4.4
iOS 5.1
Testing app on my iPhone while plugged into my mac
Can anyone help with this?
You need to tell your CCLocationManager who is the delegate. In your case it is your current controller.
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
and obviously make sure that your controller conforms to CLLocationManagerDelegate protocol.