在iOS 14小部件中获取当前位置 [英] Fetching current location in iOS 14 Widget
问题描述
是否有人试图在iOS 14小部件中更新用户的位置?在阅读了Apple Developer论坛之后,我想出了围绕 CLLocationManager
的书写包装,并以此方式使用它:
Has anyone tried to update user's location in iOS 14 Widget?
After reading Apple Developer forums I've come up with the writing wrapper around CLLocationManager
and using it this way:
class WidgetLocationManager: NSObject, CLLocationManagerDelegate {
var locationManager: CLLocationManager? {
didSet {
self.locationManager!.delegate = self
}
}
private var handler: ((CLLocation) -> Void)?
func fetchLocation(handler: @escaping (CLLocation) -> Void) {
self.handler = handler
self.locationManager!.requestLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
self.handler!(locations.last!)
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)
}
}
并以这种方式使用它:
var widgetLocationManager = WidgetLocationManager()
func getTimeline(for configuration: SelectPlaceIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
if widgetLocationManager.locationManager == nil {
widgetLocationManager.locationManager = CLLocationManager()
widgetLocationManager.locationManager!.requestWhenInUseAuthorization()
}
widgetLocationManager.fetchLocation(handler: { location in
print(location)
.......
})
}
在Widget的 info.plist
中我也有这两个条目:
I also have these 2 entries in Widget's info.plist
:
<key>NSLocationUsageDescription</key>
<string>1</string>
<key>NSWidgetWantsLocation</key>
<true/>
当调用locationManager.requestLocation()时,授权状态为authorisedWhenInUse,但从未调用委托的方法.我想念什么?
When locationManager.requestLocation() is being called, authorisation status is authorisedWhenInUse, but delegate's method is never being called. What am I missing?
推荐答案
首先,我看到的明显问题是
First of all, the obvious problem that I see:
<key>NSLocationUsageDescription</key>
<string>1</string>
NSLocationUsageDescription
已弃用: Apple文档,因此您应该改用 NSLocationWhenInUseUsageDescription
或 NSLocationAlwaysAndWhenInUseUsageDescription
.确保在主应用程序 Info.plist
中也包含您选择的权限
NSLocationUsageDescription
is deprecated: Apple Documentation , so you should be using NSLocationWhenInUseUsageDescription
or NSLocationAlwaysAndWhenInUseUsageDescription
instead. Be sure to include the permission that you choose in main apps Info.plist
as well
此外,在
func getTimeline(for configuration: SelectPlaceIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
...
}
可能会出现问题,因为它可以从后台线程中调用,所以我将像这样重构您的 WidgetLocationManager
:
might be problematic, since it can get called from background thread, so I would refactor your WidgetLocationManager
like this:
class WidgetLocationManager: NSObject, CLLocationManagerDelegate {
var locationManager: CLLocationManager?
private var handler: ((CLLocation) -> Void)?
override init() {
super.init()
DispatchQueue.main.async {
self.locationManager = CLLocationManager()
self.locationManager!.delegate = self
if self.locationManager!.authorizationStatus == .notDetermined {
self.locationManager!.requestWhenInUseAuthorization()
}
}
}
func fetchLocation(handler: @escaping (CLLocation) -> Void) {
self.handler = handler
self.locationManager!.requestLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
self.handler!(locations.last!)
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)
}
}
,然后像这样使用它:
var widgetLocationManager = WidgetLocationManager()
func getTimeline(for configuration: SelectPlaceIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
widgetLocationManager.fetchLocation(handler: { location in
print(location)
.......
})
}
这篇关于在iOS 14小部件中获取当前位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!