使用CLLocationManager.locationServicesEnabled()时的主线程警告

31

我刚升级到Xcode 14.0,在iOS 16设备上运行我们的应用程序时,调用:

CLLocationManager.locationServicesEnabled()

会返回警告:

如果在主线程上调用此方法,可能会导致UI无响应。相反,考虑等待 -locationManagerDidChangeAuthorization: 回调并首先检查 authorizationStatus.

如果必须等待失败/回调而不是直接调用 CLLocationManager.locationServicesEnabled() 方法,则我需要对我的代码进行重大更改。这似乎仅在iOS 16设备上发生。有什么建议吗?


如果你没有授权,难道不需要请求授权吗?如果你有授权,那么这将是苹果要求你在此实现的相同代码(即无论当前授权状态如何,都要请求授权并处理异步响应)。 - timbre timbre
2
@khjfquantumjj 你知道 authorizationStatuslocationServicesEnabled() 返回的是两个完全不同的状态,对吧? - AlanSTACK
@AlanSTACK 请仔细阅读问题。根据 OP 收到的警告,可能是他正在尝试在用户未授权访问位置服务的情况下获取 locationServicesEnabled,而授权是获得 locationServicesEnabled 状态的先决条件。 - timbre timbre
1
没有任何建议的解决方案对我起作用。我不得不重新配置我的代码,将这个调用移出主线程。我找不到其他的方法来解决它。 - nurider
1
@akjndklskver @AlanSTACK,您可以在没有权限的情况下检查CLLocationManager实例上的authorizationStatus。如果用户未授予权限,则状态将为“denied”。 - bugloaf
@bugloaf 你错了:状态可能被拒绝,因为用户仅针对该应用禁用: 1)如果您禁用位置服务:status = denied, locationServicesEnabled = false 2)如果您仅针对您的应用禁用位置服务:status = denied, locationServicesEnabled = true 3)如果您为两者都启用:status = always/while using.., locationServicesEnabled = true - yonivav
3个回答

32

使用调度队列将其移出主队列,如下所示:

DispatchQueue.global().async {
      if CLLocationManager.locationServicesEnabled() {
      // your code here
      }
}

你好,如果locationServicesEnabled返回false,如何停止下面的代码呢?谢谢。 - famfamfam
@famfamfam,问题到底是什么?显然,“if {}”中的代码只有在locationServicesEnabled为true时才会运行,否则我们没有任何要“停止”的代码。 - Yohst
1
另外两个选项是使用Task.detached包装或在任务中使用async let enabled = CLLocationManager.locationServicesEnabled(),然后在await enabled。有什么意见,哪个更好? - David

10

我遇到了同样的问题,但是通过使用Async/Await解决了它。

CLLocationManager调用包装在异步函数中。

func locationServicesEnabled() async -> Bool {
    CLLocationManager.locationServicesEnabled()
}

然后更新您使用此函数的地方。
Task { [weak self] in

    if await self?.locationServicesEnabled() { 
        // Do something
    }
}

6
这仍然给我同样的警告。 - akaakoz
1
如果在主线程上调用此方法,可能会导致UI无响应。相反,考虑等待“-locationManagerDidChangeAuthorization:”回调并首先检查“authorizationStatus”。 - Zack117
是的,上面的示例代码应该考虑到任务继承它们实例化的上下文。 - Marcos Curvello

-1
在我的情况下,我不得不将main.async和global().async分开,以便在后台检查一些选项。

目前来看,你的回答不够清晰。请编辑以添加更多细节,帮助他人理解这如何解答所提问题。您可以在帮助中心找到关于如何撰写好答案的更多信息。 - Community

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