Swift: 从后台返回时位置未更新

Swift: location not being updated when returned from background

我有一个 Swift 应用程序,当该应用程序从后台 return 时我正尝试更新位置,但它似乎在 return 时不起作用从后台编辑。

启动该应用程序后,我就能很好地获取位置信息。获取位置后,我调用 stopUpdatingLocation() 所以我不会继续获取位置: locationManager.stopUpdatingLocation()

然后,在我的 AppDelegate.swift 中,我再次开始更新位置:

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

}

}

但是,每当我将应用程序设置为后台(单击主页),然后 return 到该应用程序时,位置都不会更新。知道我在这里可能做错了什么吗?

applicationWillEnterForeground 中,代码正在创建一个从未显示的 ViewController 的新本地实例,还没有创建 locationManager,因此没有任何效果。

它不是指已经存在并显示的ViewController实例(并且具有最初启动的locationManager实例)。

相反,它应该获取对现有实例的引用。假设 ViewController 是根视图控制器,你可以这样做:

func applicationWillEnterForeground(application: UIApplication) {

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

}


但是,让 ViewController class 自己管理自己的行为可能是更好的做法。这样,应用程序委托就不必找到对视图控制器实例的引用,也不会直接访问视图控制器的内部状态,ViewController 变得更加独立。

除了应用程序委托方法 applicationWillEnterForeground 之外,还可以使用 UIApplicationWillEnterForegroundNotification 通知从任何地方监控这些事件。

ViewController中,您可以注册和取消注册(例如)viewWillAppearviewWillDisappear中的通知。注册时,你指明事件调用哪个方法,一切都在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()
}