View in English

  • メニューを開く メニューを閉じる
  • Apple Developer
検索
検索を終了
  • Apple Developer
  • ニュース
  • 見つける
  • デザイン
  • 開発
  • 配信
  • サポート
  • アカウント
次の内容に検索結果を絞り込む

クイックリンク

5 クイックリンク

ビデオ

メニューを開く メニューを閉じる
  • コレクション
  • トピック
  • すべてのビデオ
  • 利用方法

WWDC25に戻る

ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。

  • 概要
  • Summary
  • トランスクリプト
  • コード
  • iOSとiPadOSでのHealthKitによるワークアウトのトラッキング

    iOS上で最適なワークアウト体験を構築するためのベストプラクティスを紹介します。ワークアウトセッションのライフサイクル、Apple WatchとiPhoneの間のワークアウトの差異、アプリのロック画面の体験を向上させるためのライブアクティビティとSiriの利用方法について学ぶことができます。

    関連する章

    • 0:00 - Introduction
    • 0:56 - Run a workout session
    • 2:50 - Get session metrics
    • 8:35 - Recover from a crash
    • 9:34 - Best practices

    リソース

    • Building a multidevice workout app
    • Building a workout app for iPhone and iPad
    • Handling Workout Requests with SiriKit
    • HKWorkoutSession
    • Running workout sessions
      • HDビデオ
      • SDビデオ

    関連ビデオ

    WWDC25

    • HealthKit Medications APIの紹介

    WWDC24

    • App Intentでアプリのコア機能をユーザーに提供

    WWDC23

    • マルチデバイスワークアウトアプリの構築
    • ActivityKitについて
  • このビデオを検索

    Hello and welcome, my name is Brian and I’m an engineer on the HealthKit team. There are hundreds of health and fitness apps that help people get healthy and stay healthy. And with your permission, they have access to HealthKit’s centralized encrypted database and a set of powerful APIs to provide you a comprehensive view of your health. Now the workout APIs are some of the most powerful that HealthKit provides. And I’m excited to show you how to use these APIs on iPhone and iPad. I’ll begin by covering the basics of running a workout session. Then, I’ll dive into how to access health metrics during a workout with the focus on how the process differs from that on Apple Watch.

    I’ll then show you how to recover in the event of a crash and I’ll wrap it up with some workout tips and best practices. Let's get this workout session started.

    If you’re already running workouts in an app on Apple Watch, you’ll be able to use the same code on iPhone and iPad with only minimal changes. Just like on Apple Watch, you can now use a workout session to track any activity and use the associated workout builder to save the workout in HealthKit. Now, since you may not already have an app on Apple Watch, let me quickly run through an example of how to run a workout session.

    A workout session has several steps from setup and start to collecting health metrics and finally ending the session. To begin, you first need to create a workout configuration and set its type to reflect the activity the person will perform. I’ll use running and set the location to outdoor.

    You then create an HKWorkoutSession passing in the configuration.

    From the workout session, you’ll get the associated builder and attach a data source.

    Then call prepare on the session and display a three second countdown to allow time for on-device sensors to turn on or an external heart rate monitor to connect. This countdown ensures that you have metrics available as soon as the workout activity starts.

    Once the countdown completes, simply call startActivity on the session and beginCollection on the associated workout builder. There isn’t a need to use an anchored object query to update your UI. The workout builders delegate provides your app convenient updates when new data has been collected and handles keeping the metrics in sync when the workout is saved.

    When the person using your app decides to end the workout, you should call stopActivity on the session to allow the final metrics to be collected by your live builder.

    Once this session has transitioned to the stop state, you can call endCollection on the builder and finish the workout. After the builder has finished, call end on the session and display the workout summary.

    Alright, now that you’re familiar with how to run a workout, let me go through some of the differences between running a workout on Apple Watch and running a workout on iPhone or iPad. One key difference are the available sensors.

    While all workout activity types are available on iPhone and iPad, these devices don’t contain a heart rate sensor.

    But you can pair them with any device that you wear during a workout that supports the heart rate GAT profile, like a wearable heart rate monitor or the Powerbeats Pro 2.

    Once a device is paired, HealthKit will handle getting heart rate data from the device and saving it as samples to the Health Store, making it available to your app.

    This means there may be a difference in the samples you want to collect for your workout and the samples that the system can generate. Let's go over that difference.

    We have generated types. These are the data types generated by the system during a workout activity like calories and distance.

    And collected types, with these being the metrics you want to observe live and add to your workout sample.

    For example, if your app wants to collect water consumed during a workout, then your app will need to add the samples to the health database.

    On iPhone and iPad, on initialization, the types to collect properly on the data source will contain all possible sample types we want to collect for the current activity.

    For example, heart rate will be included even though it might not be generated by the system unless you have an external heart rate sensor.

    The data source will observe for all samples and types to collect either generated by the system or saved by your app and pass them to the live builder.

    If you want to know what the system is actually generating, you can use the same Workout Builder delegate you are using to update the metrics in your UI.

    If your app wants to modify the default types to collect, you can call enable or disable collection for type methods on the data source to add or remove the types you want.

    For example, collecting dietary water during a workout, your app will call Enable Collection and as the workout is running, add the measurement as a sample to the health database and the data source will automatically pass those samples to your live builder.

    Now that you know how to get metrics in session, let’s take a quick pause and quickly cover how to read workout metrics after the workout has been saved.

    Start by using statistics on the workout object to display a summary.

    If you want to chart metrics over the duration of the workout, you will want to use a statistics collection query with your desired interval.

    If your app does need fine grain data, keep in mind that quantity samples associated with the workout may have a count greater than one.

    This indicates that samples have finer grain data which can be accessed by using an HKQuantitySeriesSampleQuery instead.

    You may have noticed that this is the case when looking at historical Apple Watch workouts, and this will also be the case with workouts saved in iOS.

    Great, now you know how to collect metrics while your app is in the foreground and read them after the workout has been saved. Another key difference is that unlike Apple Watch, your iPhone will most likely lock while a workout is running. For privacy reasons, health data is not normally available while a device is locked, but never fear. The first time a workout session is started, the system will show a prompt indicating that workout data will be available to your app, even while the device is locked. And this is a great opportunity for your app to show a live activity with your most crucial metrics on the lock screen, allowing you to show live updates right from the lock screen without the user having to unlock their phone.

    But remember that privacy prompt I just mentioned? You may want to update your UI to omit metrics and just show the workout duration if you don’t have access to data when the device is locked or if heart rate data is unavailable, not showing the metric at all.

    But that is not all you can do from the lock screen. We are excited to bring Siri support to the lock screen. You will now be able to start, pause, resume, and cancel a workout without ever having to unlock your phone. Once the phone is unlocked, HealthKit will save the workout and make it available to your app via the Health Store. Let me go over how to add a Siri intent to your app that works from the lock screen.

    You first start by defining your Intent Handler. This must be handled from inside your app to work on the lock screen. Then, you’ll want to define the intents you want to support. I've broken them out in this example to make them easier to read.

    Next you will handle the incoming intent. Here I’ve received a StartWorkoutIntent.

    You start by first checking if there is a running workout and return a failure if there is. Next you need to get the activity type and location. For this example, I’ll just set it to an outdoor run. After which you return a success response.

    Now that you have intents defined, you need to create an app delegate to respond to them.

    You will then define the delegate in your app.

    And with that, your app now supports Siri workout intents from the lock screen.

    Adding Siri intents and live activities will ensure that the people using your app will get the most out of your app, regardless of the lock state of the device. For details on both these technologies, check out “Bring your app’s core features to users with App intents” from WWDC24, and “Meet ActivityKit” from WWDC23.

    Now that you know how to get metrics in session and how to use Siri intents in live activities, let’s move on to Crash recovery.

    Crash Recovery has been available on Watch for a while, but let me go over three key points. The system will automatically relaunch your app in case of a crash.

    The workout session in Builder will be restored in their previous state. However, you’ll need to set up your live data source again. For iPhone and iPad, we’ve added a new scene delegate you’ll use to recover your in-session workout.

    You can use the app delegate you created for Siri intents to add a scene delegate to handle crash recovery.

    We’ll start by defining our App Delegate and check if the options parameter indicates we shouldHandleActiveWorkoutRecovery.

    Now we’ll grab the recovered workoutSession from Health Store, making sure to pass the recoveredSession to your WorkoutManager. From your WorkoutManager, you can handle continuing the active workout. And if you remember, we only need to recreate our dataSource.

    Finally, let me go over some best practices for workouts.

    If you have a Watch app, be sure to start the workout there to get all available metrics. Just call Start Watch App from the Health Store.

    And once you have, be sure to mirror the workout to the iPhone. Check out “Build a multi-device workout app” from WWDC 23 to learn how.

    Your app should only request for authorization for data types you need. You don’t want your users wondering why you’re asking for authorization for data types that seem unrelated to the focus of your app.

    And finally, always use the workout builder API to create and save a workout. This will ensure that activity rings are appropriately updated.

    So that’s how to track workouts with HealthKit on iPhone and iPad. With this update, these devices now have a robust API with crash recovery and the ability to display and manage workouts even when the screen is locked. Here are some next steps before I go. Be sure to download the demo app attached to this session. It has all the code I shared today wrapped into a fully functional example you can use to get started.

    If you already have an app on iPhone or iPad, make sure to upgrade to the Workout Builder APIs I covered today. I think you’ll find them a welcome improvement.

    If you already have an app for Apple Watch, multi-platform support for the same API means your app has a whole new market for those without an Apple Watch.

    And finally, many of the features we implement are a direct result of your feedback, so keep it coming.

    We want to support the features you need to keep building those amazing apps to keep the world healthy. Thank you for watching.

    • 1:30 - Set up workout session

      // Set up workout session
      
      // Create workout configuration
      let configuration = HKWorkoutConfiguration()
      configuration.activityType = .running
      configuration.locationType = .outdoor
      
      // Create workout session
      let session = try HKWorkoutSession(healthStore: healthStore, configuration: configuration)
      session.delegate = self
      
      // Get associated workout builder and add data source
      let builder = session.associatedWorkoutBuilder()
      builder.delegate = self
      builder.dataSource = HKLiveWorkoutDataSource(healthStore: healthStore,
                                                   workoutConfiguration: configuration)
    • 1:54 - Starting the session

      // Prepare and start session
      
      session.prepare()
      
      // Start and display count down
      
      // Start session and builder collection once count down finishes
      session.startActivity(with: startDate)
      try await builder.beginCollection(at: startDate)
    • 2:14 - Handling Metrics

      // Handling collected metrics
      
      func workoutBuilder(_ workoutBuilder: HKLiveWorkoutBuilder, 
                          didCollectDataOf collectedTypes: Set<HKSampleType>) {
          for type in collectedTypes {
              guard let quantityType = type as? HKQuantityType else { return }
      
              let statistics = workoutBuilder.statistics(for: quantityType)
      
              // Update the published values
              updateForStatistics(statistics)
          }
      }
    • 2:28 - Ending workout

      // Stopping the workout session
      
      session.stopActivity(with: .now)
      
      // Session transitions to stopped then call end
      func workoutSession(_ workoutSession: HKWorkoutSession,
                          didChangeTo toState: HKWorkoutSessionState,
                          from fromState: HKWorkoutSessionState,
                          date: Date) {
          guard change.newState == .stopped, let builder else { return }
           
          try await builder.endCollection(at: change.date)
          let finishedWorkout = try await builder.finishWorkout()
          session.end()
      }
    • 7:17 - Set up Siri Intent

      // Create an INExtension within your main app
      
      // Define an intent handler
      public class IntentHandler: INExtension {
      
      }
      
      // Define the intents to support
      extension IntentHandler: INStartWorkoutIntentHandling
      
      extension IntentHandler: INPauseWorkoutIntentHandling
      
      extension IntentHandler: INResumeWorkoutIntentHandling
      
      extension IntentHandler: INEndWorkoutIntentHandling
    • 7:32 - Handle the Siri intent

      // Handle the intent
      
      public func handle(intent: INStartWorkoutIntent) async -> INStartWorkoutIntentResponse {
          let state = await WorkoutManager.shared.state
              
          switch state {
          case .running, .paused, .prepared, .stopped:
              return INStartWorkoutIntentResponse(code: .failureOngoingWorkout, 
                                                  userActivity: nil)
          default:
              break;
          }
          Task {
              await MainActor.run {
                  // Handle the intents activity type and location
                  WorkoutManager.shared.setWorkoutConfiguration(activityType: .running,   
                                                                location: .outdoor)
              }
          }
          return INStartWorkoutIntentResponse(code: .success, userActivity: nil)
       }
    • 7:52 - App Delegate

      // Implement an app delegate
      
      // Create app delegate
      class WorkoutsOniOSSampleAppDelegate: NSObject, UIApplicationDelegate {
          let handler = IntentHandler()
      
          func application(_ application: UIApplication, handlerFor intent: INIntent) -> Any? {
              return handler
          }
      }
      
      // Add app delegate to app
      struct WorkoutsOniOSSampleApp: App {
          @UIApplicationDelegateAdaptor(WorkoutsOniOSSampleAppDelegate.self) var appDelegate
      
      }
    • 9:09 - Set up crash recovery

      // App Delegate
      
      func application(_ application: UIApplication,
                       configurationForConnecting connectingSceneSession: UISceneSession,
                       options: UIScene.ConnectionOptions) -> UISceneConfiguration {
          if options.shouldHandleActiveWorkoutRecovery {
              let store = HKHealthStore()
              store.recoverActiveWorkoutSession(completion: { (workoutSession, error) in
                  // Handle error
                  Task {
                      await WorkoutManager.shared.recoverWorkout(recoveredSession: workoutSession)
                  }
              })
          }
          let configuration = UISceneConfiguration(name: "Default Configuration", 
                                                   sessionRole: connectingSceneSession.role)
          configuration.delegateClass = WorkoutsOniOSSampleAppSceneDelegate.self
          return configuration
      }
    • 9:25 - Recover the workout session

      // Recover the workout for the session
      
      
      func recoverWorkout(recoveredSession: HKWorkoutSession) {
          session = recoveredSession
          builder = recoveredSession.associatedWorkoutBuilder()
          session?.delegate = self
          builder?.delegate = self
          workoutConfiguration = recoveredSession.workoutConfiguration
      
          let dataSource = HKLiveWorkoutDataSource(healthStore: healthStore,                                                                  
                                                   workoutConfiguration: workoutConfiguration)
          builder?.dataSource = dataSource
      }
    • 0:00 - Introduction
    • The HealthKit framework allows health and fitness apps to access a centralized encrypted database of user health data. With the platform's workout APIs, you can create comprehensive workout apps for iPhone and iPad that people can use to track workouts, access health metrics, and receive recovery insights. Learn the basics of running workout sessions, accessing metrics during workouts, handling crashes, and providing workout tips and best practices.

    • 0:56 - Run a workout session
    • The same code can be used across iPhone, iPad, and Apple Watch with minor adjustments. To track any activity, you create a workout configuration, set its type, and then start a session. The workout builder collects health metrics during the workout.

    • 2:50 - Get session metrics
    • When running a workout on Apple Watch, the device's built-in sensors provide a seamless experience. In contrast, collecting heart rate data on iPhone or iPad requires pairing with an external heart rate sensor because these devices don't have one. iPhone and iPad can collect various workout metrics, but the system may generate different samples than those specifically requested by an app. You can modify the default types of data collected during a workout. After someone saves a workout, you can access and display summary statistics or chart metrics over time. iPhone workouts may have finer-grain data available for certain metrics, similar to historical Apple Watch workouts. iPhone typically locks during workouts. For privacy reasons, health data isn't usually accessible while the device is locked. However, the system can prompt someone to allow workout data access to apps even when locked. You can then display live activities on the lock screen, showing crucial metrics without the person needing to unlock their phone. Siri support is extended to the lock screen, allowing people to start, pause, resume, or cancel workouts hands-free. You can integrate Siri intents into your apps to enable this functionality.

    • 8:35 - Recover from a crash
    • Crash Recovery on Apple Watch automatically relaunches apps and restores workout sessions. For iPhone and iPad, a new scene delegate handles recovery of workout sessions after a crash. You can use this app delegate to check for recovery options and retrieve the recovered session from the Health store.

    • 9:34 - Best practices
    • To track workouts effectively with HealthKit, mirror workouts started in the Apple Watch app to iPhone, request only necessary data authorization, and employ the workout builder API. Using these recommendations, you can ensure accurate activity ring updates and enhance user experience. Also be sure to upgrade to the new APIs, download the demo app, and consider adding workout support to iPhone and iPad to expand your market reach.

