Swift: местоположение не обновляется при возврате из фона

У меня есть приложение Swift, которое я пытаюсь обновить, когда приложение возвращается из фона, но оно не работает, когда возвращается из фона.

При запуске приложения я точно получу местоположение. После получения местоположения я вызываю stopUpdatingLocation(), поэтому я не продолжаю получать местоположение: locationManager.stopUpdatingLocation()

Затем в моем AppDelegate.swift я снова запускаю UpdateLocation:

func applicationWillEnterForeground(application: UIApplication) {

    ViewController().locationManager.startUpdatingLocation()
}

Это мой код до сих пор:

import UIKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {

var locationManager = CLLocationManager()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestWhenInUseAuthorization()
    locationManager.startUpdatingLocation()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
    println("Error while updating location " + error.localizedDescription)
}

func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {

    var userLocation:CLLocation = locations[0] as CLLocation

    println("\(userLocation.coordinate.latitude),\(userLocation.coordinate.longitude)")

    locationManager.stopUpdatingLocation()

}

}

Тем не менее, всякий раз, когда я создаю фоновое изображение для приложения (нажмите "Домой") и затем возвращаюсь в приложение, местоположение не обновляется. Есть идеи, что я могу здесь делать не так?

1 ответ

Решение

В applicationWillEnterForeground код создает новый локальный экземпляр ViewController который никогда не отображается, еще не имеет locationManager создано и так не имеет никакого эффекта.

Это не относится к ViewController экземпляр, который уже существует и отображается (и имеет locationManager экземпляр который изначально был запущен).

Вместо этого он должен получить ссылку на существующий экземпляр. Если предположить, ViewController является корневым контроллером представления, вы можете сделать:

func applicationWillEnterForeground(application: UIApplication) {

    if let rvc = window?.rootViewController as? ViewController {
        rvc.locationManager.startUpdatingLocation()
    }

}


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

В дополнение к методу делегата приложения applicationWillEnterForeground можно отслеживать эти события из любого места, используя UIApplicationWillEnterForegroundNotification уведомление.

В ViewController Вы можете зарегистрироваться и отменить регистрацию для уведомления в (например) viewWillAppear а также viewWillDisappear, При регистрации вы указываете, какой метод вызывать для события, и все обрабатывается внутри ViewController (и код в applicationWillEnterForeground можно удалить).

override func viewWillAppear(animated: Bool) {
    NSNotificationCenter.defaultCenter().addObserver(
        self, 
        selector: "willEnterForegound", 
        name: UIApplicationWillEnterForegroundNotification, 
        object: nil)
}

override func viewWillDisappear(animated: Bool) {
    NSNotificationCenter.defaultCenter().removeObserver(
        self, 
        name: UIApplicationWillEnterForegroundNotification, 
        object: nil)
}

func willEnterForegound() {
    locationManager.startUpdatingLocation()
}
Другие вопросы по тегам