GPS signal is lost when App is resumed from long time suspend mode.
And/or after user goes into a building where GPS is weak and then resumes the App.
The blue dot disappears and the map is centered at lat:0 long:0 ( which is somewhere in
the ocean near Nigeria-Africa )
If you launch another GPS app at that point in time, such as Apple Maps,
you DO see the blue dot, even if not so accurate.
The only way a user can fix it - is by killing my app completely and start it again.
It happens on both iOS 5.x and iOS 6.x.
Before going into details, I would really like to ask:
Does anyone encounter this problem ??
Its very annoying but, I couldn't find anyone complaining about this
anywhere on the web - very weird.
I'm using normal CLLocation with showUserLocation=YES,
Nothing magical, no special accuracy tuning or whatever, just simple default
implementation.
I have already tried restarting every possible component when App is resumed;
showUserLocation=NO;
showUserLocation=YES;
or
[locationManager stopUpdatingLocation];
[locationManager startUpdatingLocation];
or
even releasing locationManager and initialize it again doesn't help!
( also tried restarting it with a delay using dispatch_after )
Is there any programmatic way to force RESET the GPS signal or CLLocation in ios ?
Will appreciate any relevant discussion!
I Think you default Location is set "None" so this type of issue created.
Go to
Edite Scheme..
|
|
"Run YourProjectName" / Left Hand Side
|
|
Select "Option" Tab
|
|
Default Location
|
|
Choose any Location such like , "London England"
When you say that you've tried stopping/starting the CLLocationManager object, are you saying that the call-back you get in your delegate gives you a 0,0 coordinate, or are you trying to access the location directly using the location property in CLLocationManager?
I work on a location based app and one thing I can tell you is that you cannot count of directly getting the location of a CLLocationManager object. The only reliable way to get location information is to rely on the callback of the CLLocationManager class by implementing
-(void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
The way I handle CLLocationManager in my app (now I'm not saying this is optimal or ideal for your use case but it does allow us to provide a solid location-based experience to the user on app launch/resume)
Wrap the CLLocationManager into a location management class (usually using a singleton) - I think this can be a subclass of CLLocationManager but in my case it's just a subclass of NSObject with a CLLocationManager object as a property
Store the last known valid location in this singleton, and then write it to disk (NSUserDefaults or another location - need to re-check if you're allowed to store user location in NSUserDefaults but we've done it in our app and doesn't seem to affect the approval process)
Re-implement a way to get the current location in your custom class - basically check if CLLocationManager is returning 0,0 and if it is, return your cached position instead
Not strictly necessary but if you have multiple views/pages that need to use the location, implementing the observer model works well (since your singleton is now CLLocationManager's delegate, you need to have a way to pass this information on to your view controllers).
With the above, on my map page (or wherever I'm displaying user location) - I basically update the map with the cached location once (in viewDidLoad) and then I allow one update to the map through the delegate-callback. Once that call-back is received, I then set showsUserLocation to YES (if the call-back isn't called, then you don't have a valid location yet and so setting showsUserLocation at that point doesn't do anything).
I hope this helps and feel free to let me know if you have any further questions!
Related
I have tried the significant location change in the latest iOS 8 update but the Core Location manager method
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
is never called.
When using method startUpdatingLocation the method above is called.
Everything worked in iOS 7 for the app. I need to update to iOS 8.
Share your experience.
I'm going to guess that you're not following the instructions here:
https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLLocationManager_class/index.html#//apple_ref/occ/instm/CLLocationManager/startMonitoringSignificantLocationChanges
Events are going to be accumulated while your app is not running. Your app launches and must immediately create a location manager and start significant location updates all over again in order to receive that accumulated information.
If you are updating to iOS 8 be sure to make the changes in the property list (.plist) file: NSLocationWhenInUseUsageDescription and/or NSLocationAlwaysUsageDecription : http://matthewfecher.com/app-developement/getting-gps-location-using-core-location-in-ios-8-vs-ios-7/
I want to attach a listener in IOS which is invoked whenever GPS is turned ON or OFF from settings. Listener should be invoked no matter my application is running, in background or has been stopped. I have this functionality that i need to keep GPS settings of a user who has installed app, on server side, so whenever GPS is changed i must notify the server.
I guess there isn't any listener,
You can Use Delegate method of CLLocationManager.
Use this delegate method for getting location - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
Form this [locations lastObject] you can latest location send location to server.
You can not get location when app is stopped.
As of now, there is no such notification exists.
However you can create and start a timer (NSTimer) that will regularly poll whether GPS is enabled or not, using 'CLLocationManager locationServicesEnabled' method.
Within your class, you can have a bool iVar that will be set / reset based on return value. Whenever its value is altered, you can notify server about service start / stoppage.
I have an iOS app that uses the CLLocationManager to monitor regions and to get GPS updates. Most of the time, I want my app to continue tracking the cellphone when it goes in background or even when it gets killed, and it works well (I can still see the small arrow in the status bar after my app gets killed). The problem is that I am not able to stop monitoring the regions and GPS updates after my app has been restarted by the Location Services.
When my app gets restarted by the Location Services, I instanciate the CLLocationManager and then call its methods stopRangingBeaconsInRegion and stopUpdatingLocation before setting its delegate to nil and itself to nil.
Thanks to NSLogger, I can see that my callbacks are no longer called, but the small arrow in the status bar stays there (and my app is the only one that I allowed to use the Location Services from the settings menu).
What did I miss? Is there a way to know what still uses the Location Services in my app?
When you call stopRangingBeaconsInRegion, where are you getting the list of regions? The proper way to do this is like below:
for (CLRegion *monitored in [self.locationManager monitoredRegions]) {
NSLog(#"Stopping monitoring on: %#", monitored.identifier);
[self.monitoringLocationManager stopMonitoringForRegion:monitored];
}
for (CLBeaconRegion *region in [self.locationManager rangedRegions]) {
NSLog(#"Stopping ranging on: %# ", region.identifier);
[self.rangingLocationManager stopRangingBeaconsInRegion:region];
}
I finally found that I missed to remove some of my numerous regions. The easy way to avoid this mistake is to retrieve the list of regions monitored with the property monitoredRegions and call stopRangingBeaconsInRegion for each of them. I also forgot to call stopMonitoringSignificantLocationChanges (I didn't know that my app was using it, since I am modifying the app of a former colleague).
How do you know that it is your app that is using the location services?
The small arrow appears if the iOS itself is using the location services in the background.
if you did call stopRangingBeaconsInRegion and stopUpdatingLocation before setting the delegate to nil and you are not getting any callbacks then your app is not using the location services.
To get the last know geolocation, I have:
CLLocationManager * locationManager = [[CLLocationManager alloc] init];
CLLocation * lastKnownLocation = [locationManager location];
Does the lastKnownLocation reflect the last location my app has been called back with or does it reflect a global iOS system level last location (which other app or the iOS might have queried for)?
I am doing this instead of actively querying for user's location so I don't waste the user's battery.
If user has not given permission to access location, obviously lastKnownLocation should be nil. My question is specifically for the case where user has given my app permission to access location.
Generally you should not simply rely on the existing (if any) value returned from location unless you check its accuracy and time stamp (compared to your requirements). It's better to start startUpdatingLocation until you get a location which does match your accuracy requirements and then either stopUpdatingLocation or switch to stopMonitoringSignificantLocationChanges (if available).
The location returned from location is very dependent upon history, so you can't definitely say one way or the other that it will be. You always need to verify the accuracy for your purposes.
I know this is an old question but for the sake of being complete and maybe others ending up here:
The CLLocationManager class has the location property which returns (according to official Apple docs):
The most recently retrieved user location.
This method will return nil when no location is known.
I asked a question regarding how to get old location from this:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
And I got reply
You should create and use a mutable array of previous
locations that were updated from previous calls to "locationManager:
didUpdateLocations:".
Link
Now I am confused regarding that in Location Awareness guide Apple says this:
If a location update has already been delivered, you can also get the
most recent location data directly from the CLLocationManager object
without waiting for a new event to be delivered.
I am not getting this point. Please help me out.
If you look at Apple's documentation for CLLocationManager, you'll see it has a property you can access that's named "location".
This property contains the last reported location data.
And whenever new locations gets resolved & reported, that property should presumably be updated.
In general though, you'll want to keep your users up-to-date on the current location via updates passed through the delegate methods.