Location services issue in Xcode 8 - ios

I m using location delegate methods to get the current location of the user.Everything is working fine when i debug it using xcode 7.3 but when I debug it using latest Xcode 8 and turn off location service from settings,in that case the pop up of location service disable and pop up to ask permission to get the location continuously appears on the screen and it freezes the app screen until the phone is restarted.
This is the code in AppDelegate class
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
NSLog(#"locationManager didUpdateLocations: %#",locations);
for(int i=0;i<locations.count;i++){
CLLocation * newLocation = [locations objectAtIndex:i];
CLLocationCoordinate2D theLocation = newLocation.coordinate;
CLLocationAccuracy theAccuracy = newLocation.horizontalAccuracy;
self.myLocation = theLocation;
self.myLocationAccuracy = theAccuracy;
}
if (self.shareModel.afterResume==TRUE) {
appStatus=#"Killed";
self.locationTracker = [[LocationTracker alloc]init];
self.locationTracker.str_latitude=[NSString stringWithFormat:#"%f",self.myLocation.latitude];
self.locationTracker.str_longitude=[NSString stringWithFormat:#"%f",self.myLocation.longitude];
self.locationTracker.pushStatus=FALSE;
[self.locationTracker GetDevice_LocationSettings];
}
}
These two pop up comes one after another and doesn't allow to do any other action.

Related

iPhone Getting the wrong coordinates from the GPS

IOS10 on iPhone 6 Plus.
A small app app that grabs the gps coordinates and sends them to a remote web service. On the iphone map the user location is showing correctly, but the retrieved coordinates:
location.coordinate.latitude,
location.coordinate.longitude
are 0.5 miles away from where the map says I am! This is consistent wherever I move to.
I am following Apple's best practices and using the delegate method as follows: and it's these coordinates that are incorrect.
// Delegate method from the CLLocationManagerDelegate protocol.
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
CLLocation* location = [locations lastObject];
NSDate* eventDate = location.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) < 15.0) {
// Log the data
NSLog(#"latitude %+.6f, longitude %+.6f\n",
location.coordinate.latitude,
location.coordinate.longitude);
}
}
I am setting the location accuracy as follows:
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
I sample the gps coordinates for 30 seconds to make sure i am getting the best accuracy possible.
I have tried this on 2 different iPhones, both showing the same issue.
Thanks in advance.
I finally found out what is causing the problem..
I am currently in China... and that is the reason for the mysterious offset.. the maps in China are 'offset'.
If you are interested there's an post about it here that has saved me from tearing my hair out.
http://www.sinosplice.com/life/archives/2013/07/16/a-more-complete-ios-solution-to-the-china-gps-offset-problem.
China uses a mapping projection called GCJ-02 which is different from the West's mapping standard (WGS-84). So if you're ever developing a mapping system, you might want to take this into account for travellers in China!
Thanks anyway for the useful pieces of coding advice.
You can add a check in your method to update locations again until you are down to your desired accuracy:
// Delegate method from the CLLocationManagerDelegate protocol.
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
// You can check for either locationManager.desiredAccuracy or a value you'd like in meters
CLLocation* location = [locations lastObject];
if (location.horizontalAccuracy > locationManager.desiredAccuracy) {
//Do nothing yet
return;
}
NSDate* eventDate = location.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) < 15.0) {
// Log the data
NSLog(#"latitude %+.6f, longitude %+.6f\n",
location.coordinate.latitude,
location.coordinate.longitude);
}
}

Get user Coordinates in iOS simulator at the app launch

