IOS Getting location updates when app terminated without using significantChange
Looking at the below content from the Apple doc, you clearly have 2 alternatives against using significant location changes to wake a app from the background. I have marked in bold the services you can use to relaunch the app if it has been terminated.
Using Location Services in the Background Most location services are
meant to be used while your app is in the foreground but some can also
run in the background. In some cases, location events can even cause
your app to be relaunched to process an event. To run most location
services in the background, you need to enable the location updates
background mode in the Capabilities tab of your Xcode project. For
services that launch your app, you need to request (and be granted)
“Always” authorization from the user.The standard location service delivers events normally while an app is
running in the foreground. When your app is in the background, this
service delivers events only when the location-updates background mode
is enabled for the app. This service does not relaunch iOS apps that
have been terminated.The significant location change service delivers events normally
while an app is running in the foreground or background. For a
terminated iOS app, this service relaunches the app to deliver
events. Use of this service requires “Always” authorization from the
user.The region monitoring service delivers events normally while an
app is running in the foreground or background. (You can use this
service for both geographic and beacon regions.) For a terminated
iOS app, this service relaunches the app to deliver events. Use of
this service requires “Always” authorization from the user.Beacon ranging delivers events normally while an app is running in the
foreground. When your app is in the background, this service delivers
events only when the location-updates background mode is enabled for
the app and the standard location service is running. (If the beacon
region’s notifyEntryStateOnDisplay property is YES, waking the device
causes the app to range for beacons for a few seconds in the
background.) This service does not relaunch iOS apps that have been
terminated; however, you can be relaunched by monitoring beacon
regions using the region monitoring service.The heading service delivers events normally while an iOS app is
running in the foreground. When your app is in the background, this
service delivers events only when the location-updates background mode
is enabled for the app and the standard location service is running.
This service does not relaunch iOS apps that have been terminated.The visit service delivers events normally while an iOS app is
running in the foreground. When your app is in the background, this
service delivers events only when the location-updates background mode
is enabled for the app and the standard location service is running.
For a terminated iOS app, this service relaunches the app to deliver events. Use of this service requires “Always” authorization from the
user.Enabling the location-updates background mode ensures that an app
continues to receive location events while in the background. When the
app moves to the background, the system adds the location-services
indicator to the status bar to let the user know that an app is using
location services. The system may still terminate the app at any time
to reclaim its memory or other resources.Also from the doc,
Getting the Visited Locations
In iOS, the visits service provides an alternative to the significant location change service for apps that need location
information about interesting places that the user visited. For
example, if the user is in one location for an extended period of
time, the service might generate an event when the user arrives at
that location and another when the user leaves that location. The
service is intended for apps that might already be using the
significant location change service and want an even lower power way
to do so. You would not use this service to create navigation apps or
apps that rely on regular location updates.
Document Link:
https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLLocationManager_Class/index.html#//apple_ref/doc/uid/TP40007125-CH3-SW73
Get Location Updates for iOS App Even when Suspended
After months of trials and errors by experimenting the Core Location Framework, I have found the solution to get location update even when the app is killed/suspended. It works well for both iOS 7 and 8.
Here is the solution:-
If your app is a location based mobile application that needs to monitor the location of the device when it has significant changes, the iOS will return you some location coordinates when the device has moved more than 500 meters from the last known location. Yes, even when the app is killed/suspended either by the user or iOS itself, you still can get the location updates.
So in order for a locationManager
to get location update even when the app is killed/suspended, you must use the method startMonitoringSignificantLocationChanges
, you can not use startUpdatingLocation
.
When iOS wants to return the location update to the app, it will help you to relaunch the app and return a key UIApplicationLaunchOptionsLocationKey
to the app delegate method didFinishLaunchingWithOptions
.
The key UIApplicationLaunchOptionsLocationKey
is very important and you must know how to handle it. You must create a new locationManager instance when you receive the key and you will get the location update on the locationManager delegate method didUpdateLocations
.
Here is the sample code:-
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
self.shareModel = [LocationShareModel sharedModel];
if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) {
self.shareModel.anotherLocationManager = [[CLLocationManager alloc]init];
self.shareModel.anotherLocationManager.delegate = self;
self.shareModel.anotherLocationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
self.shareModel.anotherLocationManager.activityType = CLActivityTypeOtherNavigation;
if(IS_OS_8_OR_LATER) {
[self.shareModel.anotherLocationManager requestAlwaysAuthorization];
}
[self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];
}
return YES;
}
In addition to the didFinishLaunchingWithOptions
method, I have created the locationManager
instance when the app is active. Here are some code examples:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[self.shareModel.anotherLocationManager stopMonitoringSignificantLocationChanges];
if(IS_OS_8_OR_LATER) {
[self.shareModel.anotherLocationManager requestAlwaysAuthorization];
}
[self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
if(self.shareModel.anotherLocationManager)
[self.shareModel.anotherLocationManager stopMonitoringSignificantLocationChanges];
self.shareModel.anotherLocationManager = [[CLLocationManager alloc]init];
self.shareModel.anotherLocationManager.delegate = self;
self.shareModel.anotherLocationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
self.shareModel.anotherLocationManager.activityType = CLActivityTypeOtherNavigation;
if(IS_OS_8_OR_LATER) {
[self.shareModel.anotherLocationManager requestAlwaysAuthorization];
}
[self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];
}
I have written an article explaining on the details on how to get the location update for iOS 7 and 8 even when the app is killed/suspended. I have also uploaded the complete source code on GitHub with the steps on how to test this solution.
Please visit the following URLs for more information:-
- Getting Location Updates for iOS 7 and 8 when the App is Killed/Terminated/Suspended
- Source Code on GitHub - Get the Location Updates Even when the iOS mobile apps is Suspended/Terminated/Killed
iOS update location even when app is terminated
It looks like you're using CLLocationManagerDelegate's deprecated function:
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
}
Instead you should implement
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
}
Update Location when app is terminated
In a word, no. You could subscribe to significant location change notifications. Then when the system detects that the user has moved by "a significant distance" (defined by the system.) I'm not sure what the system calls a significant location change, but it's going to be a lot more than 50 feet.
Another alternative would be to create a geofence around the user's current location and listen for location updates using the Core Location startMonitoring(for:)
function.
Both of those techniques will relaunch your app if they detect a relevant event and your app isn't running.
Related Topics
Uitableviewcelldeleteconfirmationcontrol Issue
Fbsdkaccesstoken Currentaccesstoken Nil After Quitting App
How to Disable the Back Navigation Menu in iOS 14+
How Programmatically Restart an iPhone App in iOS
Xcode 10, Command Codesign Failed with a Nonzero Exit Code
Dial a Phone Number with an Access Code Programmatically in iOS
How to Dismiss the iOS Keyboard
How to Figure Out Which Url Is Being Blocked by App Transport Security
Change Frame Programmatically with Auto Layout
Conditionally Import a Framework (Such as Speech) Based on iOS Version in Swift
Are View Controllers with Nib Files Broken in iOS 8 Beta 5
Set Custom Images to the Uibarbuttonitem But It Doesn't Show Any Image
Uicollectionview Insert Cells Above Maintaining Position (Like Messages.App)
iOS Is It a Static or a Dynamic Framework
@Published Property Wrapper Not Working on Subclass of Observableobject