저는 Apple Watch를위한 운동 앱을 개발 중이며 실제 시계에서 HealthKit을 사용하여 몇 가지 문제가 발생했습니다.HealthKit 인증이 시뮬레이터에서 승인되었지만 실제 장치에서는 작동하지 않습니다.
요청 권한은 시뮬레이터와 내 장치 모두에서 작동하며 매 출시마다 성공적으로 표시됩니다. 그러나 샘플을 쿼리하고 읽는 것은 내 장치에서는 실패하지만 시뮬레이터에서는 실패합니다.
성공적인 인증과 함께 운동을 쿼리하거나 저장해야하는 경우 "인증이 결정되지 않았습니다"라고 표시됩니다.
자격 키가 모두 HealthKit을 YES로 설정하고 HealthKit 및 백그라운드 기능이 켜져 있고 NSHealthShareUsageDescription 및 NSHealthUpdateUsageDescription 키가 iOS Info.plist에 제공됩니다.
인증 코드
// Configure write values
let writeTypes: Set<HKSampleType> = [.workoutType(),
HKSampleType.quantityType(forIdentifier: .heartRate)!,
HKSampleType.quantityType(forIdentifier: .activeEnergyBurned)!,
HKSampleType.quantityType(forIdentifier: .stepCount)!,
HKSampleType.quantityType(forIdentifier: .distanceCycling)!,
HKSampleType.quantityType(forIdentifier: .distanceSwimming)!,
HKSampleType.quantityType(forIdentifier: .distanceWalkingRunning)!,
HKSampleType.quantityType(forIdentifier: .swimmingStrokeCount)!]
// Configure read values
let readTypes: Set<HKObjectType> = [.activitySummaryType(), .workoutType(),
HKObjectType.quantityType(forIdentifier: .heartRate)!,
HKObjectType.quantityType(forIdentifier: .activeEnergyBurned)!,
HKObjectType.quantityType(forIdentifier: .stepCount)!,
HKObjectType.quantityType(forIdentifier: .distanceCycling)!,
HKObjectType.quantityType(forIdentifier: .distanceSwimming)!,
HKObjectType.quantityType(forIdentifier: .distanceWalkingRunning)!,
HKObjectType.quantityType(forIdentifier: .swimmingStrokeCount)!]
// Create health store
let healthStore = HKHealthStore()
// Use it to request authorization for our types
healthStore.requestAuthorization(toShare: writeTypes, read: readTypes) { (success, error) in
if success {
print("Success: authorization granted")
} else {
print("Error: \(error?.localizedDescription ?? "")")
}
}
쿼리 코드 (Udemy 코스)
func startQuery(_ quantityTypeIdentifier: HKQuantityTypeIdentifier) {
// We only want data points after our workout start date
let datePredicate = HKQuery.predicateForSamples(withStart: workoutStartDate, end: nil, options: .strictStartDate)
// And from our current device
let devicePredicate = HKQuery.predicateForObjects(from: [HKDevice.local()])
// Combine them
let queryPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [datePredicate, devicePredicate])
// Write code to receive results from our query
let updateHandler: (HKAnchoredObjectQuery, [HKSample]?, [HKDeletedObject]?, HKQueryAnchor?, Error?) -> Void = { query, samples, deletedObjects, queryAnchor, error in
//safely typecast to a quantity sample so we can read values
guard let samples = samples as? [HKQuantitySample] else { return }
//process the samples
print("Start processing samples")
self.process(samples, type: quantityTypeIdentifier)
}
// Create the query out of our type (e.g. heart rate), predicate and result handling code
let quantityType = HKObjectType.quantityType(forIdentifier: quantityTypeIdentifier)!
let query = HKAnchoredObjectQuery(type: quantityType, predicate: queryPredicate, anchor: nil, limit: HKObjectQueryNoLimit, resultsHandler: updateHandler)
// Tell HealthKit to re-run the code every time new data is available
query.updateHandler = updateHandler
// Start the query running
healthStore.execute(query)
// Stach it away so we can stop it later
activeDataQueries.append(query)
}