Лучшая практика iOS для обновления местоположения в фоновом режиме

Обзор

Моя компания просит меня выпустить приложение, которое может проверять местоположение устройства каждые два часа. Приложение будет отправлять эти данные о местоположении через сокет TCP/IP на мой сервер, а затем получать информацию, соответствующую этим самым данным (сразу и через тот же сокет TCP/IP). Поэтому я не пытаюсь заставить свое приложение постоянно работать в фоновом режиме (что, на самом деле, кажется горячей темой для iOS, а также не подходит для моего проекта).

Вопрос

Чтобы быть надежным, как лучше всего это сделать? Итак, я хотел бы знать:

  • Поскольку мое приложение приостановлено (= неактивно), разрешает ли Apple открывать сокет для отправки местоположения, когда оно просыпается didUpdateToLocation?
  • Как долго мне нужно выполнять задачу отправки/получения через сокет?
  • Должен ли я создать настоящую фоновую задачу с помощью beginBackgroundTaskWithExpirationHandler и использовать 10 минут, предоставленные Cocoa, для выполнения моей задачи отправки/получения?
  • Возможно (и разрешено Apple) запрашивать 10-минутную фоновую задачу каждые 2 часа без участия человека (т. Е. Пользователь должен повторно открыть приложение и т. д.)?

Чего я достиг/нашел на данный момент

  • Я добавил ключ location в свой Info.plist, чтобы иметь возможность запускать обработчик didUpdateToLocation, когда мое приложение неактивно.
  • Я могу отправлять и получать данные через сокет, который я открыл, когда мое приложение было на переднем плане (= активно).
  • Я пытался проверить backgroundTimeRemaining при вызове didUpdateToLocation. Я получил очень большой результат, что кажется нормальным, потому что на данный момент applicationState находится не в UIApplicationStateBackground, а в UIApplicationStateActive.

Эти моменты не очень ясны в официальной документации, а тем, относящихся к моему конкретному случаю, я не нашел.

Спасибо за вашу помощь.


person user1382094    schedule 31.07.2013    source источник
comment
beginBackgroundTaskWithExpirationHandler НЕ создает фоновую задачу, она помечает текущий поток как то, что хочет продолжить работу, если приложение находится в фоновом режиме.   -  person progrmr    schedule 31.07.2013
comment
@ user1382094: Не забудьте отметить правильный ответ как принятый ответ на ваш вопрос, если он вам помог. Спасибо!   -  person veducm    schedule 22.01.2014


Ответы (1)


Согласно документация Apple, вы можете добиться этого, используя подход, очень похожий на тот, который вы описали. Я бы сделал что-то похожее на то, что объяснено в этом сообщении mindsizzlers< /а>:

  • #P2#
    - (void) applicationDidEnterBackground:(UIApplication *) application
    {
        // Create the location manager if you do not already have one.
        if (nil == locationManager)
            locationManager = [[CLLocationManager alloc] init];
    
        locationManager.delegate = self;
        [locationManager startMonitoringSignificantLocationChanges];
    }
    
    #P3# <цитата> #P4# #P5#
  • Измените делегата диспетчера местоположения (didUpdateToLocation), чтобы он обрабатывал фоновые обновления местоположения.

    - (void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation
    fromLocation:(CLLocation *)oldLocation
    {
        if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
            // Send the new location to your server in a background task
            // bgTask is defined as an instance variable of type UIBackgroundTaskIdentifier
            bgTask = [[UIApplication sharedApplication] 
            beginBackgroundTaskWithExpirationHandler:
            ^{
                [[UIApplication sharedApplication] endBackgroundTask:bgTask];
            }];
    
            // Make a SYNCHRONOUS call to send the new location to our server
    
            // Close the task
            if (bgTask != UIBackgroundTaskInvalid) {
                [[UIApplication sharedApplication] endBackgroundTask:bgTask];
                bgTask = UIBackgroundTaskInvalid;
            }
    
        } else {
                // Handle location updates in the normal way
        }   
    }
    

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

Конечно, если вы хотите убедиться, что это происходит в определенный интервал времени, вы все равно можете установить таймер, чтобы начать получать обновления местоположения, и как только вы их получите, вы отправляете их на сервер. Взгляните на эту публикацию, в которой рассказывается о фоновых режимах в iOS< /strong> (раздел: Получение обновлений местоположения) и это другое questions, чтобы узнать, как это сделать в деталях.

person veducm    schedule 31.07.2013