无法在后台使应用程序保持GPS处于活动状态,或者在前台或后台使用应用程序读取位置

时间:2016-10-17 22:23:10

标签: ios swift swift3 cllocationmanager

与此问题相关的应用程序旨在以高精度跟踪用户位置,包括GPS坐标和加速度计读数,持续30分钟的时间段,即使用户已按下睡眠按钮。

为此,plist文件和应用程序功能设置已更改,以反映始终导航访问的原因,并启用后台进程以提供基于位置的服务。

该应用确实在用户运行时询问用户GPS权限,如果他们被授予,则激活此视图控制器(包含以下代码的视图控制器)会导致GPS /导航图标显示在苹果手机。

问题是,到目前为止,下面看到的四个“打印”命令都没有导致任何打印消息,因此“newLocation”和“myLocation”变量都不会产生任何数据。如果此代码远远接近能够满足第一句中概述的目的,则问题是“如何修复?”。如果这是实现目标的一种不好的方法,那么更好的答案将解释如何做到这一点。

import UIKit
import CoreMotion
import MapKit
import CoreLocation

class ActiveSession: UIViewController, CLLocationManagerDelegate {
        lazy var locationManager: CLLocationManager! = {
        let manager = CLLocationManager()
        manager.desiredAccuracy = kCLLocationAccuracyBest
        manager.delegate = self
        return manager
    }()

    func locationManager(_manager: CLLocationManager!, didUpdateToLocation newLocation: CLLocation!, fromLocation oldLocation: CLLocation!) {
        let myLocation:CLLocationCoordinate2D=CLLocationCoordinate2DMake(oldLocation.coordinate.latitude, oldLocation.coordinate.longitude)
        print(myLocation)

        if UIApplication.shared.applicationState == .active {
            print("at least it's active at all")
        } else {
            print(newLocation)
            print("it's active when the app isn't")
        }
    }

     func getPermission () {
        locationManager = CLLocationManager()

        switch CLLocationManager.authorizationStatus() {
        case .denied, .restricted:
            return
        case .notDetermined:
            locationManager!.requestAlwaysAuthorization()
            break
        case .authorizedAlways, .authorizedWhenInUse:
            break
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.getPermission()
        locationManager = CLLocationManager()
        locationManager!.desiredAccuracy = kCLLocationAccuracyBest
        locationManager?.startUpdatingLocation()
    }
}

2 个答案:

答案 0 :(得分:1)

您正在三个地方创建新的CLLocationManager实例 - 懒惰的locationManager初始化程序,getPermissionviewDidLoad - 在后两种情况下,您既没有设置期望的准确性和代表。删除locationManager = CLLocationManager()行,您应该会有更好的结果。

答案 1 :(得分:0)

正如ohr指出的那样,需要另外的许可。以下行添加到惰性locationManager初始化程序以纠正此省略:

manager.allowsBackgroundLocationUpdates = true

根据Noah和Paulw11的建议,删除了getPermission函数,并且行:

locationManager = CLLocationManager()

已从viewDidLoad中删除,因为存在大量冗余。仅这一点并没有解决问题,而是向locationManager func添加逻辑,以便将最近的地图数据存储到数组中,如下所示:

let annotation = MKPointAnnotation()
annotation.coordinate = newLocation.coordinate    
locations.append(annotation)
while locations.count > 100 {
    let annotationToRemove = locations.first!
    locations.remove(at: 0)
}

导致了工作代码。此解决方案源自此处的代码:https://www.raywenderlich.com/92428/background-modes-ios-swift-tutorial (谢谢,Ray)

最终代码在前台和后台运行,无需从类中删除任何内容或在appdelegate中实现任何内容。