스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
WorkoutKit으로 맞춤형 운동 구축하기
WorkoutKit을 사용하면 Apple Watch의 운동 앱에서 운동 일정을 생성하고 미리 보며 계획할 수 있습니다. 맞춤형 구간을 구축하고 알림을 생성하고 내장된 미리보기 UI를 사용해 Apple Watch로 여러분만의 운동 루틴을 전송하는 방법을 알아보세요.
리소스
관련 비디오
WWDC23
-
다운로드
♪ ♪
안녕하세요, 전 투 응우옌이며 Workout 팀의 엔지니어입니다 오늘 제 동료 아비라지와 함께 Apple Watch에서 맞춤형 운동을 구축하는 방법을 짚어 보겠습니다 watchOS 9에서 저희는 운동 앱에 사용자가 원하는 운동 경험을 생성하고 사용자화할 수 있는 새로운 운동 유형을 도입했습니다 목표 기반 운동은 거리, 칼로리 시간 등의 단일 목표에 맞춰 사용자가 운동을 수행할 수 있는 기능이죠 페이스 운동은 페이스나 속도에 중점을 둡니다 트라이애슬론 선수를 위한 멀티 스포츠 운동은 수영, 사이클링, 달리기 활동을 자연스럽게 전환하죠 그리고 맞춤형 운동은 사용자화 목표와 알림을 조합한 구조적 단계로 이루어져 있습니다 iOS 17와 watchOS 10에서는 이러한 모든 운동 유형을 WorkoutKit이라는 새로운 프레임워크로 제공합니다
WorkoutKit은 전혀 새로운 Swift 프레임워크입니다 사용자가 운동 앱 내에서 생성한 모든 다양한 운동 유형을 여러분의 앱에서 생성하고 사용자화할 수 있게 하죠 이러한 운동 유형을 운동 앱으로 가져와 사용자가 수행할 수 있도록 중계하기도 합니다 WorkoutKit은 미리 보기 UI와 계획된 운동을 동기화하는 기능을 제공합니다 저희는 이 4가지 운동 유형을 Workoutkit으로 가져오는데요 오늘은 맞춤형 운동에 초점을 맞추도록 하겠습니다 이 세션에서는 맞춤형 운동을 구축하고 내보낸 것을 미리 보기하며 운동을 계획하는 방법을 볼 겁니다 맞춤형 운동의 구축부터 시작해 보죠 맞춤형 운동은 사용자가 구조적 방식으로 운동에 집중할 수 있도록 하는 훌륭한 방법으로 사용자에게 운동 과정을 안내하는 일련의 구분된 단계가 포함되어 있습니다 맞춤형 운동은 3단계로 구분되어 있는데요 먼저 운동을 시작하는 단계가 있습니다 바로 준비 운동 단계죠 다음은 반복 가능 블록이 순서대로 나열된 컬렉션으로 단계의 조합이 여기에 포함되어 있습니다 이 블록들은 대부분의 운동을 나타내죠 그리고 마지막은 운동의 마무리 단계로 정리 운동 단계라고 부르는 것입니다 준비 운동, 정리 운동 반복 가능 블록 단계에는 두 가지 중요한 속성이 포함되어 있습니다 먼저 모든 단계는 단일 목표를 포함하죠 목표는 맞춤형 운동에서 단계의 진척도를 정의합니다 목표를 달성하면 맞춤형 운동은 다음 단계로 넘어갑니다
맞춤형 운동의 단계는 가능한 시간이나 거리 목표가 있죠 열린 목표를 설정할 수도 있는데요 이 경우에는 사용자가 수동으로 단계를 진행해야 합니다
두 번째로 모든 단계에는 단일 알림이 있습니다 알림은 현재 수행력을 나타내는 특정 지표를 사용자에게 알려 줍니다 사용자의 심박수가 특정 기준을 넘을 때 받을 수 있는 알림이 그 예시죠
저희는 여기에 페이스 및 케이던스 파워, 심박수 알림을 지원합니다
이제 단계가 어떻게 구성되는지 알게 됐으니 블록을 자세히 살펴봅시다
블록에는 운동 단계와 회복 단계로 구분된 단계가 포함되어 있습니다 방금 봤듯이 블록 내 단계는 목표와 알림을 포함하고 있으며 블록 내에 임의의 수와 순서로 단계를 넣을 수 있습니다 블록 또한 반복이 가능한데요 반복하고자 하는 블록의 반복 수를 지정할 수 있죠 이제 이것이 Apple Watch에서 운동 중 경험으로 어떻게 해석되는지를 봅시다 먼저 사용자의 현재 단계가 블록 내의 본운동 단계로 보이네요 이 단계에는 거리 목표가 있는데 현재 목표 진척도가 0.2마일 남은 것이 보이죠 이 단계에는 하단에 표시되는 현재 파워 알림도 있습니다 이 단계에 알림을 지정하지 않았다면 사용자의 현재 심박수가 표시됩니다
마지막으로 다음 단계가 시간 기반 목표의 회복 단계임을 미리 볼 수 있죠 블록과 단계를 통해 맞춤형 운동을 완벽히 설계할 수 있습니다
마찬가지로 맨 처음에는 준비 운동 단계가 있습니다 그리고 운동 및 회복 단계가 있고 운동 시간의 대부분을 차지하는 일련의 반복 가능 블록이 있고요 마지막은 정리 운동 단계로 끝납니다 이제 제 동료 아비라지에게 차례를 넘겨 Workoutkit으로 맞춤형 운동을 구축하는 방법을 보여 드리죠 안녕하세요, 아비라지입니다 Workout 팀의 엔지니어죠 투가 언급했듯이 Workoutkit으로 목표, 멀티 스포츠 그리고 맞춤형 운동을 위한 운동을 생성할 수 있는데요 사용자 설정 실외 사이클링 운동을 예시로 보여 드리겠습니다 운동을 4단계로 구성할 건데요 준비 운동 단계 반복 가능 본운동 및 회복 블록 둘 그리고 마지막으로 정리 운동 단계죠 준비 운동 단계에서는 열린 목표를 사용할 겁니다 첫 번째 블록은 거리 목표와 페이스 알림이 있는 본운동 단계와 거리 목표와 심박수 알림이 있는 회복 단계로 되어 있는데요 이 블록은 4번 반복할 겁니다 두 번째 블록은 시간 목표와 파워 알림이 있는 본운동 단계와 시간 목표와 심박수 알림이 있는 회복 단계로 되어 있죠 마지막으로 정리 운동 단계는 시간 목표를 둘 겁니다 이제 이걸 코드로 어떻게 표현하는지를 보죠 준비 운동 단계부터 시작해 봅시다 먼저 Workoutkit을 가져옵니다 아까 언급했듯이 준비 운동 단계는 알림이 없는 열린 목표죠 그러니 이 경우에는 단계를 기본 초기화 함수로 생성합니다 이제 운동의 첫 블록으로 넘어가죠 첫 번째 블록은 단계가 2개 있는데요 첫 번째 단계는 본운동 단계로 거리 목표와 페이스 알림이 있죠
여기에 Healthkit을 가져와야 HKQuantity와 HKUnit을 활용해 목표와 알림을 표현할 수 있습니다 이제 WorkoutGoal을 사용해 2마일 목표를 설정합니다 페이스 알림도 여기 추가할 건데요 시속 10마일을 목표로 하겠습니다 우선 페이스 값의 HKQuantity를 시속 10마일로 생성합니다 WorkoutAlert를 사용해 이 알림을 생성할 건데요 WorkoutAlertTargetType이 있어야 WorkoutAlert를 생성할 수 있으며 이 경우에 target은 시속 10마일이고 WorkoutAlertType은 현재 페이스죠 이제 WorkoutAlert의 페이스를 생성할 수 있습니다 본운동 단계를 생성하기 위해 work 유형의 BlockStep과 함께 twoMileGoal과 paceAlert를 사용합니다
블록의 두 번째 단계는 회복 단계인데요 0.5마일을 회복 목표로 생성하고 심박수 구간 1 알림도 넣겠습니다
그런 다음 rest 유형의 회복 BlockStep를 생성하고요 본운동 및 회복 단계를 정의했으니 이제 블록을 생성할 수 있는데요 그러려면 단계 배열과 반복 수 4인 IntervalBlock을 사용합니다
이렇게 하면 첫 번째 블록이 완성되죠 이제 두 번째 블록으로 넘어가 보겠습니다 이 블록에도 단계가 2개 있는데요 첫 번째 단계는 본운동 단계로 시간 목표와 파워 알림이 있습니다 목표는 2분으로 설정하고요 이 운동 블록에서 범위가 250~275W인 파워 범위 알림을 생성합니다 range 유형인 WorkoutTargetType을 생성하고 WorkoutAlert를 생성합니다 끝으로 막 생성한 목표와 알림으로 BlockStep을 생성합니다
이 블록의 두 번째 단계는 회복 단계죠 심박수 구간 1 알림으로 30초 목표를 생성합니다 그러면 회복 단계를 생성할 수 있죠
방금 정의한 본운동 및 회복 단계로 반복 수가 2인 두 번째 블록을 이제 생성할 수 있습니다
마지막으로 정리 운동 단계로 넘어가 보겠습니다 정리 단계는 시간 목표를 둘 것이기에 그걸 여기에 생성해 보죠
time 유형인 WorkoutGoal을 생성한 다음 fiveMinuteGoal로 목표를 설정한 CooldownStep의 생성에 사용합니다 이제 이걸 전부 합쳐 봅시다
지금까지 구축한 준비 운동 단계, 블록1, 블록2 정리 운동 단계를 전부 사용해 맞춤형 운동 구성을 생성할 수 있습니다 활동 유형은 사이클링 위치는 실외로 설정합니다 CustomWorkoutComposition 초기화 함수의 LocationType 매개 변수는 선택 사항이며 기본 설정은 실외입니다 전부 합쳐 맞춤형 운동을 생성하고 이름은 '나의 운동'으로 합니다
CustomWorkoutComposition 초기화 함수가 try로 선행하는 이유가 궁금하실 텐데요 그 이유는 구성을 검증하기 때문입니다 운동 구성의 검증이 왜 중요한지를 논하겠습니다 검증은 일관성 있는 운동 구조를 보장하고 운동 런타임 중 발생할 모든 문제를 방지합니다 가령 거리 목표는 거리를 기반으로 하지 않는 운동의 구성에 사용되지 말아야 하죠 마찬가지로 일립티컬 같이 페이스를 지원하지 않는 운동에 페이스 알림을 사용해도 안 되고요 이를 돕기 위해 운동 활동 유형 같은 특정 속성이 설정되거나 특정 API를 통해 실행될 때 일련의 검증을 수행합니다
WorkoutComposition 래퍼를 생성해 추가 작업을 수행할 수도 있는데요 운동 구성을 기기 간에 공유할 수 있도록 파일로 가져오고 내보내도록 생성한 API가 그 예시죠 JSON이나 이진 형식으로 내보낼 땐 dataRepresentation을 사용합니다 구성을 내보낼 때는 용량이 훨씬 작은 이진 형식을 권장합니다 이제 다시 투에게 차례를 넘겨 구성을 미리 보는 방법을 설명해 드리겠습니다 정말 고맙습니다, 아비라지 이러한 API를 활용해 완전한 맞춤형 운동을 구축하는 방법을 볼 수 있어서 참 좋네요 이제 만들어 놓은 운동 구성으로 무엇을 할 수 있나 살펴보겠습니다 운동 구성으로 WorkoutKit에서 다양한 일을 할 수 있는데요 먼저 아비라지가 언급했던 대로 .workout 확장자 파일로 구성을 내보내 공유하고 배포할 수 있습니다 특정 API를 호출할 때 자동으로 검증을 수행하는데 구성을 내보낼 때가 바로 그 예시죠
구성 내용의 미리 보기를 사용자에게 제시할 때 쓸 수 있는 API도 있는데요 이 API는 iOS와 watchOS에서 다르게 동작합니다
iOS에서는 구성의 미리 보기 API를 호출하면 앱 상단에 제시된 처리 UI가 운동 구성의 전체 내용을 표시합니다 여기서는 맞춤형 운동 구성을 예시로 사용하겠습니다 제목은 상단에 눈에 띄게 표시되며 목표와 알림을 포함한 단계와 블록이 그 밑에 나타나고 사용자가 Apple Watch의 운동 앱에 직접 저장할 수 있는 옵션이 있습니다 이제 watchOS로 넘어가죠 여기서 미리 보기 API를 호출하면 운동 구성의 내용과 함께 운동 앱이 실행됩니다 여기서 사용자가 지금 운동할지 나중을 위해 저장할지를 정하죠
아비라지에게 다시 차례를 넘겨 WorkoutKit의 미리 보기를 소개하죠 이제 멋진 운동을 만들었으니 사용자가 저장할 차례입니다 앞서 의논했듯이 운동에서 WorkoutComposition을 사용해 검증 같은 추가 작업을 수행할 수 있습니다 WorkoutComposition을 통해 사용자가 미리 볼 수도 있죠 iOS와 watchOS에 최적화된 미리 보기 API는 사용자에게 운동을 미리 보고 저장하고 시작할 편리한 방법을 제공합니다 앞에서 생성한 사이클링 운동을 WorkoutComposition으로 감싸 보죠
투가 앞서 언급한 모든 운동 유형은 WorkoutComposition과 함께 사용할 수 있는데요 이제 workoutComposition에서 presentPreview 함수를 사용해 미리 보기를 제시하겠습니다
이 태스크 블록을 사용할 건데 Swift의 현대적인 동시성 기능과 함께 작동하도록 설계된 API이기 때문이죠 전에 언급했듯이 presentPreview는 실행 중인 플랫폼에 따라 운동의 미리 보기를 다르게 표시합니다 어떻게 작동하는지 보도록 하죠 iOS에서는 해당 함수가 앱 상단에 원격 뷰를 제시합니다 사용자가 Apple Watch의 운동 앱에 직접 저장할 수 있는 옵션도 운동 내용과 함께 보여 주죠 'Watch에 추가' 버튼은 운동 앱을 새 운동으로 업데이트합니다 Apple Watch에서 미리 보기 함수는 다르게 작동하는데요 운동 앱 위에 시트를 제시하는 대신 watchOS에서는 운동의 미리 보기와 함께 앱이 실행됩니다 이제 운동의 계획을 말씀드릴 투에게 차례를 넘기겠습니다 고마워요, 아비라지 이러한 미리 보기 옵션은 사용자에게 빠른 상호작용으로 단일한 운동 구성을 제공할 때 매우 유용합니다 하지만 일정 기간 동안 사용자가 수행할 운동 컬렉션이 있는 경우에는 어떨까요? 예를 들어 사용자가 오늘은 사이클링을 계획했으며 다음 날에는 하이킹을 그리고 며칠 뒤에는 골프 그리고 약간의 휴식을 계획했고 그 뒤에는 사이클링을 더 한다고 가정하겠습니다 구성과 미리 보기 API로 운동을 운동 앱에 직접 저장할 수도 있겠지만 이 경우에는 사용자가 모든 운동을 관리하고 언제 완료해야 하는지를 기억해야 합니다 확장성이 썩 좋진 않죠 WorkoutKit의 일환으로 전체 과정을 간소화하도록 여러분의 앱이 운동 앱에서 운동을 직접 계획할 수 있습니다 어떤 모습일지 보죠 운동을 계획하면 운동 앱 상단의 전용 공간을 여러분의 앱이 차지합니다 이 전용 공간에는 여러분의 앱 아이콘과 이름 그리고 오늘 할 운동의 미리 보기가 나타납니다 여길 탭하면 표시된 운동 계획을 즉시 시작하죠
…를 탭하면 자세한 정보가 나타나는데 동기화한 예정 운동 계획이 여기에 포함되어 있습니다
운동을 계획하려면 사용자의 권한이 필요하며 동기화는 로컬에서 진행됩니다 사용자는 다음 7일과 이전 7일 동안의 운동 계획을 확인할 수 있죠 운동은 한 번에 15개까지 동기화할 수 있고요 사용자가 여러분의 앱에서 완료한 운동 계획을 쿼리할 수 있습니다
운동 계획을 쿼리할 때 운동에는 생성한 구성, 계획 날짜 사용자의 운동 완료 여부만 포함됩니다 건강 데이터는 전혀 포함되지 않죠 완료한 운동에서 건강 통계를 얻고 싶다면 HealthKit API를 참조하세요 또 WorkoutKit의 일환으로 HKWorkout의 확장을 제공해 가능한 경우 운동 구성을 검색해 회수할 수 있습니다 이제 아비라지에게 차례를 넘겨 운동을 Workoutkit을 사용해 계획하는 방법을 보여 드리죠 고맙습니다, 투 사용자를 위해 운동을 앱에서 계획할 수 있도록 운동 구성을 운동 앱에서 Apple Watch와 동기화할 수 있게 지원하는 API 묶음을 제공하고 있습니다 WorkoutKit API를 활용해 실제로 앱을 구축해 봅시다 계획 날짜와 운동 구성을 연결한 다음 동기화해야 하는데요 그 방법을 보여 드리죠 WorkoutKit API와 상호작용할 자리 표시자가 있는 앱을 구축해 놓았는데요 Workoutkit을 활용해 이 기능을 구현하는 방법을 보여 드리죠 운동 앱에서 운동 동기화를 시작하려면 사용자로부터 권한을 얻어야 합니다 WorkoutPlan에서 authorizationState를 호출해 앱의 현재 권한을 확인할 수 있죠 권한을 아직 요청하지 않았다면 WorkoutPlan에서 requestAuthorization을 호출해 인증을 요청할 수 있고요
'인증 요청하기' 버튼을 탭해 보겠습니다
requestAuthorization()을 호출하면 사용자에게 동기화할지를 묻는 알림 창이 표시됩니다 사용자는 iOS의 Watch 앱과 watchOS의 설정 앱에서 운동 설정을 변경할 수 있습니다
이제 앱이 인증을 받았으니 Apple Watch의 운동 앱에서 현재 운동 일정을 얻읍시다 WorkoutPlan.current를 사용해 WorkoutPlan을 쿼리할 수 있는데요
WorkoutPlan은 여러분의 앱에서 운동 계획을 저장하고 수정하는 인터페이스입니다 '운동 일정 얻기' 버튼을 탭해 보죠
아직 운동을 계획하지 않았기에 일정에 계획된 운동이 없군요
이제 운동을 생성하고 계획해 봅시다 저는 오늘 골프를 치고 며칠 뒤에 사이클링을 하려는데요 새로운 운동 구성으로 그 계획을 생성하겠습니다
ScheduledWorkoutComposition 오브젝트에는 운동 구성과 계획 날짜 완료 상태가 포함되어 있는데요 골프 scheduledDate를 오늘에 사이클링 scheduledDate를 모레로 배치했습니다
앱에서 어떻게 보이는지 확인해 보죠 보시다시피 오늘은 골프 운동이 계획되어 있고 사이클링 운동을 며칠 뒤에 할 계획입니다 이제 계획을 생성했으니 앱에서 동기화해 보죠 현재 운동 일정을 사용해 새로 계획된 운동을 scheduledCompositions 배열에 덧붙이겠습니다 마지막으로 이 운동을 운동 앱에 추가하도록 workoutPlan.save()를 호출합시다
실제로 어떻게 작동하는지 보도록 하죠
좋아요 이제 운동이 동기화됐네요 투가 언급했듯이 운동을 계획하면 운동 앱 상단의 전용 공간을 여러분의 앱이 차지하죠 어떤 모습일지 자세히 봅시다 운동 앱을 열어 보죠
보시다시피 제 앱의 아이콘과 이름이 나타났군요 오늘 골프 운동 계획이 있기 때문에 여기를 탭하면 운동이 시작됩니다 …를 탭하면 예정된 계획을 볼 수 있죠 첫 화면에서 오늘 계획된 모든 운동을 볼 수 있습니다 '더 보기'를 탭하면 다음 7일과 이전 7일 동안의 운동 계획을 볼 수 있죠 이전에 동기화한 오늘의 골프 운동과 예정된 사이클링 운동이 여기에 보이는군요
이제 운동 계획이 어떻게 제시되고 운동 앱 내의 전용 공간을 여러분의 앱이 어떻게 차지하는지를 이해하셨겠죠 아시다시피 오늘 제가 골프를 칠 예정인데요 곧 티타임을 가질 겁니다
괜찮으시다면 잠깐 다녀오겠습니다 2시간 후 다녀왔습니다 오늘 골프가 잘되더군요 후반 홀은 72타를 기록했죠 사용자가 운동 앱에서 계획된 운동을 완료하면 완료 단계가 업데이트됩니다 WorkoutPlan.current를 사용해 WorkoutPlan을 쿼리해서 어떤 운동이 완료됐는지를 알아볼 수 있죠 여러분의 앱에서 운동이 완료됐다고 표시되면 완료 상태를 업데이트해 사용자가 어디에서든 최신 정보를 갖도록 해야 합니다 코드로 돌아가 보죠
예시에서 scheduledComposition이 완료됐는지를 확인할 수 있는데요 만약 그렇다면 완료로 표시하도록 합시다 실제로 확인해 보죠
여러분의 앱을 운동 앱에 동기화하려면 이 방법이 좋습니다 이제 인증 요청부터 운동 앱에 구성을 동기화하기까지 Workout 계획 API를 구현할 방법을 기본적으로 이해하셨겠죠 이제 투에게 차례를 넘기도록 하죠 고마워요, 아비라지 골프 실력이 늘었다니 멋지네요 이제 앱에 Workoutkit을 도입할 때 유념해야 할 몇 가지 모범 사례로 마무리짓겠습니다
사용자에게 표시하려는 운동 경험에 가장 적합한 구성 유형을 고려하세요 우리는 맞춤형 운동이 매우 유용한 구성 유형임을 봤죠 특히 사용자 설정 목표와 알림으로 다양한 수준의 노력 및 주의를 필요로 하는 운동에서요 하지만 수영은 맞춤형 운동을 지원하지 않습니다 때문에 목표 구성을 대신 사용해야 하죠 또한 맞춤형 운동에서만 알림을 사용할 수 있습니다 30분 달리기처럼 간단한 운동에 자체적인 알림을 지정할 필요가 없는 경우 대신 목표나 페이스 구성을 사용하는 것을 고려해야 합니다 운동 구성의 검증을 반드시 처리하세요 저희가 제공하는 매우 세부적인 검증 오류를 통해 호환성이나 오류의 원인을 정확하게 찾을 수 있습니다 모든 유형이 거리를 지원하지는 않는다는 점을 알아 두셔야 합니다 그러니 시간이나 열린 목표를 대신 사용하는 것을 고려하세요 맞춤형 운동에서 특정 알림을 지원하지 않는 운동 유형에서는 심박수 구간 알림 같은 대안을 고려하시고요
운동 계획을 최신 상태로 유지하세요 앱의 전경 또는 배경 런타임을 활용해 이를 실현하세요 마지막으로 저희에게 피드백을 보내 주시기 바랍니다 API를 시도해 보세요 오늘 보신 모든 예시 코드는 developer.apple.com에 있습니다 운동 동기화 세션과 관련된 HealthKit 세션을 확인하는 것도 잊지 마세요 시청해 주셔서 감사합니다 ♪ ♪
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.