【问题标题】:locationManager didUpdateLocations crashing in suspend modelocationManager didUpdateLocations 在挂起模式下崩溃
【发布时间】:2019-05-08 06:23:52
【问题描述】:

当我的屏幕被锁定超过 10 秒左右并且我的位置发生变化时,会触发 didUpdateLocations 但代码在大约中途停止执行。具体来说,它停在以下行:print("locationManager: triggering toggleStatus")。它执行 print 语句,但不会更进一步。我尝试用其他代码替换对 eco?.toggleStatus() 函数的调用,它仍然在 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() 开头的打印语句,它包含对导致崩溃的钥匙串项的引用。此钥匙串引用与 didUpdate 函数中的引用之间的区别在于它存储在使用 SwiftKeychainWrapper 创建的钥匙串中。我之前在开发应用程序时遇到了 SwiftKeychainWrapper 的其他一些问题,并在编写其余代码时切换到 KeychainSwift。出于纯粹懒惰的原因(这个应用程序只适合我),我从未返回并切换过 toggleStatus() 中的值。删除引用允许 toggleStatus() 继续。我仍在改变一切,但这似乎已经解决了问题。

【问题讨论】:

  • 崩溃的完整错误信息是什么?究竟是哪条线路导致了崩溃?
  • 功能 > 后台模式 > 位置更新是否启用?

标签: swift cllocationmanager locationmanager


【解决方案1】:

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

假设您的设备启用了 Touch ID/Face ID 并且设备已锁定。现在,当应用程序接收到位置更新时,它将尝试访问钥匙串,但设备被锁定并启用了 Touch ID / Face ID。这种组合有时有效,有时无效。不过,我正在寻找为什么会发生这种情况。

【讨论】:

  • 我很确定这个答案是正确的。我检查了 toggleStatus() 开头的打印语句,它包含对钥匙串项的引用,它正在停止我删除它,并且 toggleStatus 继续,直到它碰到另一个钥匙串项。我现在正在重新工作,但很确定删除钥匙串引用可以解决问题。
  • 谢谢杰夫。如果您认为正确,请点赞并采纳答案
  • 我还不能投票。显然你需要一个声誉分数(我很新)。不过好像有人做过。再次感谢您的解决方案!
  • 谢谢杰夫。但你可以接受答案。请检查
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多