일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- ios
- retain cycle
- garbage collection
- layoutSubviews
- Firebase
- Automatic Reference Count
- Xcode
- Github-Action
- Tuist
- HealthKit
- authentication
- playground
- fetchSignInMethods
- YGEnums.h
- Swift
- SPM
- Nan
- human interface guidelines
- 회고
- AppStore
- Tuist-Action
- App Connect
- FlexLayout
- alamofire
- arc
- HIG
- UITest
- rc
- pagination
- content-type
- Today
- Total
멋있게걷는방법
[Swift] HealthKit 설정과 데이터 요청 (distanceWalkingRunning, activeEnergyBurned, appleExerciseTime) 본문
[Swift] HealthKit 설정과 데이터 요청 (distanceWalkingRunning, activeEnergyBurned, appleExerciseTime)
도현D 2023. 3. 7. 23:43프로젝트에서 HealthKit 을 사용했던 경험을 바탕으로 글을 적어보려고 합니다.🙂
HealthKit 이란?
HealthKit 은 사용자의 건강 정보를 받아올 수 있는데요.
아이폰에 건강이라는 앱에 들어가면 자신의 건강 정보를 확인할 수 있는데요. 이 데이터를 사용하는 기술입니다.
애플워치가 꼭 필요한가?
= 애플워치가 없더라도 괜찮습니다!
애플워치가 있다면, 애플워치를 착용했을 때의 이동한 거리나 피트니스 정보가 플러스 된다는 장점이 있습니다.
하지만 애플워치 셀룰러가 아니라면 거의 아이폰도 함께 갖고 다니니까 애플워치가 없더라도 충분합니다.
HKHealthStore
HKHealthStore 의 공식문서를 보면 'HealthKit에서 관리하는 모든 데이터의 액세스 포인트' 라고 합니다.
이 클래스를 이용하여 HealthKit 데이터를 공유하거나 읽을 수 있는 권한을 요청할 수 있습니다.
사용하려면 먼저..
먼저 Info 에서 위 사진처럼 키를 추가하여 문자열을 입력해주세요. ( 권한을 요청할 때 앱 설명에 쓰입니다.)
그리고,
Target -> Signing & Capabilities -> +Capability -> HealthKit 추가
위 과정을 실행해주시면
이렇게 뜰텐데 그럼 준비는 끝났습니다!
(저는 걷기 + 달리기 거리, 운동 시간, 활동 에너지 데이터를 불러오려고 합니다!)
let healthStore = HKHealthStore()
let read: Set = [HKSampleType.quantityType(forIdentifier: .distanceWalkingRunning)!,
HKSampleType.quantityType(forIdentifier: .activeEnergyBurned)!,
HKSampleType.quantityType(forIdentifier: .appleExerciseTime)!]
let share: Set = [HKSampleType.quantityType(forIdentifier: .distanceWalkingRunning)!,
HKSampleType.quantityType(forIdentifier: .activeEnergyBurned)!]
func requestAuthorization() {
healthStore.requestAuthorization(toShare: share, read: read) { success, _ in
if success {
print("success")
} else {
print("faild")
}
}
}
주의!
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Authorization to share the following types is disallowed: HKQuantityTypeIdentifierAppleExerciseTime'
위 처럼 문제가 발생하는 이유는 저같은 경우 .appleExerciseTime 을 share 에도 추가했기 때문이었습니다.
( 앞에 apple 이 붙은 프로퍼티를 사용할 때에는 read 에만 추가해야합니다!! )
위 함수를 성공적으로 실행하면 이래와 같은 화면을 보실 수 있을 겁니다.
이제 사용자가 접근 권한을 허용해주면 바로 데이터를 불러올 수 있습니다.
어떻게 불러오지?
제가 사용했던 코드를 예시로 들면,
func getDistanceWalkingRunning() {
let stepType = HKQuantityType.quantityType(forIdentifier: .distanceWalkingRunning)!
let second = TimeZone.autoupdatingCurrent.secondsFromGMT(for: Date())
let now = Date().addingTimeInterval(TimeInterval(second))
var dateComponents = Calendar.current.dateComponents([.year, .month, .day], from: Date())
dateComponents.timeZone = TimeZone(abbreviation: "ko")
let dateWithTime = Calendar.current.date(from: dateComponents)!
let startDate = Calendar.current.date(byAdding: .day, value: -6, to: dateWithTime)!
let daily = DateComponents(day: 1)
let exactlySevenDaysAgo = Calendar.current.date(byAdding: DateComponents(day: -7), to: dateWithTime)!
let oneWeekAgo = HKQuery.predicateForSamples(withStart: exactlySevenDaysAgo,
end: now, options: .strictStartDate)
let query = HKStatisticsCollectionQuery(quantityType: stepType,
quantitySamplePredicate: oneWeekAgo,
options: .cumulativeSum,
anchorDate: startDate,
intervalComponents: daily)
query.initialResultsHandler = { _, result, _ in
if let results = result {
results.enumerateStatistics(from: startDate, to: now) { [weak self] statistic, _ in
if let count = statistic.sumQuantity() {
let val = count.doubleValue(for: HKUnit.meter())
self?.distanceWalkingRunningData.append(round((val / 1000) * 10) / 10)
} else {
self?.distanceWalkingRunningData.append(0)
}
}
}
}
healthStore.execute(query)
}
위 코드는 오늘을 기준으로 저번 주 일주일동안 걷기 + 달리기 데이터를 가져오는 코드입니다.
이 함수를 권한 요청이 success 일 때 실행시키면 바로 값을 가져오지않고 함수 실행이 끝난 뒤에 동작하기 때문에
viewWillAppear 같은 곳에서 이 데이터를 가지고 UI 에 반영할 일이 있다면 viewWillDisAppear 나 다른 주기를 갖는 함수를 사용해야 하는 것 같더라구요.
시간대 설정에서 어려움이 있었습니다.
저는 데이터를 가져오는 시간대를 설정하는 곳에서 어려움이 있었는데,
처음엔 현재 시간 ~ 내일 현재 시간의 데이터를 가져왔더니 건강 앱과 동일한 데이터도 아닐 뿐더러, 내일 날짜의 현재 시간까지의 데이터를 요청하다보니 nil 로 반환되는 문제가 있었습니다.
이렇게 해봤어요.
그래서, 00시 ~ 내일 00시까지의 데이터를 가져오면 정확한 데이터를 가져올 수 있겠다 생각해
DateComponents 를 이용해 오늘 날짜까지만 가져오도록 함으로써 시간을 00으로 초기화 할 수 있었고, timeZone 을 한국으로 설정했습니다.
결과적으로 건강 앱과 동일한 데이터를 가져올 수 있었습니다.
내용에 틀린 부분이 있다면 알려주세요!🙇🏻
'iOS' 카테고리의 다른 글
[Swift] firebase - 이메일 중복 검사 (0) | 2023.04.12 |
---|---|
[UITest] password textFiled 에 tap 이 안 될 때? (0) | 2023.04.04 |
[Swift] Alamofire 를 쓴다면 꼭 알아야 하는 내용 (0) | 2023.03.23 |
[Swift] 값이 NaN 으로 변한다구요? (0) | 2023.01.09 |
나의 첫 App Store 심사 회고 (1) | 2022.10.10 |