Developer Footer

  • ビデオ
  • WWDC25
  • iOSとiPadOSでのHealthKitによるワークアウトのトラッキング
  • メニューを開く メニューを閉じる
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    メニューを開く メニューを閉じる
    • アクセシビリティ
    • アクセサリ
    • App Extension
    • App Store
    • オーディオとビデオ(英語)
    • 拡張現実
    • デザイン
    • 配信
    • 教育
    • フォント(英語)
    • ゲーム
    • ヘルスケアとフィットネス
    • アプリ内課金
    • ローカリゼーション
    • マップと位置情報
    • 機械学習
    • オープンソース(英語)
    • セキュリティ
    • SafariとWeb(英語)
    メニューを開く メニューを閉じる
    • 英語ドキュメント(完全版)
    • 日本語ドキュメント(一部トピック)
    • チュートリアル
    • ダウンロード(英語)
    • フォーラム(英語)
    • ビデオ
    Open Menu Close Menu
    • サポートドキュメント
    • お問い合わせ
    • バグ報告
    • システム状況(英語)
    メニューを開く メニューを閉じる
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles(英語)
    • フィードバックアシスタント
    メニューを開く メニューを閉じる
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(英語)
    • News Partner Program(英語)
    • Video Partner Program(英語)
    • セキュリティ報奨金プログラム(英語)
    • Security Research Device Program(英語)
    Open Menu Close Menu
    • Appleに相談
    • Apple Developer Center
    • App Store Awards(英語)
    • Apple Design Awards
    • Apple Developer Academy(英語)
    • WWDC
    Apple Developerアプリを入手する
    Copyright © 2025 Apple Inc. All rights reserved.
    利用規約 プライバシーポリシー 契約とガイドライン