iOS Location Services do not run after terminating app - ios

First time posting here, so please forgive me if I'm asking a question with a simple answer, but I can't seem to find anything relevant for my case.
I'm trying to have location services run on an iOS app indefinitely throughout pretty much all the stages of the app lifecycle. The user has an option inside the app to activate a certain functionality which starts location services, with the expectation that these services must run even while the app is terminated.
The issue I'm having here is that, when I terminate the app manually, it just stops working.
Here's what I've done so far:
Added background modes in Capabilities (location)
Added Application does not run in background mode and set it to NO in Info.plist. Also added the NSLocationAlwaysUsageDescription and
NSLocationWhenInUsageDescription.
When initializing CLLocationManager, I have set the following: desiredAccuracy to kCLLocationAccuracyBestForNavigation;
distanceFilter to kCLDistanceFilterNone; activityType to
CLActivityTypeFitness; pausesLocationUpdatesAutomatically to NO;
allowsBackgroundLocationUpdates to YES; and calling
requestAlwaysAuthorization.
Tried initiating significant or region monitoring on applicationWillTerminate: method in the app delegate.
So, I understand that what I've done in point 4 should restart the app once a change is detected. At least I've managed to get that much to work with significant changes but not with region monitoring. However, it does not work instantly. The only way I found this to work instantly is to either deactivate/activate airplane mode, or turn the device off and on.
Is there any way to make this work (almost) instantly after terminating the app? What I want to achieve here is to relaunch the app right after the user has terminated it, so that the app can continue to do whatever it needs to do with location services. Would there be any implications when submitting to the app store?
I have seen some things about using a background task to achieve this, could this be the way to go?
Thanks.

Related

React Native iOS app restart on reboot

I want to create an iOS app using React Native. One of the primary features of the app is that it runs constantly in the background. It also requires using GPS btw (in case that is important).
I have had a number of devs tell me its not possible to do this for iOS, however I have read that it is do-able.
Is this possible to do in the iOS environment? Mainly, if the app is running when the phone is powered off, can you make it open when the device is restarted without the user opening it?
I should say that I am a RN novice and any help is much appreciated.
If your app gets permission to get location while it's not in the foreground, then you will get periodic updates and some time to process it.
For example, if you are giving driving directions.
https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html#//apple_ref/doc/uid/TP40009497-CH2-SW10
If there is no good user benefit for you to get the location in the background constantly, you might be rejected. Apple suggests region monitoring instead
iOS supports the delivery of location events to apps that are suspended or no longer running. The delivery of location events in the background supports apps whose functionality would be impaired without them, so configure your app to receive background events only when doing so provides a tangible benefit to the user. For example, a turn-by-turn navigation app needs to track the user’s position at all times and notify the user when it’s time to make the next turn. If your app can make do with alternate means, such as region monitoring, it should do so.
I have no idea how RN wraps this behavior, but no matter what it does (or what a plugin might do), the core iOS behavior is how it is described in that URL.
I verified yesterday (at least on iOS 11.2 simulator) that automatically restarting the app (and the location tracking) after phone reboot works.
The key point is that startMonitoringSignificantLocationChanges needs to be on to wake up the app after reboot. For me the difficult part was figuring out when to turn it on, because I couldn't find a reliable way to detect when the phone is being rebooted or run any code at that point. However, based on initial testing it looks like startMonitoringSignificantLocationChanges is independent and doesn't negatively impact the usual location updates, so now I just leave it on all the time and toggle startUpdatingLocation / stopUpdatingLocation on top of it based on Core Motion-detected activity.
Otherwise requirements are the same as for any location tracking on the background, i.e. handle permissions and don't process too much. Apple documentation explains how to detect that the app was relaunched by a location event.
Here's a react native module which basically helps you achieve what you're describing: https://github.com/transistorsoft/react-native-background-geolocation

can we get location updates in IOS swift in a regular intervel of time even when app is not running in foreground

