Search code examples
iosbackgroundnstimercore-location

Sending Latitude and Longitude to Server when app is in background


I have gone through so many links, even after that I haven't found a proper solution for getting latitude and longitude.

Periodic iOS background location updates

iOS long-running background timer with "location" background mode

I tried from some links and forums but it is working for only 3 mins, then app is not at all updating the user location.

- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.


//create new uiBackgroundTask
__block UIBackgroundTaskIdentifier bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
    [app endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}];

//and create new timer with async call:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

    [locationManager startUpdatingLocation];

    NSTimer* t = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(startTrackingBg) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:t forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] run];
});

}
 -(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
//  store data
CLLocation *newLocation = [locations lastObject];


//tell the centralManager that you want to deferred this updatedLocation
if (_isBackgroundMode && !_deferringUpdates)
{
    _deferringUpdates = YES;
    [locationManager allowDeferredLocationUpdatesUntilTraveled:CLLocationDistanceMax timeout:10];
}
}

Solution

  • Ok.

    After struggling for 3days, it is working for me for sending latitude and longitude when app is in background even after 3 mins.

    I checked my app, continuously sending lat long for more than a hour in background.

    It can help some one at least.

    First Please add below two keys in your pList.

     1.NSLocationAlwaysUsageDescription
     2.NSLocationWhenInUseUsageDescription
    

    Bothe are strings and you can give any value.

    Then please turn on background fetch and check location updates under capabilities in project section.

    Then import Corelocation framework and add this below code.

    locationManager is a global variable.

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
     //create CLLocationManager variable
    locationManager = [[CLLocationManager alloc] init];
    //set delegate
    locationManager.delegate = self;
    
    app = [UIApplication sharedApplication];
    // This is the most important property to set for the manager. It ultimately determines how the manager will
    // attempt to acquire location and thus, the amount of power that will be consumed.
    
    if ([locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) {
        [locationManager setAllowsBackgroundLocationUpdates:YES];
    }
    locationManager.desiredAccuracy = 45;
    locationManager.distanceFilter = 100;
    // Once configured, the location manager must be "started".
    [locationManager startUpdatingLocation];
    }
    
     - (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    
    [locationManager stopUpdatingLocation];
    [locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
    [locationManager setDistanceFilter:kCLDistanceFilterNone];
    locationManager.pausesLocationUpdatesAutomatically = NO;
    locationManager.activityType = CLActivityTypeAutomotiveNavigation;
    [locationManager startUpdatingLocation];
     }
    
     - (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    
    
    [locationManager stopUpdatingLocation];
    
    __block UIBackgroundTaskIdentifier bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
        bgTask = UIBackgroundTaskInvalid;
    }];
    
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:10.0
                                                  target:self
                                                selector:@selector(startTrackingBg)
                                                userInfo:nil
                                                 repeats:YES];
    
    
     }
    
    -(void)startTrackingBg {
    
    [locationManager startUpdatingLocation];
     NSLog(@"App is running in background");
    }
     //starts automatically with locationManager
      -(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
    latitude=newLocation.coordinate.latitude;
    longitude=newLocation.coordinate.longitude;
    NSLog(@"Location: %f, %f",newLocation.coordinate.longitude, newLocation.coordinate.latitude);
     }