Fetching current location in iOS 14 Widget

后端 未结 1 1239
情深已故
情深已故 2021-01-05 13:46

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

相关标签:
1条回答
  • 2021-01-05 14:02

    First of all, the obvious problem that I see:

    <key>NSLocationUsageDescription</key>
    <string>1</string>
    

    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

    Additionally, creating CLLocationManager in

    func getTimeline(for configuration: SelectPlaceIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
        ...
    }
    

    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)
        }
    }
    

    and later use it like this:

    var widgetLocationManager = WidgetLocationManager()
    
    func getTimeline(for configuration: SelectPlaceIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
        widgetLocationManager.fetchLocation(handler: { location in
            print(location)
            .......
        })
    }
    
    0 讨论(0)
提交回复
热议问题