I want to get location updates of the user in a regular interval of time even if the app is not running in foreground.
In most of the articles i have read, they said that the OS will forcefully stop or suspend the background service the app have started.
What i need is the app should regularly check the user location and when that location becomes greater than say 10Kms the app should trigger a local notification.
We were able to do the functionality correctly when the app is ran again by the user. But it wont work in background. And if we inegrated it as a background service , then it is causing the app to crash. :(
this part caught my attention after a long time of search
https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html#//apple_ref/doc/uid/TP40009497-CH2-SW8
As far as I understood, they say that the OS will wakeup the app to get the current location when it senses a change in location.
But I didnt get any helping tutorial to accomplish the same
These are the tutorials which I refered
Periodic iOS background location updates
How do I get a background location update every n minutes in my iOS application?
Getting user location every n minutes after app goes to background
iOS Not the typical background location tracking timer issue
iOS long-running background timer with "location" background mode
What i need is preferably a background service or something which does the job done which check of the current location calculate distance and makes a local notification.
But as far as i know all the background services will be suspended or killed by the OS within some time after the app is gone in background.
Please guys I am desperate, Its been 2 weeks i am on in its tail.
Building the same for Android was a piece of cake actually.
Any help ???
You can get background location updates easily, you need to enable "Location updates" under "Background Modes" section in capabilities.
You also need to request for Always Authorisation and finally add this
if #available(iOS 9.0, *) {
locationManager.allowsBackgroundLocationUpdates = true
}
Make sure "Location updates" is activated else the above code will lead to a crash.
Also, write the CLLocationManager Delegate Methods in your AppDelegate class as this would increases chances of those methods being called as mentioned on Raywenderlich Background Location tutorial

Appropriate way to get user's location(also in killed state) for an "hyperlocal" app

