Nik*_*nov 7 core-location ios swift widgetkit
有没有人尝试过在 iOS 14 Widget 中更新用户的位置?在阅读了 Apple Developer 论坛后,我想出了编写包装器CLLocationManager并以这种方式使用它:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
并以这种方式使用它:
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)
.......
})
}
Run Code Online (Sandbox Code Playgroud)
我在 Widget 中也有这 2 个条目info.plist:
<key>NSLocationUsageDescription</key>
<string>1</string>
<key>NSWidgetWantsLocation</key>
<true/>
Run Code Online (Sandbox Code Playgroud)
当 locationManager.requestLocation() 被调用时,授权状态是 authorisedWhenInUse,但委托的方法永远不会被调用。我错过了什么?
首先,我看到的明显问题:
<key>NSLocationUsageDescription</key>
<string>1</string>
Run Code Online (Sandbox Code Playgroud)
NSLocationUsageDescription已弃用:Apple Documentation,因此您应该使用NSLocationWhenInUseUsageDescription或NSLocationAlwaysAndWhenInUseUsageDescription代替。请务必在主应用程序Info.plist中也包含您选择的权限
此外,CLLocationManager在创建
func getTimeline(for configuration: SelectPlaceIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
...
}
Run Code Online (Sandbox Code Playgroud)
可能有问题,因为它可以从后台线程调用,所以我会WidgetLocationManager像这样重构你:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
var widgetLocationManager = WidgetLocationManager()
func getTimeline(for configuration: SelectPlaceIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
widgetLocationManager.fetchLocation(handler: { location in
print(location)
.......
})
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2154 次 |
| 最近记录: |