This is my scenario: I need to get the user's current location punctually in order to show them a set of nearby points of interest in an MKMapView. I don't need to keep track of user's location. I need someone to clarify which the best way to do this should be:
1) ASFAIK, is it possible to get the current location by calling mapItemForCurrentLocation. You get an MKMapItem object, and I think that this call does not need to have the location services enabled, but I'm not sure if it is possible to get the coordinates for the location this way... is it?
2) Start a CLLocationManager and listen for location updates. And then just take the first location received and stop listening.
I need this to work for iOS 7+
Thanks
For an MKMapView object to be showing user location you will have to have requested authorisation for iOS8 (ie using requestWhenInUseAuthorization on a CLLocationManager object).
MKMapView objects have a didUpdateUserLocation: delegate method you could use receive user location updates, but this may fire off repeatedly until it reaches the accuracy the map requires - you might need to ignore later updates depending on what you're doing.
Based on your scenario it could be better to use CLLocationManger, then stop requesting updates once you have a fix of required accuracy.
Related
Is there any way or method for getting the source of location if it is coming from GPS or from Wifi?
Thanks.
Imho there is no way how to decide if signal comes from GPS or WIFI or whatever (this handles CoreLocation framework) - but you can still "decide" depending on current accuracy - the horizontalAccuracy property and verticalAccuracy property in CLLocation object.
In Significant change location service, I've used the method "startMonitoringSignificantLocationChanges" but it returns cached Location only, it doesn't return updated location information.
I've used Swift language.
Assuming you are keeping a strong reference to your location manager object, please ensure you are calling locationManager.requestAlwaysAuthorization() for startMonitoringSignificantLocationChanges to function well.
EDIT:
From Apple Documentation:
Regardless of which location service you use, location data is
reported to your app via the location manager’s associated delegate
object. Because it can take several seconds to return an initial
location, the location manager typically delivers the previously
cached location data immediately and then delivers more up-to-date
location data as it becomes available. Therefore it is always a good
idea to check the timestamp of any location object before taking any
actions. If both location services are enabled simultaneously, they
deliver events using the same set of delegate methods.
Wait for some time and ensure you make a physical location change for location manager to return back the right location. Note that Significant Location Changes mode is always slower than the regular one.
I am using Core Location for turn by turn based navigation and would like to show a "GPS lost" alert in tunnels.
The problem is that the following two scenarios look the same to the app:
The user drives into a tunnel. GPS updates cease because there is no way to know where the user is.
The user stops at an intersection. GPS updates cease because the user is no longer moving.
I need to set these two situations apart. Ideas?
I have tried looking at the horizontalAccuracy property, but sometimes the updates cease completely, so there is no new horizontalAccuracy information.
Normally with CLLocationManager set for best accuracy for navigation and no distance filter, you should get a location update once a second even if you are stopped at an intersection.
If you stop getting those updates while the motion coprocessor (using CMMotionActivityManager) says you are still driving then you can infer that you are in a tunnel (or underground car park or someplace with a bad GPS signal).
BTW, GPS updates should not stop when you are stopped at an intersection if you have set distanceFilter = 0 and desiredAccuracy = kCLLocationAccuracyBestForNavigation and activityType = CLActivityTypeAutomotiveNavigation, etc.
Another thing to watch out for, if the tunnel has cellular coverage, you may still get location update from cellular triangulation but with worse accuracy. If the CLLocation.horizontalAccuracy goes from less than 50m to over 300m then you have lost GPS/GLONASS coverage even though you are still getting location updates.
Look at locationManager:didFailWithError: method:
If the location service is unable to retrieve a location right away,
it reports a kCLErrorLocationUnknown error and keeps trying.
To determine a second situation (user stops) use locationManagerDidPauseLocationUpdates: method:
When the location manager detects that the device’s location is not
changing, it can pause the delivery of updates in order to shut down
the appropriate hardware and save power. When it does this, it calls
this method to let your app know that this has happened.
In iOS 8 the MKMapView requests by default the permission to track the user's location even when the app is in the background. Is there any way to change this, so as to request only the NSLocationWhenInUseUsageDescription permission?
I am not using a custom CLLocationManager, since I do not need it for anything else apart from displaying the user location on the map. Is it possible to avoid using a custom CLLocationManager?
I don't think you can use location without the user giving permission. Imagine the problems if everyone could just track a device location without the user's knowledge?
I need to get exact location (as much accurate as possible) in background while making a call to a phone number (The call will be made from app). As far as I understand from documentation, I can listen to significant changes of location in background. I am wondering how accurate is a significant update and when will it trigger.
I need the location where the call is made because it will be an emergency call. And it's not a good idea to listen to location in foreground and then make a call because it will be an emergency situation - call will be made immediately.
Is there a solution to get accurate location of user in background? What do you recommend?
Edit: Location will be sent to server immediately.
As for the accuracy, you can get accurate location in the background, under those conditions:
Getting Location Events in the Background
If your application needs location updates delivered whether the application is in the foreground or background, there are multiple options for doing so. The preferred option is to use the significant location change service to wake your application at appropriate times to handle new events. However, if your application needs to use the standard location service, you can declare your application as needing background location services.
An application should request background location services only if the absence of those services would impair its ability to operate. In addition, any application that requests background location services should use those services to provide a tangible benefit to the user. For example, a turn-by-turn navigation application would be a likely candidate for background location services because of its need to track the user’s position and report when it is time to make the next turn.
As for getting location during phone call, I didn't use it myself, but navigation apps like 'waze' do inform turns and navigation events during a phone call so I guess what you ask is possible.
If I understand your needs, you have 2 options:
If you think that the user will be static then simply get the user location right before the call is made. Or better when your app is lunched to make the emergency call.
If the user is moving then you can 'ask' to get background location events. Even then you should consider using 'significant-change location service' as you don't need more then the user location. The standard 'location services' are used for navigation 'Turn by turn' services.
*LAST COMMENT *
If your app is an emergency app you shold read the "Tips for Conserving Battery Power" in the previous link. you don't want your user battery to empty while tracking his location.
Can't you like add that flag in your app plist file to request Location Service to be running in the background mode.
Then in your app, when the user presses the "call" button, you can do your normal CLLocationManager didUpdateToLocation, right before you perform the call.
In your didUpdateToLocation method, you can record the user's location either in a TXT file written to the application sandbox Library/Cache folder or you can use NSUserDefaults.
Note: I've written an app that records the user's GPS location as they drive even when the user presses the lock screen, so I am confident your app can write the GPS coordinate to a TXT file even when the app is minimized, as long as you start your location manager.