iOS模拟器无法读取我保存的健康数据
iOS Simulator Cannot Read the Health Data I Saved
我创建了一个应用程序来保存和读取一些 运行 和步行锻炼数据到 HealthKit。
我设法保存了数据,并在模拟器的 Health 应用程序上查看了它,但是当我尝试读取数据时,样本计数为 0。如果有人能帮我解决这个问题,我将不胜感激。
Xcode 12.5.1 / iOS 14.5
func AuthenticateHealthKit() {
print("AuthenticateHealthKit")
let typesToShare: Set = [
HKQuantityType.workoutType()
]
let typesToRead: Set = [
HKQuantityType.workoutType(),
HKQuantityType.quantityType(forIdentifier: .distanceWalkingRunning)!,
HKQuantityType.quantityType(forIdentifier: .height)!,
]
healthStore.requestAuthorization(toShare: typesToShare, read: typesToRead) { (success, error) in
if !success {
fatalError("Error requesting authorization from health store: \(String(describing: error)))")
} else {
print("Authenticated!")
}
}
}
func SaveData() {
let configuration = HKWorkoutConfiguration()
configuration.activityType = .running
configuration.locationType = Int.random(in: 0..<2) == 0 ? .indoor : .outdoor
let startDate = now - (86400 * 60.0)
let duration = 120.0
let endDate = startDate + duration
let quantity = HKQuantity(unit: HKUnit.kilocalorie(), doubleValue: 20.0)
let distance = HKQuantity(unit: HKUnit.meter(), doubleValue: 1200)
let workout = HKWorkout(
activityType: configuration.activityType, start: startDate, end: endDate, duration: duration,
totalEnergyBurned: quantity, totalDistance: distance,
metadata: [HKMetadataKeyIndoorWorkout: true])
healthStore.save(workout) { success, _ in
if success {
print("SAVED WORKOUT!!!")
} else {
print("COULD NOT SAVE WORKOUT!!!")
}
}
}
func ReadData() {
let start = now - (86400 * 60.0)
let end = now
let predicate = HKQuery.predicateForSamples(withStart: start, end: end, options: [])
print("start : \(start)")
guard HKHealthStore.isHealthDataAvailable() else {
print("No data available!")
return
}
guard
let sampleType = HKSampleType.quantityType(
forIdentifier: HKQuantityTypeIdentifier.distanceWalkingRunning)
else {
fatalError("*** This method should never fail ***")
}
let query = HKSampleQuery(
sampleType: sampleType, predicate: predicate, limit: Int(HKObjectQueryNoLimit),
sortDescriptors: nil
) {
query, results, error in
guard let samples = results as? [HKQuantitySample] else {
print("Error")
return
}
for sample in samples {
print("sample : \(sample.quantity) \(sample.quantityType)")
}
DispatchQueue.main.async {
print("Update UI : \(samples.count)")
}
}
healthStore.execute(query)
}
这里是 ReadData 方法的输出
start : 2021-08-14 21:38:35 +0000
Authenticated!
Update UI : 0
以下是 Health App 数据和权限(全部在模拟器上)
您正在写锻炼但想阅读远距离步行+运行。在锻炼中节省距离 属性 并不会节省步行距离+运行 样本。您需要创建该类型的样本,为其请求授权,然后使用 HKHealthStore 上的 addSamples 方法保存并关联锻炼。
最好使用 HKWorkoutBuilder,它的 beginCollection/add/endCollection/finishWorkout 方法会为您创建合适的 HKWorkout 对象。
我已经设法保存了可以使用 ReadData 方法读取的数据(查看原始问题)。这是新的 SaveData 方法:
let now = Date()
func SaveData() {
let configuration = HKWorkoutConfiguration()
configuration.activityType = .running
configuration.locationType = Int.random(in: 0..<2) == 0 ? .indoor : .outdoor
let builder = HKWorkoutBuilder(healthStore: healthStore, configuration: configuration, device: .local())
let sample = HKCumulativeQuantitySample(type: HKSampleType.quantityType(forIdentifier: HKQuantityTypeIdentifier.distanceWalkingRunning)!, quantity: HKQuantity.init(unit: HKUnit.meter(), doubleValue: 1230), start: now - 3600, end: now)
builder.add([sample]) { success, error in
guard success else {
print("Error!")
return
}
print("Added Sample")
}
}
我创建了一个应用程序来保存和读取一些 运行 和步行锻炼数据到 HealthKit。 我设法保存了数据,并在模拟器的 Health 应用程序上查看了它,但是当我尝试读取数据时,样本计数为 0。如果有人能帮我解决这个问题,我将不胜感激。
Xcode 12.5.1 / iOS 14.5
func AuthenticateHealthKit() {
print("AuthenticateHealthKit")
let typesToShare: Set = [
HKQuantityType.workoutType()
]
let typesToRead: Set = [
HKQuantityType.workoutType(),
HKQuantityType.quantityType(forIdentifier: .distanceWalkingRunning)!,
HKQuantityType.quantityType(forIdentifier: .height)!,
]
healthStore.requestAuthorization(toShare: typesToShare, read: typesToRead) { (success, error) in
if !success {
fatalError("Error requesting authorization from health store: \(String(describing: error)))")
} else {
print("Authenticated!")
}
}
}
func SaveData() {
let configuration = HKWorkoutConfiguration()
configuration.activityType = .running
configuration.locationType = Int.random(in: 0..<2) == 0 ? .indoor : .outdoor
let startDate = now - (86400 * 60.0)
let duration = 120.0
let endDate = startDate + duration
let quantity = HKQuantity(unit: HKUnit.kilocalorie(), doubleValue: 20.0)
let distance = HKQuantity(unit: HKUnit.meter(), doubleValue: 1200)
let workout = HKWorkout(
activityType: configuration.activityType, start: startDate, end: endDate, duration: duration,
totalEnergyBurned: quantity, totalDistance: distance,
metadata: [HKMetadataKeyIndoorWorkout: true])
healthStore.save(workout) { success, _ in
if success {
print("SAVED WORKOUT!!!")
} else {
print("COULD NOT SAVE WORKOUT!!!")
}
}
}
func ReadData() {
let start = now - (86400 * 60.0)
let end = now
let predicate = HKQuery.predicateForSamples(withStart: start, end: end, options: [])
print("start : \(start)")
guard HKHealthStore.isHealthDataAvailable() else {
print("No data available!")
return
}
guard
let sampleType = HKSampleType.quantityType(
forIdentifier: HKQuantityTypeIdentifier.distanceWalkingRunning)
else {
fatalError("*** This method should never fail ***")
}
let query = HKSampleQuery(
sampleType: sampleType, predicate: predicate, limit: Int(HKObjectQueryNoLimit),
sortDescriptors: nil
) {
query, results, error in
guard let samples = results as? [HKQuantitySample] else {
print("Error")
return
}
for sample in samples {
print("sample : \(sample.quantity) \(sample.quantityType)")
}
DispatchQueue.main.async {
print("Update UI : \(samples.count)")
}
}
healthStore.execute(query)
}
这里是 ReadData 方法的输出
start : 2021-08-14 21:38:35 +0000
Authenticated!
Update UI : 0
以下是 Health App 数据和权限(全部在模拟器上)
您正在写锻炼但想阅读远距离步行+运行。在锻炼中节省距离 属性 并不会节省步行距离+运行 样本。您需要创建该类型的样本,为其请求授权,然后使用 HKHealthStore 上的 addSamples 方法保存并关联锻炼。
最好使用 HKWorkoutBuilder,它的 beginCollection/add/endCollection/finishWorkout 方法会为您创建合适的 HKWorkout 对象。
我已经设法保存了可以使用 ReadData 方法读取的数据(查看原始问题)。这是新的 SaveData 方法:
let now = Date()
func SaveData() {
let configuration = HKWorkoutConfiguration()
configuration.activityType = .running
configuration.locationType = Int.random(in: 0..<2) == 0 ? .indoor : .outdoor
let builder = HKWorkoutBuilder(healthStore: healthStore, configuration: configuration, device: .local())
let sample = HKCumulativeQuantitySample(type: HKSampleType.quantityType(forIdentifier: HKQuantityTypeIdentifier.distanceWalkingRunning)!, quantity: HKQuantity.init(unit: HKUnit.meter(), doubleValue: 1230), start: now - 3600, end: now)
builder.add([sample]) { success, error in
guard success else {
print("Error!")
return
}
print("Added Sample")
}
}