locationManager didUpdateLocations在挂起模式下崩溃

时间:2019-05-08 06:23:53

标签: swift cllocationmanager locationmanager

当我的屏幕被锁定超过10秒钟左右并且我的位置发生变化时,didUpdateLocations被触发,但是代码在中途停止执行。具体来说,它停在以下行:print(“ locationManager:triggering toggleStatus”)。它执行print语句,但不会更进一步。我尝试用其他代码替换对eco?.toggleStatus()函数的调用,但在print语句后仍然停止。无论print语句下面的代码是什么。 locationManager.allowsBackgroundLocationUpdates设置为true。

我正在使用真实的iPhone来测试此代码。我注意到,当模拟器处于锁定模式时,代码将贯穿模拟器的整个过程(包括调用和执行toggleStatus())。我猜这是因为模拟器只是将应用程序置于后台模式,而不是将其挂起,但我不确定。

需要注意的另一件事:几周前,我在iPhone上测试了此代码,它似乎可以正常工作,包括在手机锁定时。几周后,我注意到它在打印声明中停止了。

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    let location = locations[locations.count - 1]

    if location.horizontalAccuracy > 0 {

        var latitude = round(location.coordinate.latitude*1000000)/1000000
        let longitude = round(location.coordinate.longitude*1000000)/1000000
        print("locationManager: latitude is: \(latitude)")
        print("locationManager: longitude is: \(longitude)")


        if settingNewHomeLocation == true {
            keychain.set(String(format:"%f", latitude), forKey: "bLatitude", withAccess: .accessibleAlways)
            keychain.set(String(format:"%f", longitude), forKey: "bLongitude", withAccess: .accessibleAlways)
            print("base latitude is: \(keychain.get("bLatitude")!)")
            print("base longitude is: \(keychain.get("bLongitude")!)")
            settingNewHomeLocation = false
        }

        if keychain.get("bLatitude") != nil { 

            let bLatitude = Double(keychain.get("bLatitude")!)
            let bLongitude = Double(keychain.get("bLongitude")!)

            let baseLocation = CLLocation(latitude: bLatitude!, longitude: bLongitude!)
            let distance = CLLocation(latitude: latitude, longitude: longitude).distance(from: baseLocation)
            print("locationManager: distance is: \(distance)")

            if distance > 100 {

                print("locationManager: triggering toggleStatus")
                eco?.toggleStatus()
            }

        } else {
            print("No home location set")
        }
    }
}

解决方案:以下Anand的解决方案(删除钥匙串参考)似乎是正确的。我在toggleStatus()的开头检查了print语句,它包含对钥匙串项目的引用,这导致了崩溃。该钥匙串引用与didUpdate函数中的区别在于,它存储在使用SwiftKeychainWrapper创建的钥匙串中。在开发应用程序时,我较早时遇到了SwiftKeychainWrapper的其他问题,而在编写其余代码时切换到KeychainSwift。出于纯粹的懒惰(此应用仅适合我)的原因,我从未回过头来切换toggleStatus()中的值。删除引用可以使toggleStatus()继续。我仍然在更改所有内容,但这似乎已经解决了问题。

1 个答案:

答案 0 :(得分:1)

似乎您将位置详细信息存储在钥匙串中。当应用程序处于挂起状态时访问钥匙串将不会总是没有错误。对于背景案例,它的行为是完全怪异的。在设备中启用触摸ID /面部ID时,锁定设备会使情况变得更加复杂。

比方说,您的设备已启用触摸ID /面部ID,并且设备已锁定。现在,当应用接收位置更新时,它将尝试访问钥匙串,但设备已启用触摸ID /面部ID锁定。这种组合有时会起作用,有时则不会。不过,我正在搜索为什么会这样。