我的iOS应用程序不会在后台更新位置

3
我有一个使用Swift开发的iOS应用程序。我的应用程序目前采用Swift 2,但我正在使用带有Swift 3的Xcode 8。该应用程序配置为使用旧版Swift语言。
直到最近,该应用程序一直正常工作。
该应用程序请求始终使用位置的正确权限,并且授权已正确设置为始终使用。
我更新了生产应用程序的签名标识,然后该应用程序停止在位置更新时收到通知,但在开发模式下仍在工作(从xcode启动)。
现在我吊销并更新了生产和开发证书,但该应用程序在后台不更新位置,尽管授权已设置为始终使用。
该应用程序已正确安装,因此我猜测证书是没有问题的,但我不明白为什么位置没有在后台更新。
我在iPhone 7上运行该应用程序,使用的是IOS 10.2,并且xcode自动管理签名。
以下是我的位置管理器配置:
public class LocationManager : NSObject, ModuleManager, CLLocationManagerDelegate {

    /// The core location manager
    let coreLocationManager: CLLocationManager

    public var datas: JSONable? {
        get {
            return LocationDatas(locations: self.locations)
        }

        set {
            self.locations = newValue == nil ? [Location]() : newValue as? [Location]
        }
    }

    /// The list of locations to send
    private var locations: [Location]?

    /// The last location
    public var lastLocation: Location? {
        return self.locations?.last
    }

    public override init() {

        self.coreLocationManager = CLLocationManager()
        if #available(iOS 9.0, *) {
            self.coreLocationManager.allowsBackgroundLocationUpdates = true
        }
        // The accuracy of the location data.
        self.coreLocationManager.desiredAccuracy = kCLLocationAccuracyBest;
        // The minimum distance (measured in meters) a device must move horizontally before an update event is generated.
        self.coreLocationManager.distanceFilter = 500; // meters
        self.locations = [Location]()

        super.init()
        self.coreLocationManager.delegate = self
        self.locationManager(self.coreLocationManager, didChangeAuthorizationStatus: CLLocationManager.authorizationStatus())

    }

    // MARK: - CLLocationManager Delegate

    public func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        NSLog("location update")
        guard locations.count > 0 else {
            NSLog("Module Location -- no location available")
            return
        }

        // Add all location waiting in the list to send
        self.locations?.appendContentsOf(locations.map { Location(cllocation: $0) })
        SDKManager.manager?.sendHeartbeat()
    }

    public func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        switch CLLocationManager.authorizationStatus() {
            case .NotDetermined:
                if #available(iOS 8.0, *) {
                    self.coreLocationManager.requestAlwaysAuthorization()
                } else {
                    self.coreLocationManager.startUpdatingLocation()
                }

            case .Denied, .Restricted:
                NSLog("Module Location -- access denied to use the location")

            case .AuthorizedAlways:
                NSLog("AuthorizedAlways")
                self.coreLocationManager.startUpdatingLocation()
                //self.coreLocationManager.startMonitoringSignificantLocationChanges()

            default:
                break
        }
    }

    public func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
        NSLog("Module Location -- error : \(error)")
    }
}
locationManager 函数在后台未被调用。
以下是我的 info.plist: enter image description here 以下是手机上的授权信息: enter image description here 小的位置箭头一直存在,但没有位置更新被记录。

你能够每次都成功调用 startUpdatingLocation() 吗? - Matt
是的,AuthorizedAlways始终被记录。 - Florian Courtial
你收到了“允许位置”提示吗? - Matt
是的,我有警报并且我说“是”。 - Florian Courtial
请查看以下链接以了解如何停止在iOS中多次调用didUpdateLocations方法:https://dev59.com/hmEh5IYBdhLWcg3wjD_n#46580983 - user8336100
2个回答

0

我已经检查了你的代码,看起来没问题,如果你已经完成了以下必要设置,请进行修订:

  1. 在后台模式下启用位置更新
  2. 在你的info.plist中添加NSLocationAlwaysUsageDescription

如果你没有完成第一个点,你的应用程序会崩溃,但如果你没有完成第二个点,你的代码将通过,但你将永远不会得到更新。

更新:

看起来你的LocationManager对象在ARC中被释放了。你能否尝试将你的LocationManager类更改为Singleton,并添加以下内容:

static let sharedInstance = LocationManager()

在您的代码中像这样访问LocationManager

LocationManager.sharedInstance

是的,我已经在原问题中更新了info.plist和手机应用程序授权的截图。我的假设是与证书有关。 - Florian Courtial
我刚刚看到答案,正在尝试。 - Florian Courtial
我更新了代码,启动了程序,30分钟后我会检查一下是否已经发送到新的位置。 - Florian Courtial
唯一的更新是通过后台获取完成的,但没有位置更新。 - Florian Courtial
同样的问题在这里。 - Alessandro Mattiuzzi

0

你不需要仅为后台位置更新使用应用程序后台刷新。 (它可以用于其他维护工作,如在充电时进行的数据库清理、上传、下载等)

在初始化coreLocationManager时,也要设置以下属性

// It will allow app running location updates in background state
coreLocationManager.allowsBackgroundLocationUpdates = true 

// It will not pause location automatically, you can set it true if you require it. 
coreLocationManager.pausesLocationUpdatesAutomatically = false 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接