Getting user's location while making a phone call - ios

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.

Related

Can we get user current location when app is not running in iOS?

We would like to track user so we want user current location when app is not running also.
We are tracking user when app is in background or foreground mode but in some cases like battery drain, memory footprint issue etc, app going to auto kill so in that case we can not track user. We have used startMonitoringSignificantLocationChanges also but in this case we are getting user location once user moved around 500 meter or more from their current location. If user not move after app kill, we can not track. Is there any way to do this?
Certain types of apps, like turn-by-turn navigation apps, are allowed to run from the background, and can continue to monitor the user's location.
Normal apps cannot. If the system terminates your app you stop receiving location updates. As you say, you can use startMonitoringSignificantLocationChanges or geofencing to get updates when the device moves a significant distance, but I don't think there is another solution for an app store app.
("Kill mode" isn't really a meaningful term.)

iOS: Location Update in Application Suspended State

Is it possible to update location when application is in suspended/terminate state.
i want to update location every 500 meters when app is in suspended/terminate state.
thanks in advance.
When terminated the only real way to get updates is to use Region Monitoring but you will only get major updates so I doubt it will work for 500 meters.
From the documentation:
If your app is terminated either by a user or by the system, the
system doesn't automatically restart your app when new location
updates arrive. A user must explicitly relaunch your app before the
delivery of location updates resumes. The only way to have your app
relaunched automatically is to use region monitoring or
significant-change location service. However, when a user disables the
Background App Refresh setting either globally or specifically for
your app, the system doesn't relaunch your app for any location
events, including significant change or region monitoring events.
Further, while Background App Refresh is off your app won't receive
significant change or region monitoring events even when it's in the
foreground.
There are good reasons for this. Firstly people don't want apps that 'snoop' on them all the time and even if there is a good reason imagine having 10 apps doing this constantly. It's going to start causing you performance and battery life issues.
EDIT
There appears to be some confusion by a lot of people over this issue so I will attempt to clear things up a bit.
Your app is NOT supposed to be continually tracking location while terminated (or suspended really). You are just not allowed to do this both for privacy reasons and so that you don't drain the battery excessively.
While your app is in the foreground you can use location services via startUpdatingLocation to monitor the device location. Assuming the app has been granted permission this will use all available hardware (GPS, WiFi, Cellular).
Now from the documentation itself:
If you start this service and your app is suspended, the system stops
the delivery of events until your app starts running again (either in
the foreground or background). If your app is terminated, the delivery
of new location events stops altogether. Therefore, if your app needs
to receive location events while in the background, it must include
the UIBackgroundModes key (with the location value) in its Info.plist
file.
So once suspended and terminated your options are really to monitor regions and to monitor for significant location changes. Neither of these are particularly accurate or frequent. One reason for this is that they only use low power methods to get the position (WiFi and Cellular) they don't use the GPS.
So no accurate and/or frequent location tracking while an app is suspended or terminated. This just has to be accepted and you need to design your apps accordingly.
let locationManager = CLLocationManager()
locationManager.startMonitoringSignificantLocationChanges()
After returning a current location fix, the receiver generates update events only when a significant change in the user’s location is detected. It does not rely on the value in the distanceFilter property to generate events
If you start this service and your app is subsequently terminated, the system automatically relaunches the app into the background if a new event arrives. In such a case, the options dictionary passed to the application(:willFinishLaunchingWithOptions:) and application(:didFinishLaunchingWithOptions:) methods of your app delegate contains the key location to indicate that your app was launched because of a location event. Upon relaunch, you must still configure a location manager object and call this method to continue receiving location events. When you restart location services, the current event is delivered to your delegate immediately. In addition, the location property of your location manager object is populated with the most recent location object even before you start location services.
Apps can expect a notification as soon as the device moves 500 meters or more from its previous notification. It should not expect notifications more frequently than once every five minutes. If the device is able to retrieve data from the network, the location manager is much more likely to deliver notifications in a timely manner.
Hope It helps

Swift Region Monitoring Local Notification trigger

I'm doing an app to trigger a local notification when a region is entered.
However, sometimes when the phone is locked, the notifications didn't pop up even I've been in the region area for a while. The notification popup will show only when the power/home button is pressed(phone still in locked mode).
In general, all seems to be working except that sometimes the notification will show only when power/home button is pressed to awake the phone although it is still locked.
Hope someone can enlighten me please! =)
According to the developer documentation. In core-location framework, two services can give you the current location information.
The standard location service is a configurable, general-purpose solution for getting location data and tracking location changes for the specified level of accuracy.
The significant-change location service delivers updates only when there has been a significant change in the device’s location, such as 500 meters or more.
You need to use standard location services to keep monitoring location in background
If your iOS app must keep monitoring location even while it’s in the background, use the standard location service and specify the location value of the UIBackgroundModes key to continue running in the background and receiving location updates. (In this situation, you should also make sure the location manager’s pausesLocationUpdatesAutomatically property is set to YES to help conserve power.)

CLLocationManager region monitoring and airplane mode

I am developing a location dependent feature. The uses case is this:
User receives data and notifications based on their location.
Location is actually the city/town they reside in more accurately a
region based on the city.
Then they hop on a plane/train and go to another city. I want to
be able to detect that send them local notification to change
their location settings and if they accept to start providing them
data based on the new location i.e. city. Very important to this
part of the usage is the Airplane mode which is usually turned on
during the travel and then turned off when the user arrives at
their destination.
I thought region monitoring will be the perfect technology for that. However there is no way to find out if the user had gone outside the region when using Airplane mode. There will be nor crossing event and I am unable to request the state for the particular region. Also in that case if the app was terminated the system will not wake it up for crossing event because there is not one.
Is there a way to reliably handle that situation.
I also thought a replacement technology for my use case might be the Visit monitoring.
Thanks!

IOS App in Background?

I currently have a discussion with my developers, and we're facing an issue.
We are working on an application which should find offers when user is near some latitudes and longitudes in the GPS Position Tracker. It should send a push notification when user is near a position.
The issue is, it works perfectly when app is "on", but when user "quits" the application the app should go in "Background Mode" and still be available to find users gps position and send back to our webservice in the background mode.
How is that possible?
Is this the solution of do you have a better solution?
1. First time user launch the application we find the users position and make call to webservice to get places nearby 100km and save it to local storage incl. the users unique deviceID (UDID).
User quits the application - here it should run in backgroundMode.
User is near a place in our localstorage database for lat and longitude and now we send a push notification to the users device from the localstorage.
Every 20 minutes we make a call for app to refresh all positions for my currently lng and lat to keep it updated ,
You can preconfigure areas for the app to be notified when the user enters those regions without the need for the app to be in the foreground.
https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLLocationManager_Class/CLLocationManager/CLLocationManager.html#//apple_ref/occ/instm/CLLocationManager/startMonitoringForRegion:
So get your places of interest and register those places with the above api, then when your app springs back to life, fire your notification off for whatever you are near.
In iOS, the regions you register with the location manager persist
between launches of your application. If a region crossing occurs
while your iOS app is not running, the system automatically wakes it
up (or relaunches it) in the background so that it can process the
event. When relaunched, all of the regions you configured previously
are made available in the monitoredRegions property of any location
manager objects you create.
The feature you are looking is GeoFencing not push notification. It will create a virtual fence to the specific coordinate and when the user enters into specific distance(say 5km) it will call some delegate methods. So we can implement a local notification with necessary message in that.
I think your solution is something complex and i suggest you to go on with GeoFencing
Find a nice a tutorial here
http://www.creativebloq.com/ipad/get-started-geofencing-ios-9122867

Resources