Постоянно запускать приложение в фоновом режиме

Я хочу, чтобы мое приложение продолжало работать в фоновом режиме с помощью служб определения местоположения. Для этого я использовал:

-(void)applicationDidEnterBackground:(UIApplication *)application {

    [locationManager stopUpdatingLocation];
    [locationManager startUpdatingLocation];

    //timer=[NSTimer scheduledTimerWithTimeInterval:300 target:self selector:@selector(UpdateLocation) userInfo:nil repeats:YES];

}

но когда я использую NSTimer, он не вызывает UpdateLocation. Я пробовал называть его с помощью другого метода, но потом он также вызывался только один раз.

Я хочу постоянно запускать приложение в фоновом режиме, обнаруживая местоположения через регулярный промежуток времени.

Ответ 1

Я сделал это в приложении, которое я разрабатываю. Таймеры не работают, когда приложение находится в фоновом режиме, но приложение постоянно получает обновления местоположения. Я читал где-то в документации (я не могу найти его сейчас, я опубликую обновление, когда я это сделаю), что метод можно вызывать только в цикле активного запуска, когда приложение находится в фоновом режиме. У делегата приложения есть активный цикл цикла даже в bg, поэтому вам не нужно создавать свои собственные, чтобы сделать эту работу. [Im не уверен, что это правильное объяснение, но вот как я понял из того, что я читал)

Прежде всего, добавьте объект "location" для ключа "Режимы фона" в вашем приложении info.plist. Теперь вам нужно начать обновление местоположения в любом месте вашего приложения:

CLLocationManager locationManager = [[CLLocationManager alloc] init];

locationManager.delegate = self;//or whatever class you have for managing location

[locationManager startUpdatingLocation];

Затем напишите метод обработки обновлений местоположения, say - (void) didUpdateToLocation: (местоположение CLLocation *) в делегате приложения. Затем реализуем метод locationManager: didUpdateLocation: fromLocation CLLocationManagerDelegate в классе, в котором вы запустили диспетчер местоположений (поскольку мы установили делегат менеджера местоположений на "я" ). Внутри этого метода вам нужно проверить, прошел ли временной интервал, после которого вы должны обрабатывать обновления местоположения. Вы можете сделать это, сохраняя текущее время каждый раз. Если это время истекло, вызовите метод UpdateLocation из вашего делегата приложения:

NSDate *newLocationTimestamp = newLocation.timestamp;
NSDate *lastLocationUpdateTiemstamp;

int locationUpdateInterval = 300;//5 mins

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
if (userDefaults) {

        lastLocationUpdateTiemstamp = [userDefaults objectForKey:kLastLocationUpdateTimestamp];

        if (!([newLocationTimestamp timeIntervalSinceDate:lastLocationUpdateTiemstamp] < locationUpdateInterval)) {
            //NSLog(@"New Location: %@", newLocation);
            [(AppDelegate*)[UIApplication sharedApplication].delegate didUpdateToLocation:newLocation];
            [userDefaults setObject:newLocationTimestamp forKey:kLastLocationUpdateTimestamp];
        }
    }
}

Это вызовет ваш метод каждые 5 минут, даже если ваше приложение находится в фоновом режиме. Imp: эта реализация истощает батарею, если точность данных о местоположении не является критичной, вы должны использовать [locationManager startMonitoringSignificantLocationChanges]

Прежде чем добавлять это в свое приложение, ознакомьтесь с руководством по программированию http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/LocationAwarenessPG/Introduction/Introduction.html

Ответ 2

Я знаю, что это очень поздно для ответа. Но если у вас все еще нет ответа, вот что я сделал, и мое приложение постоянно работает в фоновом режиме.

- (void)applicationDidEnterBackground:(UIApplication *)application
{
     UIApplication *app = [UIApplication sharedApplication];
     UIBackgroundTaskIdentifier bgTask = 0;

     backgroundTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self  selector:@selector(backgroundTask) userInfo:nil repeats:YES];

     bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
        [app endBackgroundTask:bgTask];
    }];
}

Теперь сделайте все, что хотите, в backgroundTask.

Ответ 3

Вы можете использовать для запуска приложения в фоновом режиме для конкретной задачи.

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    UIApplication *app = [UIApplication sharedApplication];
    UIBackgroundTaskIdentifier bgTask = 0;

    backgroundTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(backgroundTask) userInfo:nil repeats:YES];

    bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
        [app endBackgroundTask:bgTask];
    }];
}