SwiftUI-HealthKit中的DispatchQueue.main.async
我想在SwiftUI中加载以下GUI:SwiftUI-HealthKit中的DispatchQueue.main.async,swiftui,healthkit,Swiftui,Healthkit,我想在SwiftUI中加载以下GUI: import SwiftUI struct ContentView: View { @ObservedObject var test = Test() @ObservedObject var healthStore = HealthStore() func callUpdate() { print(test.value) print(healthSto
import SwiftUI
struct ContentView: View {
@ObservedObject var test = Test()
@ObservedObject var healthStore = HealthStore()
func callUpdate() {
print(test.value)
print(healthStore.systolicValue)
print(healthStore.diastolicValue)
}
var body: some View {
Text("Platzhalter")
.padding()
.onAppear(perform: {
healthStore.setUpHealthStore()
callUpdate()
})
Button("Test"){
callUpdate()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
变量healthStore.systolicValue和healthStore.diastolicValue通过函数callUpdate()调用。在第一次调用时,两个变量都为零。只有当我通过测试按钮调用函数时,控制台才会输出正确的值
变量healthStore.systolicValue和healthStore.diastolicValue在healthStore类中计算:
import Foundation
import HealthKit
class HealthStore: ObservableObject {
var healthStore: HKHealthStore?
var query: HKStatisticsQuery?
public var systolicValue: HKQuantity?
public var diastolicValue: HKQuantity?
init() {
if HKHealthStore.isHealthDataAvailable() {
healthStore = HKHealthStore()
}
}
func setUpHealthStore() {
let typesToRead: Set = [
HKQuantityType.quantityType(forIdentifier: .bloodPressureSystolic)!,
HKQuantityType.quantityType(forIdentifier: .bloodPressureDiastolic)!
]
healthStore?.requestAuthorization(toShare: nil, read: typesToRead, completion: { success, error in
if success {
print("requestAuthrization")
self.calculateBloodPressureSystolic()
self.calculateBloodPressureDiastolic()
}
})
}
func calculateBloodPressureSystolic() {
guard let bloodPressureSystolic = HKObjectType.quantityType(forIdentifier: .bloodPressureSystolic) else {
// This should never fail when using a defined constant.
fatalError("*** Unable to get the bloodPressure count ***")
}
query = HKStatisticsQuery(quantityType: bloodPressureSystolic,
quantitySamplePredicate: nil,
options: .discreteAverage) {
query, statistics, error in
DispatchQueue.main.async{
self.systolicValue = statistics?.averageQuantity()
}
}
healthStore!.execute(query!)
}
func calculateBloodPressureDiastolic() {
guard let bloodPressureDiastolic = HKObjectType.quantityType(forIdentifier: .bloodPressureDiastolic) else {
// This should never fail when using a defined constant.
fatalError("*** Unable to get the bloodPressure count ***")
}
query = HKStatisticsQuery(quantityType: bloodPressureDiastolic,
quantitySamplePredicate: nil,
options: .discreteAverage) {
query, statistics, error in
DispatchQueue.main.async{
self.diastolicValue = statistics?.averageQuantity()
}
}
healthStore!.execute(query!)
}
}
DispatchQueue.main.async{
// self.systolicValue = statistics?.averageQuantity()
self.systolicValue = HKQuantity(unit: HKUnit(from: ""), doubleValue: 1.2)
print("----> calculateBloodPressureSystolic statistics: \(statistics)")
print("----> calculateBloodPressureSystolic error: \(error)")
print("----> calculateBloodPressureSystolic: \(self.systolicValue)")
}
当我调用ContentView时,我需要如何修改代码以直接获得healthStore.systolicValue和healthStore.disatolicvalue的正确值?我想你差不多做到了。您的HealthStore需要为发布新值 收缩值和舒张值。不需要“callUpdate()”函数 我将对您的代码进行如下修改: (注意,一旦计算了systolicValue和DISATOLICVALUE,模型将更新,视图也将自动更新自身)
struct ContentView:View{
@ObservedObject变量healthStore=healthStore()
var body:一些观点{
VStack{
文本(“Platzhalter”)
文本(“systolicValue:\(healthStore.systolicValue)”)
文本(“舒张值:\(healthStore.diastolicValue)”)
}奥纳佩尔先生{
healthStore.setUpHealthStore()
}
}
}
类HealthStore:ObservableObject{
var healthStore:HKHealthStore?
var查询:HKStatisticsQuery?
@已发布的var systolicValue:HKQuantity?/@workingDog我按照建议更改了代码,但仍然无法从healthStore获得计算值
@ObservedObject var healthStore = HealthStore()
var bloodPressureStandard = HKQuantity(unit: HKUnit(from: ""), doubleValue: 0.0)
var body: some View {
VStack {
Text("systolicValue: \(healthStore.systolicValue ?? bloodPressureStandard)")
Text("diastolicValue: \(healthStore.diastolicValue ?? bloodPressureStandard)")
}.onAppear {
healthStore.setUpHealthStore()
}
}
您确定数据可用吗?要检查,请将其放入HealthStore:
import Foundation
import HealthKit
class HealthStore: ObservableObject {
var healthStore: HKHealthStore?
var query: HKStatisticsQuery?
public var systolicValue: HKQuantity?
public var diastolicValue: HKQuantity?
init() {
if HKHealthStore.isHealthDataAvailable() {
healthStore = HKHealthStore()
}
}
func setUpHealthStore() {
let typesToRead: Set = [
HKQuantityType.quantityType(forIdentifier: .bloodPressureSystolic)!,
HKQuantityType.quantityType(forIdentifier: .bloodPressureDiastolic)!
]
healthStore?.requestAuthorization(toShare: nil, read: typesToRead, completion: { success, error in
if success {
print("requestAuthrization")
self.calculateBloodPressureSystolic()
self.calculateBloodPressureDiastolic()
}
})
}
func calculateBloodPressureSystolic() {
guard let bloodPressureSystolic = HKObjectType.quantityType(forIdentifier: .bloodPressureSystolic) else {
// This should never fail when using a defined constant.
fatalError("*** Unable to get the bloodPressure count ***")
}
query = HKStatisticsQuery(quantityType: bloodPressureSystolic,
quantitySamplePredicate: nil,
options: .discreteAverage) {
query, statistics, error in
DispatchQueue.main.async{
self.systolicValue = statistics?.averageQuantity()
}
}
healthStore!.execute(query!)
}
func calculateBloodPressureDiastolic() {
guard let bloodPressureDiastolic = HKObjectType.quantityType(forIdentifier: .bloodPressureDiastolic) else {
// This should never fail when using a defined constant.
fatalError("*** Unable to get the bloodPressure count ***")
}
query = HKStatisticsQuery(quantityType: bloodPressureDiastolic,
quantitySamplePredicate: nil,
options: .discreteAverage) {
query, statistics, error in
DispatchQueue.main.async{
self.diastolicValue = statistics?.averageQuantity()
}
}
healthStore!.execute(query!)
}
}
DispatchQueue.main.async{
// self.systolicValue = statistics?.averageQuantity()
self.systolicValue = HKQuantity(unit: HKUnit(from: ""), doubleValue: 1.2)
print("----> calculateBloodPressureSystolic statistics: \(statistics)")
print("----> calculateBloodPressureSystolic error: \(error)")
print("----> calculateBloodPressureSystolic: \(self.systolicValue)")
}
同样,舒张值也是如此。这是我用于测试的完整代码,适用于我,
使用macos 11.4、xcode 12.5、目标ios 14.5,在iPhone设备上测试。
如果这对您不起作用,请告诉我们
import SwiftUI
import HealthKit
@main
struct TestErrorApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class HealthStore: ObservableObject {
var healthStore: HKHealthStore?
var query: HKStatisticsQuery?
@Published var systolicValue: HKQuantity?
@Published var diastolicValue: HKQuantity?
init() {
if HKHealthStore.isHealthDataAvailable() {
healthStore = HKHealthStore()
}
}
func setUpHealthStore() {
let typesToRead: Set = [
HKQuantityType.quantityType(forIdentifier: .bloodPressureSystolic)!,
HKQuantityType.quantityType(forIdentifier: .bloodPressureDiastolic)!
]
healthStore?.requestAuthorization(toShare: nil, read: typesToRead, completion: { success, error in
if success {
print("--> requestAuthorization")
self.calculateBloodPressureSystolic()
self.calculateBloodPressureDiastolic()
}
})
}
func calculateBloodPressureSystolic() {
guard let bloodPressureSystolic = HKObjectType.quantityType(forIdentifier: .bloodPressureSystolic) else {
// This should never fail when using a defined constant.
fatalError("*** Unable to get the bloodPressure count ***")
}
query = HKStatisticsQuery(quantityType: bloodPressureSystolic,
quantitySamplePredicate: nil,
options: .discreteAverage) {
query, statistics, error in
DispatchQueue.main.async{
// self.systolicValue = statistics?.averageQuantity()
self.systolicValue = HKQuantity(unit: HKUnit(from: ""), doubleValue: 1.2)
print("----> calculateBloodPressureSystolic statistics: \(statistics)")
print("----> calculateBloodPressureSystolic error: \(error)")
print("----> calculateBloodPressureSystolic: \(self.systolicValue)")
}
}
healthStore!.execute(query!)
}
func calculateBloodPressureDiastolic() {
guard let bloodPressureDiastolic = HKObjectType.quantityType(forIdentifier: .bloodPressureDiastolic) else {
// This should never fail when using a defined constant.
fatalError("*** Unable to get the bloodPressure count ***")
}
query = HKStatisticsQuery(quantityType: bloodPressureDiastolic,
quantitySamplePredicate: nil,
options: .discreteAverage) {
query, statistics, error in
DispatchQueue.main.async{
// self.diastolicValue = statistics?.averageQuantity()
self.diastolicValue = HKQuantity(unit: HKUnit(from: ""), doubleValue: 3.4)
print("----> calculateBloodPressureDiastolic statistics: \(statistics)")
print("----> calculateBloodPressureDiastolic error: \(error)")
print("----> calculateBloodPressureDiastolic: \(self.diastolicValue)")
}
}
healthStore!.execute(query!)
}
}
struct ContentView: View {
@ObservedObject var healthStore = HealthStore()
var bloodPressureStandard = HKQuantity(unit: HKUnit(from: ""), doubleValue: 0.0)
var body: some View {
VStack {
Text("systolicValue: \(healthStore.systolicValue ?? bloodPressureStandard)")
Text("diastolicValue: \(healthStore.diastolicValue ?? bloodPressureStandard)")
}.onAppear {
healthStore.setUpHealthStore()
}
}
}
这是我得到的输出:
-->请求授权
---->计算血压收缩统计:无
---->CalculateBloodPressureCystalError:可选(错误域=com.apple.healthkit Code=11“没有可用于指定谓词的数据。”UserInfo={NSLocalizedDescription=没有可用于指定谓词的数据。})
---->CalculateBloodPressureSytocol:可选(1.2())
---->计算血压舒张统计:无
---->CalculateBloodPressureDistributor错误:可选(错误域=com.apple.healthkit Code=11“指定谓词没有可用数据。”UserInfo={NSLocalizedDescription=指定谓词没有可用数据。})
---->计算血压舒张压:可选(3.4())
用户界面显示:
系统价值:1.2()
舒张值:3.4()我发现了错误:
我在HealthStore类中声明变量systolicValue和DISATOLICVALUE是错误的。我将它们声明为public,而不是@Published。正确的代码是:
@Published var systolicValue: HKQuantity?
@Published var diastolicValue: HKQuantity?
谢谢您的帮助。这是我的输出:-->CalculateBloodPressureStoryStorial statistics:Optional()------>CalculateBloodPressureStory错误:nil-->CalculateBloodPressureStoryStorial:Optional(1.2())很高兴听到您找到了原因。请将答案标记为正确,谢谢。