【发布时间】:2021-03-06 11:45:06
【问题描述】:
我想开发从 Health kit(正念时间)加载数据的视图,因此我每 1 分钟使用 Timer 从 Apple watch 创建的 Health kit 中获取新数据,但 onReceive(Timer) 不会刷新新数据(它只传递以前的数据)
如果我打开另一个应用程序并回到这个应用程序,那么它会显示一个新数据
import SwiftUI
struct LoadingView: View {
var healthStore : HealthStore? = HealthStore()
@State private var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
@State var num : Int = 0
@Binding var showModal: Bool
var decription : String
// MARK: - BODY
var body: some View {
VStack (alignment: .center){
Spacer()
WatchView()
Spacer()
Text(decription)
.font(.callout)
.fontWeight(.semibold)
.padding(.horizontal,30)
Spacer()
}
.navigationBarBackButtonHidden(true)
.onReceive(timer) { _ in
if let healthStore = healthStore {
healthStore.requestAuthorization { success in
if success {
healthStore.getDailyMindfulnessTime { time in
print("\(time)")
}
} //: SUCCESS
}
}
}// ON RECEIVE
.onDisappear(perform: {
self.timer.upstream.connect().cancel()
})//ON DISAPPEAR
}
}
健康商店
import Foundation
import HealthKit
class HealthStore {
var healthStore : HKHealthStore?
var query : HKStatisticsCollectionQuery?
var querySampleQuery : HKSampleQuery?
init(){
// to check data is avaliable or not?
if HKHealthStore.isHealthDataAvailable(){
//Create instance of HKHealthStore
healthStore = HKHealthStore()
}
}
// Authorization
func requestAuthorization(compleion: @escaping(Bool)-> Void){
let stepType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount)!
let mindfulSampleType = HKSampleType.categoryType(forIdentifier: .mindfulSession)!
guard let healthStore = self.healthStore else { return compleion(false)}
healthStore.requestAuthorization(toShare: [], read: [stepType,mindfulSampleType]) { (success, error) in
compleion(success)
}
}
//Calculate steps count
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)
//cumulativeSum (Watch+Iphone)
query = HKStatisticsCollectionQuery(quantityType: stepType, quantitySamplePredicate: predicate, options: .cumulativeSum, anchorDate: anchorDate, intervalComponents: daily)
query!.initialResultsHandler = { query, statisticsCollection , error in
completion(statisticsCollection)
}
if let healthStore = self.healthStore, let query = self.query {
healthStore.execute(query)
}
}
// DailyMindfulnessTime
func getDailyMindfulnessTime(completion: @escaping (TimeInterval) -> Void) {
let sampleType = HKSampleType.categoryType(forIdentifier: .mindfulSession)!
let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)
let startDate = Calendar.current.startOfDay(for: Date())
let endDate = Calendar.current.date(byAdding: .day, value: 1, to: startDate)
let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: .strictStartDate)
querySampleQuery = HKSampleQuery(sampleType: sampleType, predicate: predicate, limit: HKObjectQueryNoLimit, sortDescriptors: [sortDescriptor]) { (_, results, error) in
if error != nil {
print(" HealthKit returned error while trying to query today's mindful sessions. The error was: \(String(describing: error?.localizedDescription))")
}
if let results = results {
var totalTime = TimeInterval()
for result in results {
totalTime += result.endDate.timeIntervalSince(result.startDate)
}
completion(totalTime)
} else {
completion(0)
}
}
if let healthStore = self.healthStore, let querySampleQuery = self.querySampleQuery {
healthStore.execute(querySampleQuery)
}
}
}
extension Date {
static func mondayAt12AM() -> Date{
return Calendar(identifier: .iso8601).date(from: Calendar(identifier: .iso8601).dateComponents([.yearForWeekOfYear,.weekOfYear],from: Date()))!
}
}
【问题讨论】: