【问题标题】:Updating location in the background does not keep app running after being backgrounded在后台更新位置不会在后台运行后保持应用程序运行
【发布时间】:2017-11-12 08:55:46
【问题描述】:

我几乎完成了基于位置的导航应用程序的制作。它会在收到警报时播放声音,并且在访问谷歌地图时它应该在后台保持打开状态,这样,在长途旅行或长时间旅行后,他们可以回到应用程序并从他们离开的地方继续。但是,这不起作用,即使我已经定义并请求了 Location Usage 和 Location Always Usage。进入后台后,我可以在 Xcode 调试器中看到从服务器接收到一些指定的 JSON,但不会播放声音。此外,如果用户离开的时间足够长,即使在控制台中从func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) 打印出坐标时,应用程序也会结束并将用户踢回初始视图控制器。我怎么能阻止它?我看到其他应用程序在后台保持打开状态,并在 iOS 中获得一个蓝色状态栏,表示“[此应用程序] 正在使用您的位置”。如果我无法让我的应用保持打开状态超过 180 秒,那么如何保存当前数据以便用户可以从他/她停止的地方继续?

var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid
var locationManager = CLLocationManager()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.

    navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    mapView.showsUserLocation = true
    mapView.delegate = self

    if let userLocation = mapView.userLocation.location { // because sometimes there is no coordinate and it will unwrap nil.
        mapView.centerCoordinate = userLocation.coordinate
        let region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 9484.1, 9484.1)
        mapView.setRegion(region, animated: true)
    }

    UIApplication.shared.isIdleTimerDisabled = true

    locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestAlwaysAuthorization()

}

func mapView(_ mapView: MKMapView, didUpdate: MKUserLocation) {
    let userLocation = mapView.userLocation
    mapView.centerCoordinate = userLocation.location!.coordinate
    //let region = MKCoordinateRegionMakeWithDistance(frontedUserLocation, 1855, 1855)
    let region = MKCoordinateRegionMakeWithDistance(mapView.centerCoordinate, 9484.1, 9484.1)
    mapView.setRegion(region, animated: true)
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let mostRecentLocation = locations.last else {
        return
    }

    // Add another annotation to the map.
    let annotation = MKPointAnnotation()
    annotation.coordinate = mostRecentLocation.coordinate

    // Also add to our map so we can remove old values later

    // Remove values if the array is too big

    if UIApplication.shared.applicationState == .active {

    } else {
        print("App is backgrounded. New location is %@", mostRecentLocation)
        print("Background time remaining = \(UIApplication.shared.backgroundTimeRemaining) seconds")
        if (UIApplication.shared.backgroundTimeRemaining < 175.2) {
            print("Time low. Re-registering...")
            locationManager.stopUpdatingLocation()
            locationManager.startUpdatingLocation()
            self.registerBackgroundTask()
        }
    }
}

/*func operate() {
    //call endBackgroundTask() on completion..
    switch UIApplication.shared.applicationState {
    case .active:
        print("App is active.")
    case .background:
        print("App is in background.")
        print("Background time remaining = \(UIApplication.shared.backgroundTimeRemaining) seconds")
        if (UIApplication.shared.backgroundTimeRemaining < 175.2) {
            print("Time low. Re-registering...")
            self.registerBackgroundTask()
        }
    case .inactive:
        endBackgroundTask()
        self.registerBackgroundTask()
        break
    }
}*/

func updateCoords() {
    let updateCoordinates = CloudOperation() // edit this to accept a different parameter
    let userLocation = self.mapView.userLocation.location!.coordinate
    updateCoordinates.latit = userLocation.latitude
    updateCoordinates.longi = userLocation.longitude
    locationManager.allowsBackgroundLocationUpdates = true
    locationManager.pausesLocationUpdatesAutomatically = false
    locationManager.startUpdatingLocation()

    /*backgroundTask = UIApplication.shared.beginBackgroundTask { [weak self] in
        self?.endBackgroundTask()
    }
    assert(backgroundTask != UIBackgroundTaskInvalid)*/

    //self.registerBackgroundTask()
    print("Trying to update...")

    dump(self.phase)
}

谢谢!

【问题讨论】:

  • 您需要显示设置位置管理器的代码

标签: ios swift ios11


【解决方案1】:

请确保您已在CLLocationManager 中激活后台模式:

locationManager.allowsBackgroundLocationUpdates = true

【讨论】:

  • 这适用于 iPhone 7,但不适用于 iPhone 6s 上的 iOS 10。
猜你喜欢
  • 1970-01-01
  • 2020-02-19
  • 1970-01-01
  • 2019-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多