Requirement - I am building a hyperlocal app which will provide offers to user based on his location. When in app I can get his current location and show offers accordingly but what I need now is to send push notification to user based on his location. So I want to find out user's location and send offers based on his location.
I have read Apple doc for Significant-Change Location Service but then this answer is saying that it won't work once app is killed.
I have also read about Tracking the User’s Location but that didn't work for me properly. I was not getting more than 5 updates in background.
My current code in viewDidLoad -
if (self.locationManager == nil)
{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.delegate = self;
self.locationManager.allowsBackgroundLocationUpdates = true;
self.locationManager.pausesLocationUpdatesAutomatically = false;
if ([CLLocationManager authorizationStatus] != AVAuthorizationStatusAuthorized) {
[self.locationManager requestAlwaysAuthorization];
}
}
[self.locationManager startUpdatingLocation];
And my delegate method looks like this -
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
if (UIApplication.sharedApplication.applicationState == UIApplicationStateActive) {
// Get updated data according to location
} else {
// Send location to server
}
}
My apps capabilities And my plist -
Please suggest some appropriate way, I can live with accuracy of around 1km.
Another approaches -
Can I get user's location in "Background Mode- Background Fetch"'s fetchNewDataWithCompletionHandler: ?
Can I get user's location using Silent Push notification's application:didReceiveRemoteNotification:fetchCompletionHandler:? ): Not possible according to this answer
So, your question is basically "How can I get around Apple's specifically designed user interaction for people wanting to make my app shut up?"
The answer to that is "Not if you want to stay within the rules for the AppStore".
Listen, if the user decides to terminate your app (i.e. they swipe it up and out of the task manager), the entire point of this design is for your app to stop do anything. Apple designed this so that people can quickly turn off exactly the kind of behavior you seem to want to implement. I don't quite get why you would want to circumvent that. I agree that this interaction is a bit obscure perhaps (after all, users can also allow/disallow an app's right to receive location updates in the background in the Settings app as well), but that's the interaction iOS defines.
If I understand you correctly, you succeeded in properly setting up the background location modes, so your app can receive the location updates even if it is not in the foreground (i.e. in background or suspended, in the latter situation iOS wakes it up briefly so you can process location updates and e.g. send a local notification to inform the user). That's as good as it gets.
Oh, and don't fear a device reboot. Yes, after the reboot your app is technically not running, but since the user didn't explicitly kill it the last time, iOS treats it like it was in suspended mode, IIRC, so you will still get significant location updates and can react properly.
(In a more general way: people often seem to think the actual app process state reflects the app state as it is defined in the documentation and/or that whether the app is shown in the task manager is linked to that. Both isn't entirely true.)
Edit after your comment asking me specifically about background fetch:
Sorry, that was perhaps not entirely clear. I didn't answer on this sub-question specifically, because after the user quits your app intentionally, you should not, as explained, "cheat" on their intention. Silent push notifications won't work because of this, yes.
I don't know whether the background fetch will be suppressed in a similar way (could be, but I haven't tried it), but I think that won't help you either, even if it were still working (which I doubt, Apple's probably going to be hard on this). I have also never tried to (re)start location updates in this method, so I can't say whether that even works (once the completion handler is called the system will likely suspend your app again at least, and I am not sure that this "resets" the "user killed the app flag" that the system seems to use for deciding which app to wake up and deliver location updates to).
application:performFetchWithCompletionHandler: (as it is fully called) will be called by the OS based on heuristics, it tries to be "clever" on this. Since the method is meant to fetch some data from a backend that doesn't provide push notifications, the times it is called at all can be severely limited, as is explained in the documentation. The actual mechanism that decides when the OS calls is a black box and it is a gamble to try to trick it into getting called when you need it. Could be very likely that this happens hours later. Think of the following scenario:
Your app runs fine in the background location modes (I understood you correctly in that you successfully set that up? see here and here)
The user manually kills your app. For the sake of this argument let's assume that doesn't keep the system from later restarting it to give it a background fetch opportunity
Since other apps are running on the system and the user only has an edge connection at the moment, the OS decides it is a bad time to initiate a background fetch (I just assume here that those factors play a role, as said it's a blackbox, but those appear reasonable to me). Your user walks around some more, bypassing several locations you would be interested in.
Two hours later, the user is by now in a completely different area, your app is started again by the OS and gets a application:performFetchWithCompletionHandler: call. You start location updates again (lets assume that even works and the system doesn't immediately terminate the app again, i.e. even after the fake background fetch it delivers location updates in background). You missed several locations, but nevertheless the app now handles new ones. All your logic is basically messed up, because you didn't plan for so many location updates being missing...
(Optional: After a while your user realizes that your app apparently does something, even although they terminated it (for example they notice battery drain). They will delete your app and leave a one-start review...)
(Optional 2, worst-case: Once apple realizes it is possible to re-init background location updates after a user killed an app this way, they simply close the loop-hole in an iOS update and your app is back where we started...)
For the record: I am not defending any design decisions made by apple, heck I know this is confusing to wrap your head around and just as one can make a stand for "preserve battery and user intent under all circumstances" one can make one for better background tracking. I am merely pointing out that they're in control here and trying to weasel around any specific interaction paradigms they set on the platform is likely not a good idea.
That all being said, I am afraid the "user terminated the app, now I won't get any location updates" is simply something you have to live with. Why would that even be a problem for you, considering you didn't say anything about background location modes not being enough for you? The only (questionable) scenario I could imagine is a kind of tracker application, maybe given on devices handed out to employees of a delivery service or something. If that is it (and putting aside the ethics behind such stuff, in some countries that is even illegal to do, mind you...), I have to say that iOS is simply not the correct platform for this.
Hi just create a UILocalNotification set it with your details and most important for notification to be triggered when you enter a Region add the region property see docs
Hope it helps

iOS8 background standard-location updates after termination

I'm wondering if, in iOS8 with all possible background-modes turned on, the app will be woken up after termination to deliver location updates using the standard-location updates monitoring?
I've read all possible documentations, but I find it quite confusing because it at one point says the device will wake up the app, and at another point is says the device will not wake up the app when using standard-location updates.
My app needs continuous location updates with a movement-threshold of about 150 meters (max), and therefore the standard-location-monitoring seems appropriate. It also needs to keep getting these updates even if the app is terminated by the system, as it is crucial to the user.
I've come to understand that if using the significant change location monitoring the app will be woken up upon delivery of new data, but I'm still confused about the standard location monitoring when having requested Always authorization and having the background updates for location turned on.
Have anyone tested this, or know what happens? And if the app is not woken up after being terminated by the system, how can I solve that problem?
Thanks.
Standard location is something your app does. Thus your app needs to be running. It can operate in the foreground or you can even run in the background. But if your app is not running, it's not running; there is nothing to track.
Significant location monitoring and region monitoring, on the other hand, are done for you by the system, so it runs even if your app is not running, and you are woken up or launched to receive updates.

GPS Application running in the background

I have an IOS application that uses location services.
I know that applications using location services can execute in the background.
However, I don't want my app to run in the background. If the user isn't watching it, it should not power.
Is this going to happen naturally (i.e. something special is needed for apps using location services to continue to operate in the background?)?
If not, what do I need to do to ensure the app using location services suspends when it goes into the background? If so, what? And what would need to be done to restore the app?
Thx
No problem - just do nothing. When the user switches away from your app (to another app, or locking the screen) your app will be suspended.
However, to make absolutely sure you don't do any location in the background, use the applicationDidEnterBackground and applicationWillEnterForeground notifications (or the corresponding app delegate methods) to stop and restart location updating.

Resources