SwiftLocation 是 Apple CoreLocation 框架的轻量级封装,支持新的 Swift 并发模型。
这意味着不再需要处理委托模式,也不再需要完成块。
您可以直接使用新的 async/await 语法来管理位置请求、区域和 Beacon 监控。
例如,您想获取当前用户的位置吗?
只需 2 行代码即可搞定
try await location.requestPermission(.whenInUse) // obtain the permissions
let userLocation = try await location.requestLocation() // get the location
SwiftLocation 非常易于使用。
只需创建您自己的 Location
实例并使用可用的方法之一。
重要提示
由于特定的硬件限制,某些 API 可能在某些受支持的平台上不可用。
新的 6.0 里程碑是一个完全重写的版本,旨在最佳地支持 async/await。我们还专注于支持所有 CoreLocation 功能,而不会创建一个过于臃肿的软件包。
所有功能都由完整的单元测试套件支持。
这个新版本也仅通过 Swift Package Manager (5.5+) 分发,并且与所有 Apple 平台兼容:iOS 14+、macOS 11+、watchOS 7+、tvOS 14+。
版本 5.x 中的功能 - 地理编码、IP 解析、自动完成 - 将在后续开发过程中作为单独的可下载模块包含。
使用 location.locationServicesEnabled
获取位置服务的当前状态。
为了监控更改,您可以使用 AsyncStream
的 `startMonitoringLocationServices()` 方法
for await event in await location.startMonitoringLocationServices() {
print("Location Services are \(event.isLocationEnabled ? "enabled" : "disabled")"
// break to interrupt the stream
}
您可以随时使用 break
停止流;它将在使用的 `Location` 实例上自动调用 `stopMonitoringLocationServices()`。
您可以使用 location.authorizationStatus
属性获取授权状态的当前状态。
如果您需要监控此值的更改,您可以使用 startMonitoringAuthorization()
方法提供的 AsyncStream
for await event in await location.startMonitoringAuthorization() {
print("Authorization status did change: \(event.authorizationStatus)")
// break to interrupt the stream
}
location.accuracyAuthorization
提供应用程序提供的当前精度级别的单次值。
当您需要监控更改时,您可以使用 startMonitoringAccuracyAuthorization()
提供的 AsyncStream
for await event in await location.startMonitoringAccuracyAuthorization() {
print("Accuracy authorization did change: \(event.accuracyAuthorization.description)")
// break to interrupt the stream
}
位置权限请求也通过 async await 管理。一旦您正确配置了 Info.plist
文件,您就可以使用 requestPermission()
方法
// return obtained CLAuthorizationStatus level
let obtaninedStatus = try await location.requestPermission(.whenInUse)
首次进行授权请求时,系统会显示一个警报,询问用户是否授予或拒绝该请求。警报包含一个使用描述字符串,用于解释您为何需要访问位置数据。
您在应用程序的 Info.plist 文件中提供此字符串,并使用它来告知用户您的应用程序如何使用位置数据。
Core Location 支持每个访问级别的不同使用字符串。您必须包含“使用时”访问的使用描述字符串。如果您的应用程序支持“始终”访问,请提供额外的字符串来解释您为何需要更高的权限。下表列出了要包含在 Info.plist 中的键以及何时包含它们。
使用键 | 何时需要 |
---|---|
NSLocationWhenInUseUsageDescription |
应用程序请求“使用时”或“始终”授权时。 |
NSLocationAlwaysAndWhenInUseUsageDescription |
应用程序请求“始终”授权时。 |
NSLocationTemporaryUsageDescriptionDictionary |
当您想要临时扩展您的授权级别的精度时使用 |
如果应用程序并非所有功能都需要精确位置,但仅在特定功能(例如,在结账、预订服务等期间)需要精确位置,则应用程序可以仅针对该会话使用 requestTemporaryPrecisionAuthorization(purpose:)
方法请求临时精度级别
// return CLAccuracyAuthorization value
let status = try await location.requestTemporaryPrecisionAuthorization(purpose: "booking")
如果您需要持续监控来自用户设备的新位置,您可以使用 startMonitoringLocations()
提供的 AsyncStream
for await event in try await location.startMonitoringLocations() {
switch event {
case .didPaused:
// location updates paused
case .didResume:
// location updates resumed
case let .didUpdateLocations(locations):
// new locations received
case let .didFailed(error):
// an error has occurred
}
// break to stop the stream
}
有时您可能需要将用户位置作为单个值获取。async 的 requestLocation(accuracy:timeout:)
方法旨在在有效的时间间隔内返回可选的过滤位置
// Simple implementation to get the last user location
let location = try await location.requestLocation()
// Optionally you can return a value only if satisfy one or more constraints
let location = try await location.requestLocation(accuracy: [
.horizontal(100) // has an horizontal accuracy of 100 meters or lower
], timeout: 8) // wait for response for a max of 8 seconds
过滤器包括水平/垂直、速度、航向精度,并提供设置自定义过滤器函数作为回调的机会。
访问监控允许您观察用户去过的地方。
访问对象由系统创建并由 CLLocationManager 传递。访问对象包括访问发生的位置以及关于到达和离开时间的相关信息。
要监控访问,您可以使用 AsyncStream
的 startMonitoringVisits()
方法
for await event in await location.startMonitoringVisits() {
switch event {
case let .didVisit(place):
// a new CLVisit object has been received.
case let .didFailWithError(error):
// an error has occurred
}
}
AsyncStream
的 startMonitoringSignificantLocationChanges()
方法启动基于重要位置变更的更新生成。
for await event in await self.location.startMonitoringSignificantLocationChanges() {
switch event {
case .didPaused:
// stream paused
case .didResume:
// stream resumed
case .didUpdateLocations(locations):
// new locations received
case let .didFailWithError(error):
// an error has occured
}
// break to stop the stream
}
要获取有关当前设备朝向的更新,请使用 startUpdatingHeading()
方法提供的 AsyncStream
for await event in await self.location.startUpdatingHeading() {
// a new heading value has been generated
}
Beacon 测距由 AsyncStream
的 startRangingBeacons()
方法提供
let constraint: CLBeaconIdentityConstraint = ...
for await event in await location.startRangingBeacons(satisfying: constraint) {
// a new event has been generated
}
SwiftLocation 分发时附带了一个广泛的单元测试套件,您可以在 SwiftLocationTests
文件夹中找到它。
在套件内部,您还将找到 MockedLocationManager.swift
文件,这是一个 CLLocationManager
模拟类,您可以使用它为您的应用程序提供测试套件。通过配置和扩展此文件,您将能够在您的宿主应用程序中直接模拟位置请求和监控的结果。
SwiftLocation 通过 Swift Package Manager 提供。
将其作为依赖项添加到 Swift Package 中,并将其添加到您的 Package.swift
中
dependencies: [
.package(url: "https://github.com/malcommac/SwiftLocation.git", from: "6.0.0")
]
如果您喜欢这个库并希望鼓励进一步开发,请考虑通过 Github Sponsorship 成为我工作的赞助商。
此软件包由 Daniele Margutti 创建和维护。
它使用 MIT 许可证 分发。
阅读 CONTRIBUTING 文件以获取更多信息。