【发布时间】:2023-01-24 01:38:45
【问题描述】:
在我的应用程序的主屏幕中,我有一个包含用户步骤的 Capsule()。这些数据是通过 HealthKit 获得的。数据是正确的,但是当它在健康应用程序中发生变化时,它应该在我的应用程序中发生变化,但这并没有发生。我如何获取'steps'变量来监听HealthKit,我的代码中一定有错误。
这是我的主页视图的代码:
import SwiftUI
import HealthKit
struct Home: View {
@ObservedObject var healthStore = HealthStore()
@State private var steps: [Step] = [Step]()
init() {
healthStore = HealthStore()
}
private func updateUIFromStatistics(_ statisticsCollection: HKStatisticsCollection) {
let startDate = Date()
let endDate = Date()
statisticsCollection.enumerateStatistics(from: startDate, to: endDate) { (statistics, stop) in
let count = statistics.sumQuantity()?.doubleValue(for: .count())
let step = Step(count: Int(count ?? 0), date: statistics.startDate)
steps.append(step)
}
}
var body: some View {
NavigationView {
ScrollView {
ZStack {
Color("BackgroundColour")
.ignoresSafeArea()
VStack {
let totalSteps = steps.reduce(0) { $0 + $1.count }
ForEach($steps, id: \.id) { step in
Button(action: {
// Perform button action here
print("Step Capsule Tapped...")
}) {
HStack {
Image("footsteps")
Text("\(totalSteps)")
}
}
} // ForEach End
} // VStack End
}//ZStack End
.edgesIgnoringSafeArea(.all)
} // ScrollView End
.background(Color("BackgroundColour"))
.onLoad {
healthStore.requestAuthorization { success in
if success {
healthStore.calculateSteps { statisticsCollection in
if let statisticsCollection = statisticsCollection {
// update the UI
updateUIFromStatistics(statisticsCollection)
}
}
}
}
} // .onLoad End
.onAppear(perform: {
let defaults = UserDefaults.standard
let keyString: String? = defaults.string(forKey: "key") ?? ""
print("User's Key:\(keyString ?? "")")
}) // .onAppear End
} // NavigationView End
}
}
HealthStore 的代码如下:
import Foundation
import HealthKit
import SwiftUI
import Combine
class HealthStore: ObservableObject {
@Published var healthStore: HKHealthStore?
@Published var query: HKStatisticsCollectionQuery?
init() {
if HKHealthStore.isHealthDataAvailable() {
healthStore = HKHealthStore()
}
}
func calculateSteps(completion: @escaping (HKStatisticsCollection?)-> Void) {
let stepType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!
let startDate = Calendar.current.date(byAdding: .day, value: -7, to: Date())
let anchorDate = Date.mondayAt12AM()
let daily = DateComponents(day: 1)
let predicate = HKQuery.predicateForSamples(withStart: startDate, end: Date(), options: .strictStartDate)
let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates:
[.init(format: "metadata.%K != YES", HKMetadataKeyWasUserEntered), predicate]
)
query = HKStatisticsCollectionQuery(
quantityType: stepType,
quantitySamplePredicate: compoundPredicate,
options: .cumulativeSum,
anchorDate: anchorDate,
intervalComponents: daily)
query!.initialResultsHandler = { query, statisticsCollection, error in
completion(statisticsCollection)
}
if let healthStore = healthStore, let query = self.query {
healthStore.execute(query)
}
}
func requestAuthorization(completion: @escaping (Bool) -> Void) {
let stepType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!
guard let healthStore = self.healthStore else { return completion(false) }
healthStore.requestAuthorization(toShare: [], read: [stepType]) { (success, error) in
completion(success)
}
}
}
extension Date {
static func mondayAt12AM() -> Date {
return Calendar(identifier: .iso8601).date(from: Calendar(identifier: .iso8601).dateComponents([.yearForWeekOfYear, .weekOfYear], from: Date()))!
}
}
这是步骤的代码:
import Foundation
struct Step: Identifiable {
let id = UUID()
let count: Int
let date: Date
}
下面是 Home 视图中使用的 .onLoad 方法的代码:
import SwiftUI
struct ViewDidLoadModifier: ViewModifier {
@State private var didLoad = false
private let action: (() -> Void)?
init(perform action: (() -> Void)? = nil) {
self.action = action
}
func body(content: Content) -> some View {
content.onAppear {
if didLoad == false {
didLoad = true
action?()
}
}
}
}
extension View {
func onLoad(perform action: (() -> Void)? = nil) -> some View {
modifier(ViewDidLoadModifier(perform: action))
}
}
有任何想法吗?
【问题讨论】:
-
您在
Home中两次初始化healthStore,可能与您的问题无关,但仍然是您应该解决的问题。
标签: ios swift swiftui healthkit