HealthKitReporter
关于
HealthKit Apple 框架数据操作的包装器。该库支持操作来自 HealthKit 仓库的值,并将它们转换为 Codable 模型,允许将结果编码为简单的 JSON 有效负载。此外,您可以使用 Codable 包装器编写自己的 HealthKit 对象,这些对象将被转换为 HealthKit 仓库中的 HKObjectType 对象。
开始
准备
首先,在您的应用程序权限中选中HealthKit,并在您的应用程序的info.plist文件中添加权限
<key>NSHealthShareUsageDescription</key>
<string>WHY_YOU_NEED_TO_SHARE_DATA</string>
<key>NSHealthUpdateUsageDescription</key>
<string>WHY_YOU_NEED_TO_USE_DATA</string>
如果您计划使用WorkoutRoute 系列,请另外提供CoreLocation权限
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>WHY_YOU_NEED_TO_ALWAYS_SHARE_LOCATION</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>WHY_YOU_NEED_TO_SHARE_LOCATION</string>
通用用法
您在一个do catch块中创建一个HealthKitReporter实例。如果苹果健康不支持该设备(例如iPad),则会调用catch块。
报告实例包含几个属性
- 读取器
- 写入器
- 管理者
- 观察者
每个属性都负责HealthKit框架的相应部分。从命名可以看出,读取器将处理有关读取数据的所有操作,而写入器将处理与HealthKit库中写入相关的一切,观察者将处理观察并通知 HealthKit 中是否发生任何更改,管理者负责读写类型的授权和启动您制作的WatchApp。
如果您想读取、写入数据或观察数据更改,您必须始终确保数据类型已授权进行读取/写入/观察。在这种情况下,manager使用一个完成块的方法来授权,其中通知授权窗口的出现。注意,苹果健康库将在整个应用程序安装期间仅显示此窗口一次,在这种情况下,如果某些类型被拒绝读取或写入,用户应手动在苹果健康应用程序中允许此操作。
以下示例中,每个操作都在授权块内发生。这样做是有推荐性的,因为如果添加了新类型,则将抛出权限异常。如果确认没有新类型出现,您可以在应用程序中调用授权块外的操作,前提是已授予该类型的数据读取/写入权限。
读取数据
创建一个HealthKitReporter实例。
授权读取所需类型,如步数。
如果授权成功(显示授权窗口),调用步数类型的样本查询以创建一个Query
对象。
使用报告者的manager
的executeQuery执行查询。 (或stopQuery停止)
do {
let reporter = try HealthKitReporter()
let types = [QuantityType.stepCount]
reporter.manager.requestAuthorization(
toRead: types,
toWrite: types
) { (success, error) in
if success && error == nil {
reporter.manager.preferredUnits(for: types) { (preferredUnits, error) in
if error == nil {
for preferredUnit in preferredUnits {
do {
let query = try reporter.reader.quantityQuery(
type: try QuantityType.make(from: preferredUnit.identifier),
unit: preferredUnit.unit
) { (results, error) in
if error == nil {
for element in results {
do {
print(try element.encoded())
} catch {
print(error)
}
}
} else {
print(error)
}
}
reporter.manager.executeQuery(query)
} catch {
print(error)
}
}
} else {
print(error)
}
}
} else {
print(error)
}
}
} catch {
print(error)
}
以下是步数的样本响应
{
"sourceRevision" : {
"productType" : "iPhone8,1",
"systemVersion" : "14.0.0",
"source" : {
"name" : "Guy’s iPhone",
"bundleIdentifier" : "com.apple.health.47609E07-490D-4E5F-8E68-9D8904E9BA08"
},
"version" : "14.0"
},
"harmonized" : {
"value" : 298,
"unit" : "count"
},
"device" : {
"softwareVersion" : "14.0",
"manufacturer" : "Apple Inc.",
"model" : "iPhone",
"name" : "iPhone",
"hardwareVersion" : "iPhone8,1"
},
"endTimestamp" : 1601066077.5886581,
"identifier" : "HKQuantityTypeIdentifierStepCount",
"startTimestamp" : 1601065755.8829093
}
写入数据
创建一个HealthKitReporter实例。
授权写入所需类型,如步数。
您可以调用管理器的
如果授权成功(显示授权窗口),请调用包含步骤计数的保存方法。
do {
let reporter = try HealthKitReporter()
let types = [QuantityType.stepCount]
reporter.manager.requestAuthorization(
toRead: types,
toWrite: types
) { (success, error) in
if success && error == nil {
reporter.manager.preferredUnits(for: types) { (preferredUnits, error) in
for preferredUnit in preferredUnits {
//Do write steps
let identifier = preferredUnit.identifier
guard
identifier == QuantityType.stepCount.identifier
else {
return
}
let now = Date()
let quantity = Quantity(
identifier: identifier,
startTimestamp: now.addingTimeInterval(-60).timeIntervalSince1970,
endTimestamp: now.timeIntervalSince1970,
device: Device(
name: "Guy's iPhone",
manufacturer: "Guy",
model: "6.1.1",
hardwareVersion: "some_0",
firmwareVersion: "some_1",
softwareVersion: "some_2",
localIdentifier: "some_3",
udiDeviceIdentifier: "some_4"
),
sourceRevision: SourceRevision(
source: Source(
name: "mySource",
bundleIdentifier: "com.kvs.hkreporter"
),
version: "1.0.0",
productType: "CocoaPod",
systemVersion: "1.0.0.0",
operatingSystem: SourceRevision.OperatingSystem(
majorVersion: 1,
minorVersion: 1,
patchVersion: 1
)
),
harmonized: Quantity.Harmonized(
value: 123.0,
unit: preferredUnit.unit,
metadata: nil
)
)
reporter.writer.save(sample: quantity) { (success, error) in
if success && error == nil {
print("success")
} else {
print(error)
}
}
}
}
} else {
print(error)
}
}
} catch {
print(error)
}
提示:如果您在选择要保存的对象的单位时遇到困难,可以调用管理器的一个函数
reporter.manager.preferredUnits(for: [.stepCount]) { (dictionary, error) in
for (identifier, unit) in dictionary {
print("\(identifier) - \(unit)")
}
}
观测数据
创建一个HealthKitReporter实例。
授权读取/写入所需类型,如步数和睡眠分析。
您可能创建一个HealthKit每次都会调用的应用,并接收通知,指示HealthKit中某些数据已更改,具体取决于频率。但请注意,有时您设置的所需频率可能无法由HealthKit满足。
在您的AppDelegate的方法中调用观测查询方法。这将允许Apple Health在应用在后台中发送事件,甚至在它之前已处于"不运行"状态时唤醒应用并执行observerQuery更新处理程序提供的代码。
警告:要使应用被系统杀掉时运行observerQuery,提供一个额外的功能Background Mode并选择Background fetch。
使用报告者的manager
的executeQuery执行查询。 (或stopQuery停止)
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
do {
let reporter = try HealthKitReporter()
let types: [SampleType] = [
QuantityType.stepCount,
CategoryType.sleepAnalysis
]
reporter.manager.requestAuthorization(
toRead: types,
toWrite: types
) { (success, error) in
if success && error == nil {
for type in types {
do {
let query = try reporter.observer.observerQuery(
type: type
) { (query, identifier, error) in
if error == nil && identifier != nil {
print("updates for \(identifier!)")
}
}
reporter.observer.enableBackgroundDelivery(
type: type,
frequency: .daily
) { (success, error) in
if error == nil {
print("enabled")
}
}
reporter.manager.executeQuery(query)
} catch {
print(error)
}
}
}
}
} catch {
print(error)
}
return true
}
示例
要运行示例项目,请复制存储库,并首先从示例目录运行pod install
。
需求
库支持iOS 9及以上版本。一些特性,如HKHeartbeatSeries,从iOS 13.0开始可用,而HKElectrocardiogramm则从iOS 14.0开始可用。
安装
Cocoapods
HealthKitReporter通过CocoaPods提供。要安装它,只需将以下行添加到您的Podfile中
pod 'HealthKitReporter'
或者
pod 'HealthKitReporter', '~> 3.0.0'
Swift Package Manager
要安装它,只需将以下行添加到您的Package.swift文件中(或者只需从XCode中使用包管理器并引用此存储库)
dependencies: [
.package(url: "https://github.com/VictorKachalov/HealthKitReporter.git", from: "3.0.0")
]
Carthage
在您的Cartfile中添加此行
github "VictorKachalov/HealthKitReporter" "3.0.0"
作者
维克多·卡夏洛夫,[保密邮箱]
许可证
HealthKitReporter 在 MIT 许可证下可用。更多信息请参阅 LICENSE 文件。
赞助
如果您认为我的仓库帮助您解决了困难,请不要害羞,请赞助吧!:-)