I was asked to code a small app for iOS in Objective C that's supposed to choose the closest object of a user, in a set of coordinates
The plan was to load the coordinates of the user only once, when the application loads for the first time.
Here's my current code :
(void)viewDidLoad {
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.headingFilter = 1;
self.locationManager.delegate = self;
self.locationManager.distanceFilter = kCLDistanceFilterNone;
[self.locationManager startUpdatingLocation];
self.userLat = self.locationManager.location.coordinate.latitude;
self.userLon = self.locationManager.location.coordinate.longitude;
NSLog(#" ----------------------------- ");
NSLog(#"User lat : %lf", self.userLat);
NSLog(#"User lon : %lf", self.userLon);
NSLog(#" ----------------------------- ");
}
I don't have a Apple iOS developper program, so I'm stuck with the iOS simulator from xCode.
I try to set some custom coordinates in the iOS simulator through debug, like this :
When i execute the app (obviously after setting coordinates), the log has userLat and userLon to 0.00..
Apr 6 03:16:20 Locals-Mac.local app[5683]: -----------------------------
Apr 6 03:16:20 Locals-Mac.local app[5683]: User lat : 0.000000
Apr 6 03:16:20 Locals-Mac.local app[5683]: User lon : 0.000000
Apr 6 03:16:20 Locals-Mac.local app[5683]: -----------------------------
I remember hearing somewhere that the iOS simulator don't work with the CoreLocation library (It might be right or wrong, i wouldn't know).
Is it the reason the lat/lon values are 0?
If the reason is indeed the iOS simulator, does this code give user current location?
Thanks in advance!
Edit :
With the answer and comments, i'm now using the didUpdateLocations callback function :
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation *location = [locations lastObject];
self.userLat = location.coordinate.latitude;
self.userLon = location.coordinate.longitude;
NSLog(#" ----------------------------- ");
NSLog(#"User lat : %lf", self.userLat);
NSLog(#"User lon : %lf", self.userLon);
NSLog(#" ----------------------------- ");
}
I ask xCode to simulate my position to London with the Scheme option that follows :
My new load function :
-(void)viewDidLoad {
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.headingFilter = 1;
self.locationManager.delegate = self;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
[self.locationManager requestWhenInUseAuthorization];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
[self.locationManager startUpdatingLocation];
}
This code still doesn't print the NSLog that was put in the location callback function. Did i miss something?
The location manager doesn't instantly have the user's location when you start updating it. If you check the location property right after calling startUpdatingLocation it is usually going to be nil unless some other app was recently updating it. You need to implement the locationManager:didUpdateLocations: delegate method which will be called once it has a location.
You also need to check and possibly request for location permissions.

Core Location can't get data in viewDidLoad

I wrote a simple iOS application that retrieves location information and then uses the location to request Yahoo Weather.
The problem is that even when I call the Core Location in the viewDidLoad, it won't give me the result immediately.
So why can't I get the location information?
How can I get the location information in viewDidLoad?
The pseudocode currently is something like:
- (void)viewDidLoad
{
[super viewDidLoad];
self.locManager = [[CLLocationManager alloc] init];
self.locManager.delegate = self;
self.locManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locManager.distanceFilter = 100;
[self.locManager startUpdatingLocation];
//won't get the current location right now, so the output will be null
NSLog(#"Current Location Longitude: %#", self.longitudeString);
NSLog(#"Current Location Latitude: %#", self.latitudeString);
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *newLocation = [locations lastObject];
self.longitudeString = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.longitude];
self.latitudeString = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.latitude];
}
Location updates are not provided as instantly as you are expecting, you need to wait few seconds (2-3 or may be more) to get precise location update. If you want to have location data in viewDidLoad then you should init your location manager (and call startUpdatingLocation) before invoking the ViewController (since then it is not guaranteed that you will have location-data in viewDidLoad).

Altitude is always zero on iPhone simulator

I'm trying to develop an Altimeter on Xcode and Simulator but it always return 0 for the height above the sea.
I don't understand why, I've tried with a lot of places on Simulator.
My code is this:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
_mapView.delegate = self;
_locationManager = [[CLLocationManager alloc] init];
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
_locationManager.pausesLocationUpdatesAutomatically = YES;
_locationManager.delegate = self;
firstLocation = YES;
checkUserLocation = NO;
}
- (void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
CLLocation *location = [locations lastObject];
lastLocation = location.coordinate;
_latitudeLabel.text = [NSString stringWithFormat:#"Current latitude: %f", location.coordinate.latitude];
_longitudeLabel.text = [NSString stringWithFormat:#"Current longitude: %f", location.coordinate.longitude];
_altitudeLabel.text = [NSString stringWithFormat:#"Current altitude: %f m", location.altitude];
}
Where is my error?
There's nothing wrong with your code, its because you are using the simulator.
Determining altitude requires a device with GPS capabilities, and you also need to be using GPS on that device in order to get it (wifi only location would not report altitude correctly even on GPS-enabled devices). The iOS simulator does not have those capabilities so altitude will not be accurate there. You will need to use a real device with GPS to get altitude measurements.
If you want to simulate a CLLocation with altitude you can create your CLLocation object and pass it an altitude yourself:
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate
altitude:(CLLocationDistance)altitude
horizontalAccuracy:(CLLocationAccuracy)hAccuracy
verticalAccuracy:(CLLocationAccuracy)vAccuracy
timestamp:(NSDate *)timestamp
Altitude is a readonly property so you will need to create a new CLLocation object yourself instead of changing it manually when you receive a CLLocation object in your delegate callback.

Core Location does't update the significant location changes

In my app(Deployment Target 5.1), i am using CoreLocation to setup a reminder feature, it will basically search the nearby items(have location attached) as device update its current location.
This feature is not working very stable at this stage, sometimes it just doesn't works at all regardless of whether device is in active, suspended and terminated states. i realized that the delegate method locationManager:didUpdateToLocation:fromLocation: didn't get call.
Is there anybody can point me a direction to make this thing work properly?
Here is my setup for the CLLocationManager
sharedLocationManager = [[CLLocationManager alloc]init];
[ESLocationManager defaultManager].delegate = someDelegateClassInstance;
[[ESLocationManager defaultManager] setDesiredAccuracy:kCLLocationAccuracyHundredMeters];
[[ESLocationManager defaultManager] startMonitoringSignificantLocationChanges];
And the implementation of the delegate callback
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
// If it's a relatively recent event, turn off updates to save power
NSDate* eventDate = newLocation.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) < 20.0) {
// If the event is recent,find nearby items.
NSLog(#"latitude %+.6f, longitude %+.6f\n",
newLocation.coordinate.latitude,
newLocation.coordinate.longitude);
//reload nearby list
NSArray *nearbyItems = [self nearbyItemsForLocation:newLocation];
if (nearbyItems && nearbyItems.count ) {
UIApplicationState appState = [[UIApplication sharedApplication] applicationState];
if (appState != UIApplicationStateActive) {
[[UIApplication sharedApplication] presentLocalNotificationNow:[self localNotificationForItems:nearbyItems]];
}
}
}
}
Similar reason to this forum with region monitoring
https://devforums.apple.com/message/251046#251046
Hope this helps

Resources