스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
HealthKit의 새로운 기능
건강 및 피트니스 앱에 HealthKit 기능을 구현할 수 있습니다. 수면 단계를 통해 보다 상세한 수면 데이터를 캡처하고, 향상된 운동 API를 통해 수영-자전거-달리기 및 인터벌 운동을 추적하며, 개인 정보를 보호하면서 실제 처방전의 이미지를 포함한 시력 처방을 HealthKit에 직접 저장하는 방법을 보여드리겠습니다.
리소스
-
다운로드
♪ 잔잔한 힙합 연주 음악 ♪ ♪ 안녕하세요 WWDC에 오신 걸 환영합니다 제 이름은 Karim이고 저는 HealthKit 엔지니어입니다 HealthKit 프레임워크는 멋진 건강 체험을 구축하기 위한 기반을 제공하고 Apple Watch는 건강 및 안전 기능들로 가득하며 그것들은 여러분을 위해 이것저것을 감시해줍니다 가장 인기 있는 것 중 하나는 수면 추적 기능입니다 우린 보다 상세한 수면 데이터를 확보하기 위해 업데이트를 하고 있습니다 그 외에도 올해 HealthKit에 새롭게 추가한 멋진 것들이 더 있습니다 우린 API를 강화해서 Swift 비동기 기능으로 데이터에 대한 조회를 더 쉽게 만들었습니다 운동에 대한 보다 풍부한 묘사로 그걸 개선하고 있습니다 그리고 우린 시력 처방전 저장에 대한 지원을 추가하는데 여기에는 실제 처방전의 디지털 사본도 포함됩니다 이런 여러 업데이트와 여러분의 앱이 그것들을 활용할 수 있는 방법을 자세히 알려드리게 되어 기쁩니다 그럼 시작해보죠 수면은 매우 본질적인 기능으로 우리 육체와 정신이 재충전할 수 있게 해주죠 저는 Apple Watch를 써서 제 수면 일정을 관리하고 수면을 잘 알고 개선하게 하는 통찰력을 얻는 걸 참 좋아합니다 올해 우리는 수면 추적 기능을 크게 개선하고 있습니다 수면 단계를 도입해서요 Apple Watch는 여러분이 수면 중에 겪게 되는 다양한 수면 단계를 자동으로 추적하고 이 데이터는 건강 앱에서 볼 수 있고 HealthKit에 저장됩니다 물론 여러분의 앱은 수면 단계 데이터를 읽고 저장할 수 있습니다 Apple Watch나 여러분 앱에 저장된 수면 데이터는 범주 샘플별로 HealthKit에 표시됩니다 sleepAnalysis 식별자로요 우린 세 가지 수면 단계를 지원합니다 렘수면, 얕은 수면 깊은 수면입니다 HealthKit에 수면 데이터를 저장할 때 반드시 해야 하는 건 주어진 수면 단계에서 각각의 지속되는 시간에 대한 하나의 샘플을 만드는 겁니다 수면 샘플 값인 enum은 이런 모습입니다 우린 세 가지 케이스를 추가해서 수면 단계를 표현합니다 먼저 asleepCore가 있습니다 이건 미국수면의학협회, 즉 AASM의 평점 모델에서 1, 2단계에 해당됩니다 asleepDeep은 AASM 평점 모델의 3단계에 해당하고 마지막으로 asleepREM은 급속 안구 운동 단계에 해당됩니다 수면 단계를 추가했으니 우린 asleep 케이스를 없애고 asleepUnspecified를 넣습니다 이는 사용자가 자고 있긴 하지만 수면 단계는 명시되지 않았다는 걸 표시합니다 업데이트된 수면 샘플 enum으로 이제 HealthKit에서 수면 단계 데이터를 저장하고 읽는 게 가능해졌습니다 우리 새로운 프레디케이트를 넣어 주어진 단계에서 수면 샘플을 읽는 걸 쉽게 했습니다 제가 렘수면 단계의 수면 샘플을 읽고 싶다고 가정해보죠 우선 프레디케이트를 만듭니다 새로운 predicateForSamples 기법을 사용하고 asleepREM을 그 값으로요 이제 저는 제 쿼리를 구축하기 시작할 수 있습니다 제 쿼리에 대한 프레디케이트를 sleepAnalysis 샘플 타입과 수면 단계 프레디케이트로 만듭니다 그리고 이 쿼리 프레디케이트로 이제 제 쿼리를 만들 수 있습니다 쿼리를 돌리면 저는 렘수면 단계의 수면 샘플 배열을 돌려 받게 됩니다 하지만 여러분이 명시되지 않은 것까지 포함해서 모든 수면 단계에 대한 샘플을 읽는 데 관심이 있다면 프레디케이트를 구축할 때 앱을 업데이트해서 새로운 .allAsleepValues를 사용하는 게 중요합니다 작년 이후로 HealthKit를 살펴보지 못한 분들은 퀴리 작업을 위한 짧은 구문이 낯설어 보일 수도 있습니다 iOS 15.4 이후로 우린 쿼리 API를 업데이트해서 Swift 비동기를 지원합니다 쿼리는 HealthKit의 필수 요소 중 하나고 Swift 비동기 지원으로 더욱 간결한 신택스로 그 사용이 쉬워졌습니다 쿼리는 HealthKit의 다양한 데이터를 읽게 해줍니다 프레디케이트를 사용하여 결과를 필터링하고 그게 들어올 때 새로운 데이터를 살펴보기도 합니다 모든 쿼리는 HKQuery의 하위 클래스입니다 제가 특정 기간 동안 소모한 열량을 아는 데 관심이 있다면 이런 계산된 통계치를 얻기 위한 멋진 쿼리는 HKStatisticsCollectionQuery입니다 초기 결과를 얻으려면 쿼리의 initialResultsHandler 클로저를 정합니다 그리고 업데이트를 받아보는 데 관심이 있는 분은 추가로 정해야 할 건 statisticsUpdateHandler 클로저입니다 일단 그 쿼리가 시작되면 이 클로저는 결과와 함께 호출됩니다 Swift 비동기 덕분에 우린 이걸 더욱 단순하게 만들죠 이제 각각의 쿼리에 대응하는 쿼리 기술어가 있어서 HKStatisticsCollectionQuery가 HKStatisticsCollectionQuery Descriptor가 됩니다 비동기 result(for:) 방식을 호출하기만 하면 초기 결과를 얻게 됩니다 반면에 초기 결과도 얻으면서 업데이트도 받아보고 싶다면 results(for:)를 호출합니다 그건 여러분이 루프로 갈 수 있는 AsyncSequence를 돌려줘서 결과를 읽게 해줍니다 HealthKit는 운동 추적과 소모된 열량처럼 관련된 수치 추적에 아주 좋아요 제가 이번 주에 소모한 열량이 얼마나 되는지 알려면 StatisticsCollectionQuery Descriptor를 사용하면 됩니다 먼저 프레디케이트로 열량 샘플들에 일치하는 쿼리 기술어를 만듭니다 cumulativeSum 옵션을 사용합니다 총계를 알고 싶으니까요 저는 이번 주 데이터에 관심이 있으니 thisSunday를 제 anchorDate로 사용합니다 그리고 마지막으로 저는 열량 총합이 일주일의 시간 간격 동안 계산되길 원하죠 일단 제 쿼리 기술어를 만들었으면 healthStore 오브젝트로 result(for:)를 호출하기만 하면 됩니다 돌아온 statisticsCollection 오브젝트는 제 현재 데이터의 요약 정보를 알려줍니다 그런데 제 열량이 변할 때 실시간 업데이트를 원하면 아주 간단합니다 results(for:)를 호출하고 돌아온 비동기 시퀀스를 루프 형태로 이동하면서 결과를 읽으면 됩니다 제가 업데이트를 기다리는 걸 다했으면 루프에서 빠져나오면 쿼리가 종료됩니다 이제 운동 얘기를 해보죠 HealthKit는 운동과 그와 관련된 모든 수치를 저장하기에 아주 좋습니다 일상적인 자전거 타기를 위해 나갈 때나 경주에서 스스로를 한계까지 몰아붙이든 말이죠 그리고 종종 운동에는 한 가지를 초과하는 활동들이 포함될 수 있어요 여러분은 인터벌 트레이닝으로 동일한 운동을 반복하거나 철인 3종 경기에 참가할 수도 있죠 그건 수영, 사이클 마라톤으로 이루어집니다 우린 iOS 16과 watchOS 9의 Workouts API를 업데이트해서 이런 종류의 운동과 각 활동에 대한 관련 통계치를 확보하는 걸 가능하게 할 겁니다 이건 제가 최근에 했던 수영-자전거-달리기 운동의 일정표입니다 저는 수영으로 시작했고 그다음에 시간을 조금 들여서 운동 중 사이클 부분을 준비했고 마지막으로 마라톤을 했습니다 각 활동은 HKWorkoutActivity 오브젝트로 표현됩니다 각각의 운동 활동은 자체 운동 설정과 함께 만들어지는데 여기에는 활동 타입이 포함됩니다 운동 활동에는 활동 중에 일어난 이벤트 목록이 있습니다 그리고 여러분은 각 활동에 대한 통계치를 읽을 수 있는데 이는 특정 활동 중에 어떤 일이 있었는지 분석하는 데만 관심이 있을 때 아주 좋습니다 제 일정표로 돌아가죠 저의 세 가지 활동이 적절한 활동 종류로 설정되어 있습니다 활동들의 시간은 겹칠 수 없습니다 각 활동 사이에 변환 시기가 있을 수 있기 때문에 닿아 있는 게 요구되진 않습니다 제가 그 변환 시기에 어떤 일이 있었는지 분석하는 데 관심이 있다면 각각의 변환에 대한 HKWorkoutActivity를 만들 수 있습니다 transition 타입으로요 이 모든 활동은 HKWorkout 오브젝트로 저장됩니다 workoutActivities 속성 하에서요 여러분이 HKWorkoutBuilder를 써서 HealthKit에 운동을 추가한다면 활동을 추가하는 건 쉬워요 HKWorkoutActivity 오브젝트를 만들기만 하면 되죠 workoutConfiguration과 시작 및 종료 일자와 선택적 메타데이터로요 그런 다음 운동 빌더에 있는 addWorkoutActivity를 호출하기만 하면 됩니다 Apple Watch에서는 운동 세션을 사용해서 수영-자전거-달리기 운동 추적하고 연관된 운동 빌더도 써서 HealthKit에 운동을 저장할 수 있습니다 제 운동 일정표로 돌아가보죠 이 운동을 Apple Watch에서 추적하려면 운동 세션과 빌더를 준비시켜야 합니다 먼저 swimBikeRun 타입으로 운동 설정을 만듭니다 그리고 제 설정을 사용해서 HKWorkoutSession을 만듭니다 운동이 시작될 때 그 세션의 startActivity를 호출하고 연관된 운동 빌더에 beginCollection을 호출합니다 이제 제 세션과 빌더가 준비됐으니 저의 첫 활동을 추가할 수 있어요 beginNewActivity 기법을 수영 운동 설정과 시작 일자를 넣어 사용해서요 각각의 활동을 시작할 때 운동 빌더 데이터 출처를 반드시 업데이트해서 여러분이 관심 있는 데이터 타입만 수집해야 합니다 이건 수영 활동이기 때문에 저는 수영 거리가 수집되길 바랍니다 활동이 종료될 때 저는 종료 일자를 넣어 endCurrentActivity를 호출합니다 저는 수영에서 사이클 사이의 변환 시기 분석에 관심이 있기 때문에 새로운 변환 활동을 시작합니다 수영이 끝난 직후에요 반복하지만 이건 활동의 시작이기 때문에 저는 빌더 데이터 출처를 업데이트해서 수영 거리의 수집을 중단시킵니다 그건 더 이상 의미가 없으니까요 저는 사이클이 시작되기 직전에 변환 활동을 종료합니다 나머지 제 운동 활동도 동일한 방식으로 추적하면 됩니다 운동이 끝날 때 세션을 끝내면 제 달리기 활동도 다 끝납니다 그럼 저는 운동 빌더를 마칠 수 있죠 그건 HKWorkout 오브젝트를 저장해서 돌려줍니다 저는 돌려받은 운동을 사용해서 연관된 수치들을 읽을 수 있습니다 가령 totalEnergyBurned와 totalDistance를요 그리고 제 앱에 운동의 요약본을 표시할 수 있어요 하지만 이런 소규모 속성 집합은 더 이상 충분하지 않습니다 totalSwimmingStrokeCount는 모든 운동과 관련돼 있지 않고 일부 운동에선 수치를 더 많이 수집할 수 있습니다 모든 종류의 운동에 대한 수치를 읽는 걸 더 쉽게 하기 위해 우린 이 속성들을 버리고 주어진 수량 타입에 대한 통계치를 돌려주는 새로운 기법을 도입합니다 알려드리고 싶은 건, 이 방식은 HKWorkoutActivity에서도 이용 가능해서 여러분이 활동 중에 어떤 일이 일어났는지에 집중할 수 있게 해줍니다 이 통계치가 운동으로 수집된 모든 샘플에서 자동으로 계산되는 건 HKWorkoutBuilder이나 HKLiveWorkoutBuilder를 사용하는 경우에 한합니다 이렇게 풍부한 운동 표현과 함께 우린 프레디케이트 집합도 새로 마련해서 여러분이 관심 있는 운동만 조회할 수 있게 돕습니다 여러분의 분석이나 시각화를 이끌어낼 때 말이죠 예를 하나 들어보자면 여기에 각 활동에 대한 평균 심장 박동 수가 있는 저의 최근 운동 목록이 있습니다 저는 제 평균 심장 박동 수가 150을 초과하는 강도 높은 활동이 있는 제 운동을 찾아내고 싶습니다 먼저 저는 새로운 predicateForWorkoutActivities 기법을 사용해서 프레디케이트를 만듭니다 이는 운동 활동에 작용합니다 저는 평균 심장 박동 수가 분당 150회를 초과하게 하고 싶습니다 다음으로는 제가 운동을 조회하길 원하므로 심장 박동 수 프레디케이트를 운동 프레디케이트 내에 넣어줍니다 그리고 그 프레디케이트를 써서 쿼리를 만듭니다 저는 제 쿼리 기술어의 result(for: healthStore) 기법을 호출해서 제 프레디케이트와 일치하는 운동들의 목록을 얻습니다 그런 식으로 제가 관심을 갖는 운동만 조회할 수 있는 거죠 제가 최근에 했던 운동 중 하나는 네 번의 마라톤 인터벌로 이뤄졌습니다 HKWorkoutActivity의 사용은 이 인터벌들을 포착하는 데 아주 좋은 방법이죠 여러분이 할 일은 인터벌이 있는 운동의 모든 활동에 운동과 동일한 활동 타입이 있게 하는 겁니다 따라서 달리기 운동의 경우 모든 활동이 .running 타입으로 설정됩니다 운동 활동을 써서 인터벌을 추적하는 것의 장점은 각각의 인터벌에 대한 통계치를 얻을 수 있다는 겁니다 이 업데이트들로 운동에 이제 포함되는 건 그 활동들에 대한 더욱 포괄적인 그림과 그것들의 주위에 있는 맥락입니다 훨씬 더 풍부한 그림을 제공하기 위해 우린 새로운 달리기 수치를 도입합니다 그건 Apple Watch Series 6, SE 그리고 이후 모델에서 자동으로 수집됩니다 달리기 걸음 길이나 와트로 나타낸 일률 같은 수치를요 수영 운동의 경우 SWOLF 점수를 추가합니다 그것의 정의는 주어진 길이에서 팔을 저은 횟수와 그 길이만큼 헤엄치는 데 걸린 시간입니다 이 점수는 각각의 왕복 이벤트와 세그먼트 이벤트에 대해 측정됩니다, Apple Watch에 기록된 수영 운동에 대해서요 이 수치들은 운동의 질을 높이고 자신이 했던 걸 더 잘 알 수 있게 해주지만 운동을 마친 후에 기록되는 또 하나의 중요한 수치는 심장 박동 수 회복입니다 그건 운동 후 심장 박동 수가 얼마나 빨리 줄어드는지의 추정치인데, 그건 스트레스를 받은 후에 심장이 회복되는 방식을 알고 잠재적인 건강 문제를 드러내는 데 사용될 수 있습니다 iOS 16으로 우린 Cardio Recovery 데이터 타입을 새로 도입합니다 그건 건강 앱에서 볼 수 있고 여러분의 앱은 HealthKit에서 이 데이터를 읽고 거기에 저장할 수 있습니다 심장 박동 수 회복은 수량 타입으로 그 식별자는 .heartRate RecoveryOneMinute입니다 각각의 심장 박동 수 회복 샘플에 관한 추가적인 맥락 정보는 매타데이터로 넣을 수 있습니다 최근 저는 수영-자전거-달리기 운동을 하며 스스로를 한계까지 몰아붙였고 제 심장 박동 수의 회복 속도를 관찰했습니다 운동을 끝내기까지는 약 3시간 반이 걸렸습니다 달리기를 할 때 저의 최고 심장 박동 수는 분당 184회에 도달했습니다 운동 이후 1분 동안 제 심장 박동 수는 50회 감소했습니다 Apple Watch에서 HKLiveWorkoutBuilder을 사용할 때 심장 박동 수 회복 샘플은 그 주위의 맥락과 함께 운동 후에 HealthKit에 자동으로 저장됩니다 그 외에 심장 박동 수 회복 샘플을 저장하려면 .heartRateRecoveryOneMinute 타입으로 수량 샘플을 만듭니다 운동 이후 1분 만에 제 심장 박동 수는 50회 줄어서 저는 그걸 제 샘플의 수량으로 정했습니다 또한 저는 샘플의 시작과 종료 일자를 정했습니다 그런 다음 추가 맥락 정보는 메타데이터 사전에 넣었습니다 회복 테스트 타입으로 시작해서요 제 운동에 혼신의 노력을 쏟았기에 테스트 타입은 .maxExercise입니다 제 운동은 swimBikeRun이니 그걸 활동 타입으로 정했습니다 또한 HeartRateRecoveryActivity Duration 키를 사용해서 운동 지속 시간도 추가할 수 있습니다 마지막으로 저는 운동 중 관찰된 최고 심장 박동 수를 넣습니다, 그건 분당 184회였습니다 이 업데이트들로 수영-자전거-달리기와 인터벌 운동의 추적은 이제 그 어느 때보다 쉬워졌습니다 게다가 새로운 수치의 도입은 운동에 대한 더욱 포괄적인 그림과 시간에 따른 발전을 평가하는 더욱 새로운 방식을 제공합니다 활동과 건강은 모두에게 영향을 미치는 일이긴 하지만 건강의 다른 측면들 중에 많은 사람과 관련된 게 있습니다 가령 시력이 그렇죠 실제로 미국시력협의회에 따르면 미국 성인의 약 75%가 시력 교정에 의존한다고 합니다 맞춤 안경이나 콘택트 렌즈로요 하지만 이런 처방전들은 분실하기 쉽고 맞춤 안경이나 콘택트 렌즈를 주문할 때 추가로 챙겨야 하는 겁니다 그러니 그걸 우리 휴대폰에 넣어보죠 iOS 16을 기점으로 여러분의 앱은 HealthKit에 안경과 콘택트 렌즈 처방전을 저장할 수 있습니다 시력 처방전은 샘플로 visionPrescriptionType이 동반됩니다 샘플의 시작 일자는 처방전의 발행 일자에 대응됩니다 한편 종료 일자는 만기 일자에 대응됩니다 선택에 따라 실제 처방전의 디지털 사본이 샘플에 첨부될 수 있습니다 안경 혹은 콘택트 렌즈 처방전 샘플은 HKVisionPrescription의 하위 클래스입니다 안경의 경우 HKGlasses Prescription 하위 클래스를 쓰고 콘택트 렌즈의 경우 HKContacts Prescription 하위 클래스를 쓰죠 두 개의 안경 렌즈 사양 오브젝트를 써서 각각의 안경 처방전이 만들어집니다 눈 하나에 하나씩이죠 그리고 마찬가지로 콘택트 렌즈 처방전도 두 개의 콘택트 렌즈 사양 오브젝트로 만들어집니다 이제 제 독서용 안경 처방전을 HealthKit에 저장해보죠 첫 단계는 각각의 눈에 HKGlassesLensSpecification을 만드는 겁니다 정점간거리와 프리즘 같은 일부 파라미터는 선택형입니다 같은 방식으로 오른쪽 눈 렌즈 사양을 만들 수 있습니다 다음으로는 제 오른쪽 눈과 왼쪽 눈의 렌즈 사양으로 안경 처방전 샘플을 만듭니다 이 처방전은 제 독서용 안경에 대한 것이니 저는 그걸 설명에 넣겠습니다 그런 다음 제 처방전으로 healthStore에서 저장을 호출합니다 그렇게 이제 제 처방전은 HealthKit에 저장됐습니다 저는 그 사진도 찍어놨는데요 그걸 방금 저장한 샘플에 첨부하고 싶습니다 파일 첨부는 HKAttachment 오브젝트로 표현됩니다 HKAttachmentStore를 써서 파일 첨부를 저장하고 읽습니다 처방전에는 정지 이미지나 PDF 파일만 첨부될 수 있습니다 제 처방전 샘플에 찍었던 사진을 첨부하려면 먼저 healthStore를 사용해서 HKAttachmentStore 오브젝트를 만듭니다 그리고 제 처방전 샘플로 addAttachment(to:)를 호출합니다 첨부물의 이름을 정합니다 여기에서 저는 PNG 파일을 첨부합니다 그리고 마지막으로 파일의 URL을 전달합니다 제가 방금 첨부한 처방전에는 렌즈 사양에 비해 정보가 훨씬 많이 들어 있습니다 제 이름과 성, 출생일자 같은 민감한 정보가 있죠 HealthKit의 핵심 원칙 중 하나는 여러분의 개인 정보를 보호하고 공유하는 데이터를 늘 여러분이 제어하게 하는 겁니다 첨부물이 포함된 처방전으로 의도했던 것보다 많은 데이터를 공유하기 쉬워질 수 있기 때문에 우린 처방전에 대한 허가 모델을 새롭게 도입합니다 각각의 처방전 오브젝트에 대해 별도의 읽기 허가를 부여합니다 사용자들은 앱에 접근권을 부여할 처방전이 정확히 어떤 건지 선택할 수 있고 언제든 그 선택을 업데이트할 수 있습니다 시력 처방전 오브젝트에 대해 허가를 요청하기 위한 API를 새로 마련했습니다 다른 데이터 타입과 마찬가지로 자신의 앱이 접근할 수 있는 처방전을 읽기 위한 쿼리를 여러분은 사용할 수 있습니다 여러분이 특정 처방전에만 관심이 있다면 프레디케이트를 사용할 수 있습니다 허가를 요청하려면 healthStore의 requestPerObjectRead Authorization 기법을 호출하면 됩니다 visionType으로요 그렇게 하면 여러분 앱에 허가 프롬프트가 늘 뜰 겁니다 여러분의 프레디케이트와 일치하는 모든 처방전의 목록과 함께요 반드시 적절한 맥락 속에서 허가를 요청해서 최고의 사용자 체험을 선사하세요 그것들이 우리가 HealthKit에 새롭게 추가한 것들 중 일부로 여러분의 앱에 보다 나은 건강과 피트니스 경험을 제공할 능력을 부여합니다 여러분이 다음으로 구축할 걸 빨리 보고 싶네요 WWDC를 즐기시고 질문이 있으면 개발자 포럼에서 기꺼이 도와드리겠습니다 ♪
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.