I’ve developed an iOS app by react-native that requires background location updates. The app works perfectly on my phone, providing frequent location updates as expected. However, on some other devices, the location updates occur only once every 15 minutes, exactly, which is problematic for my app’s functionality.
Details:
- Location Services: Enabled and set to “Always” on both devices.
- Battery Optimization: Low Power Mode is turned off on the other devices.
- Permissions: The app has the necessary permissions (
NSLocationAlwaysUsageDescription
andNSLocationWhenInUseUsageDescription
) in the Info.plist file. - Background Modes: The location background mode is enabled in the app’s capabilities.
- Implementation: Using the standard location service with appropriate accuracy and distance filter settings.
Relevant Code Snippet:
- init {
self = [super init];
if (self) {
self->locationManager = [[CLLocationManager alloc] init];
self->locationManager.delegate = self;
}
return self;
}
RCT_EXPORT_METHOD(startGeolocationTracking:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
self->locationManager.distanceFilter = kCLDistanceFilterNone;
self->locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self->locationManager.allowsBackgroundLocationUpdates = YES;
self->locationManager.pausesLocationUpdatesAutomatically = NO;
self->locationManager.activityType = CLActivityTypeOtherNavigation;
[self->locationManager startUpdatingLocation];
[self->locationManager startMonitoringSignificantLocationChanges];
resolve(nil);
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
CLLocation *location = locations.lastObject;
NSLog(@"applog location: %@", location);
[self sendEventWithName:@"onGeolocation" body:@{
@"errorCode": @0,
@"latitude": @(location.coordinate.latitude),
@"longitude": @(location.coordinate.longitude),
@"direction": @(location.course),
@"speed": @(location.speed),
@"altitude": @(location.altitude),
@"accuracy": @(location.horizontalAccuracy),
@"timestamp": @([location.timestamp timeIntervalSince1970] * 1000),
@"count": @(locations.count),
}];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(@"applog location error: %@", error);
[self sendEventWithName:@"onGeolocation" body:@{
@"errorCode": @1,
@"error": error.localizedDescription,
}];
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
NSLog(@"applog location authorization status: %d", status);
[self sendEventWithName:@"onGeolocation" body:@{
@"errorCode": @1,
@"auth": @(status),
}];
}
- (void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager {
NSLog(@"applog location pause");
[self sendEventWithName:@"onGeolocation" body:@{
@"errorCode": @1,
@"status": @"pause",
}];
}
- (void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager {
NSLog(@"applog location resume");
[self sendEventWithName:@"onGeolocation" body:@{
@"errorCode": @1,
@"status": @"resume",
}];
}
- (void)locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error {
NSLog(@"applog location deferred error: %@", error);
[self sendEventWithName:@"onGeolocation" body:@{
@"errorCode": @1,
@"deferred": error.localizedDescription,
}];
}
RCT_EXPORT_METHOD(stopGeolocationTracking:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
[self->locationManager stopUpdatingLocation];
[self->locationManager stopMonitoringSignificantLocationChanges];
resolve(nil);
}
RCT_EXPORT_METHOD(requestLocation:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
dispatch_async(dispatch_get_main_queue(), ^{
[self->locationManager requestLocation];
resolve(nil);
});
}
Observations:
- The issue is device-specific; it works fine on my phone but not on others.
- The app’s background location updates are being throttled on some devices, updating only every 15 minutes, no more, no less.
Steps Taken:
- Verified location services settings.
- Ensured Low Power Mode is off.
- Checked Info.plist for necessary permissions.
- Enabled location background mode in capabilities.
- It doesn’t work neither when running in the foreground, background, or killed by task manager.
Questions:
- What could be causing the background location updates to be throttled on certain devices?
- Are there any additional settings or configurations I should check or implement to ensure consistent background location updates across all devices?
Any help or insights would be greatly appreciated. Thank you!