首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从HealthKit查询更新SwiftUI

从HealthKit查询更新SwiftUI
EN

Stack Overflow用户
提问于 2021-05-09 21:22:13
回答 1查看 75关注 0票数 1

我想在SwiftUI中通过ContentView输出变量'healthStore.valueTest‘。

healtStore类的结构如下:

代码语言:javascript
运行
复制
class HealthStore {
    
    var healthStore: HKHealthStore?
    var query: HKStatisticsQuery?
    var valueTest: HKQuantity?
    
    
    init() {
        if HKHealthStore.isHealthDataAvailable() {
            healthStore = HKHealthStore()
        }
    }
    
    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 ***")
        }

        
//        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)
        
        query = HKStatisticsQuery(quantityType: bloodPressureSystolic,
                                                quantitySamplePredicate: nil,
                                                options: .discreteAverage) {
                                                query, statistics, error in
            
                                                DispatchQueue.main.async{
                                                    self.valueTest = statistics?.averageQuantity()
                                                }

                                                    
        }
        
        healthStore!.execute(query!)
        
    }
}

ContentView的构建方式如下:

代码语言:javascript
运行
复制
import SwiftUI
import HealthKit

struct ContentView: View {
    
    private var healthStore: HealthStore?
               
    init() {
        healthStore = HealthStore()
    }
    
    
    var body: some View {
        Text("Hello, world!")
            .padding().onAppear(){
                
        if let healthStore = healthStore {
            healthStore.requestAuthorization { success in
                if success {
                    healthStore.calculateBloodPressureSystolic()
                    print(healthStore.query)
                    print(healthStore.valueTest)
                    }
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

变量self.valueTest的值在process DispatchQueue.main.async中赋值。然而,当我通过ContentView查询时,我只得到了一个nil的返回值。

EN

Stack Overflow用户

发布于 2021-05-09 22:25:57

您可以设置HealthStore类并将其用作EnvironmentObject。假设您的应用程序使用SwiftUI生命周期,您可以在应用程序的@main入口点将HealthStore注入到环境中。

代码语言:javascript
运行
复制
import SwiftUI

@main
struct NameOfYourHeathApp: App {

    let healthStore = HealthStore()

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(healthStore)
        }
    }
}

将您的HealthStore类更改为以下内容。(我在下面的示例中删除了您注释掉的代码)

代码语言:javascript
运行
复制
import HealthKit

class HealthStore: ObservableObject {

    var healthStore: HKHealthStore?
    var query: HKStatisticsQuery?
    var valueTest: HKQuantity?

    init() {
        if HKHealthStore.isHealthDataAvailable() {
            healthStore = HKHealthStore()
        }
    }

    // I moved the HealthStore conditional check out of your View logic 
    // and placed it here instead.
    func setUpHealthStore() {
        let typesToRead: Set = [
            HKQuantityType.quantityType(forIdentifier: .bloodPressureSystolic)!
        ]

        // I left the `toShare` as nil as I did not dig into adding bloodpressure reading to HealthKit.
        healthStore?.requestAuthorization(toShare: nil, read: typesToRead, completion: { success, error in
            if success {
                self.calculateBloodPressureSystolic()
            }
        })

    }

    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.valueTest = statistics?.averageQuantity()
            }
        }

        healthStore!.execute(query!)
    }
}

然后像这样在你的ContentView中使用它。

代码语言:javascript
运行
复制
import SwiftUI

struct ContentView: View {

    @EnvironmentObject var healthStore: HealthStore

    var body: some View {
        Text("Hello, world!")
            .onAppear {
                healthStore.setUpHealthStore()
            }
    }
}

我没有在.plist文件中设置适当的权限,但是您还需要设置Health Share使用描述和Health Update使用描述。我假设你已经这样做了,但我只是想提一下。

票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67458210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档