HealthKit 会不断更新模拟器上的样本数据,但不会更新 Apple Watch 上的实际数据
Posted
技术标签:
【中文标题】HealthKit 会不断更新模拟器上的样本数据,但不会更新 Apple Watch 上的实际数据【英文标题】:HealthKit keeps updating the sample data on a simulator, but not the actual data on apple watch 【发布时间】:2021-09-13 12:39:41 【问题描述】:我刚开始使用 WWDC 开源学习 swift。我正在学习如何创建手表操作系统锻炼应用程序。当我在模拟器上运行它时,它会不断更新示例数据,但在我的 Apple Watch 上,当我运行它时,它不会不断更新实时锻炼数据。我确信我必须处理下面的代码,但是
extension WorkoutManager: HKLiveWorkoutBuilderDelegate
func workoutBuilderDidCollectEvent(_ workoutBuilder: HKLiveWorkoutBuilder)
func workoutBuilder(_ workoutBuilder: HKLiveWorkoutBuilder, didCollectDataOf collectedTypes: Set<HKSampleType>)
for type in collectedTypes
guard let quantityType = type as? HKQuantityType else
return // Nothing to do.
let statistics = workoutBuilder.statistics(for: quantityType)
// Update the published values.
updateForStatistics(statistics)
我不知道调用 HealthKit 时究竟发生了什么,我从 WWDC 示例中获取了大部分代码。
import Foundation
import HealthKit
class WorkoutManager: NSObject, ObservableObject
var selectedWorkout: HKWorkoutActivityType?
didSet
guard let selectedWorkout = selectedWorkout else return
startWorkout(workoutType: selectedWorkout)
@Published var showingSummaryView: Bool = false
didSet
if showingSummaryView == false
resetWorkout()
let healthStore = HKHealthStore()
var session: HKWorkoutSession?
var builder: HKLiveWorkoutBuilder?
func startWorkout(workoutType: HKWorkoutActivityType)
let configuration = HKWorkoutConfiguration()
configuration.activityType = workoutType
configuration.locationType = .outdoor
// Create the session and obtain the workout builder.
do
session = try HKWorkoutSession(healthStore: healthStore, configuration: configuration)
builder = session?.associatedWorkoutBuilder()
catch
// Handle any exceptions.
return
// Set the workout builder's data source.
builder?.dataSource = HKLiveWorkoutDataSource(healthStore: healthStore,
workoutConfiguration: configuration)
session?.delegate = self
builder?.delegate = self
// Start the workout session and begin data collection.
let startDate = Date()
session?.startActivity(with: startDate)
builder?.beginCollection(withStart: startDate) (success, error) in
// The workout has started.
func requestAuthorization()
// The quantity type to write to the health store.
let typesToShare: Set = [
HKQuantityType.workoutType()
]
// The quantity types to read from the health store.
let typesToRead: Set = [
HKQuantityType.quantityType(forIdentifier: .heartRate)!,
HKObjectType.activitySummaryType()
]
// Request authorization for those quantity types.
healthStore.requestAuthorization(toShare: typesToShare, read: typesToRead) (success, error) in
// Handle error.
// MARK: - Session State Control
// The app's workout state.
@Published var running = false
func togglePause()
if running == true
self.pause()
else
resume()
func pause()
session?.pause()
func resume()
session?.resume()
func endWorkout()
session?.end()
showingSummaryView = true
// MARK: - Workout Metrics
@Published var averageHeartRate: Double = 0
@Published var heartRate: Double = 0
@Published var workout: HKWorkout?
func updateForStatistics(_ statistics: HKStatistics?)
guard let statistics = statistics else return
DispatchQueue.main.async
switch statistics.quantityType
case HKQuantityType.quantityType(forIdentifier: .heartRate):
let heartRateUnit = HKUnit.count().unitDivided(by: HKUnit.minute())
self.heartRate = statistics.mostRecentQuantity()?.doubleValue(for: heartRateUnit) ?? 0
self.averageHeartRate = statistics.averageQuantity()?.doubleValue(for: heartRateUnit) ?? 0
default:
return
func resetWorkout()
selectedWorkout = nil
builder = nil
workout = nil
session = nil
averageHeartRate = 0
heartRate = 0
extension WorkoutManager: HKWorkoutSessionDelegate
func workoutSession(_ workoutSession: HKWorkoutSession, didChangeTo toState: HKWorkoutSessionState,
from fromState: HKWorkoutSessionState, date: Date)
DispatchQueue.main.async
self.running = toState == .running
// Wait for the session to transition states before ending the builder.
if toState == .ended
builder?.endCollection(withEnd: date) (success, error) in
self.builder?.finishWorkout (workout, error) in
DispatchQueue.main.async
self.workout = workout
func workoutSession(_ workoutSession: HKWorkoutSession, didFailWithError error: Error)
extension WorkoutManager: HKLiveWorkoutBuilderDelegate
func workoutBuilderDidCollectEvent(_ workoutBuilder: HKLiveWorkoutBuilder)
func workoutBuilder(_ workoutBuilder: HKLiveWorkoutBuilder, didCollectDataOf collectedTypes: Set<HKSampleType>)
for type in collectedTypes
guard let quantityType = type as? HKQuantityType else
return // Nothing to do.
let statistics = workoutBuilder.statistics(for: quantityType)
// Update the published values.
updateForStatistics(statistics)
【问题讨论】:
developer.apple.com/wwdc21/10009 【参考方案1】:您是否在Info.plist
中启用了Workout processing
后台模式?
【讨论】:
是的,它已启用。以上是关于HealthKit 会不断更新模拟器上的样本数据,但不会更新 Apple Watch 上的实际数据的主要内容,如果未能解决你的问题,请参考以下文章
HealthKit 授权已授予并在模拟器上工作,但不在实际设备上
此 HealthKit 错误的原因是啥:“将样本添加到锻炼时发生错误”?