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()
}