LocationProvider

一个基于 Combine 的 CoreLocation 提供者。

每次从包装的 CLLocationManager 更新设备位置时,它都会提供最新的位置作为已发布的 CLLocation 对象,并通过名为 locationWillChangePassthroughSubject<CLLocation, Never> 发布。

用法

启动 LocationProvider

初始化并启动 LocationProvider

import LocationProvider

let locationProvider = LocationProvider()

do {
    try locationProvider.start()
}
catch {
    // handle the lack of authorization, e.g. by
    // locationProvider.requestAuthorization()
}

需要捕获潜在的位置访问授权错误 LocationProviderError.noAuthorization

请求位置访问权限

可以通过以下方式弹出标准位置访问用户对话框:

locationProvider.requestAuthorization()

默认情况下,它会请求 authorizedWhenInUse 类型的访问权限。

LocationProvider 具有一个属性 onAuthorizationStatusDenied,用于定义在当前位置访问被拒绝的情况下要执行的操作。 默认操作是显示一个警报 (presentLocationSettingsAlert()),建议进入应用程序设置屏幕以更改位置设置。

处理位置数据

订阅 locationWillChange subject 并存储返回的 Cancellable

cancellableLocation = locationProvider.locationWillChange.sink { loc in
    // handleLocation(loc)
}

sink 闭包中的 handleLocation 函数将在 LocationProvider 发送的每个 CLLocation 对象上执行。

停止 LocationProvider

停止 LocationProvider 并取消订阅

locationProvider.stop()
cancellableLocation?.cancel()

在 SwiftUI 中使用

此外,LocationProvider 是一个 ObservableObject,它具有一个 @Published 属性 location,用于更新 ObservableObject。 可观察的 LocationProvider 及其 location 属性可以直接在 SwiftUI 中访问。

import SwiftUI
import LocationProvider

struct ContentView: View {
    @StateObject var locationProvider = LocationProvider()
    
    var body: some View {
        VStack{
            Text("latitude \(locationProvider.location?.coordinate.latitude ?? 0)")
            Text("longitude \(locationProvider.location?.coordinate.longitude ?? 0)")
        }
        .onAppear {
            do {try locationProvider.start()} 
            catch {
                print("No location access.")
                locationProvider.requestAuthorization()
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

在 Info.plist 中设置正确的属性

为了使应用程序可以访问用户位置,应在 Info.plist 中设置以下键:

默认情况下,该软件包在后台请求位置访问权限。 因此,还请在 Info.plistLocation 添加到 UIBackgroundModes,或者在通过 locationProvider.start() 启动位置更新之前,设置 locationProvider.lm.allowsBackgroundLocationUpdates = false

示例代码

一个使用 SwiftUI 中的 LocationProvider 的最小可用 iOS 应用程序可以在这里找到:https://github.com/himbeles/LocationProviderExample

支持我

如果您喜欢这个软件包并想支持我,

Buy Me A Coffee