Правильный запуск приложения iOS в фоновом режиме из события местоположения - PullRequest
0 голосов
/ 04 октября 2018

(iOS 11, Swift 4.1)

Я написал плагин Cordova в Swift для управления мониторингом региона, но он не работает должным образом, когда мое приложение приостановлено или убито.Вот мой класс с соответствующими функциями:

class GeofenceManager : NSObject, CLLocationManagerDelegate {

  func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {
      switch state {
          case .inside:
              log ("Did Enter Region: " + region.identifier)
              self.postGeofenceTransition(region: region, transitionType: 1)
              break
          case .unknown:
              log ("Unknown Transition for region: " + region.identifier)
              // self.postGeofenceTransition(region: region, transitionType: 1)
              break
          default:
              break
        }
    }

    func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
        log ("Did Exit Region: " + region.identifier)
        self.postGeofenceTransition(region: region, transitionType: 2)
    }

    func locationManager(_ manager: CLLocationManager, didStartMonitoringFor region: CLRegion) {
        log("Did start monitoring region: " + region.identifier)
        self.locationManager.requestState(for: region)
    }
}

(я делаю это таким образом, чтобы обрабатывать кого-то, кто уже находится в регионе, когда мы начинаем мониторинг)

У меня также есть didChangeAuthorizationStatus"который выбирает и устанавливает все геозоны, работает нормально.

В моем AppDelegate (objc) я пытаюсь запустить Location Services, если приложение открывается из события региона, с

if([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) {
    _locationManager = [[CLLocationManager alloc] init];
    [_locationManager setDelegate:self];
    [_locationManager setDistanceFilter:kCLHeadingFilterNone];
    //change the desired accuracy to kCLLocationAccuracyBest
    [_locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
    //SOLUTION: set setPausesLocationUpdatesAutomatically to NO
    [_locationManager setPausesLocationUpdatesAutomatically:NO];
    [_locationManager startUpdatingLocation];
}

У меня вопрос: если мое приложение открывается из события, то есть "didEnterRegion", я немедленно запускаю службы определения местоположения, но удастся ли мне снова попасть в мой делегат "didEnterRegion"?И я здесь что-то делаю совершенно неправильно?

Я думаю, что мне не хватает некоторого понимания состояний приложений iOS, я копался в документах, но пока не нажал.Любое понимание очень ценится.

1 Ответ

0 голосов
/ 04 октября 2018

У меня такой вопрос: если мое приложение открывается из события, то есть "didEnterRegion", я немедленно запускаю службы определения местоположения, но я снова нажму свой делегат "didEnterRegion"?

Если ваше приложение было приостановлено или прекращено, и если оно было пробуждено или запущено только для получения didEnterRegion, оно остается в фоновом режиме .Дается время просто обработать это одно событие, а затем оно приостанавливается.

Вы не можете начать обновление местоположения с startUpdatingLocation в этой точке.Вы на заднем плане!Даже если вы авторизованы для фоновых обновлений, вы не можете запускать получение обновлений, пока вы находитесь в фоновом режиме.И даже если бы вы могли, ваш код потерпит неудачу, потому что вы никогда не установили allowsBackgroundLocationUpdates.И даже если бы вы могли сделать , вы не получили бы никаких событий, потому что у вас нет реализации didUpdateLocation.

Правильная процедура: ничего не делать.Просто держи didEnterRegion и уходи.Если пользователь снова входит в регион, ваш didEnterRegion будет вызван снова.Мониторинг региона продолжается до тех пор, пока вы его не остановите (и убедитесь, что вы действительно остановите его, или пользователь может быть вынужден удалить ваше приложение).

Приложение : Как реагировать на запуск с нуля в фоновом режиме, как это?Вы можете обнаружить ключ в didFinishLaunchWithOptions и обработать его там и вернуть false, или вы можете проигнорировать его и вернуть true и получить didEnterRegion.Но в любом случае вы должны немедленно создать менеджера местоположения и назначить его делегата, иначе вы ничего не получите, очевидно.Вот почему вы должны всегда создавать менеджер местоположения и устанавливать его делегат в вашем делегате приложения или в корневом контроллере представления, то, что всегда существует и существует как ранний насколько возможно в жизни приложения, как только оно запускается.

...