watchOS: SwiftUIを使ったApple Watch開発の基礎

著者: IT Sectr 公開日: 2026-02-07 読了時間: 12 分

watchOSはApple Watch向けのAppleのオペレーティングシステムで、2015年に初代Apple Watchとともに初めてリリースされました。watchOSアプリ開発はSwiftUIとWatchKitを使用してSwiftで行われます。特徴:小型の長方形ディスプレイ、0.3Whの限られたバッテリー消費、Bluetoothを介したiPhoneとの緊密な統合。Counterpoint Researchによると、Apple Watchは世界のスマートウォッチ市場の30%以上を占めています。

重要なポイント

  • watchOS — XNUカーネルベースのApple Watch用OS、低消費電力に重点
  • SwiftUI — watchOSアプリのインターフェース開発の主要フレームワーク
  • Watch Connectivity — Apple WatchとiPhone間のデータ交換メカニズム
  • Smart Stack — watchOS 10で導入されたインテリジェントウィジェットスタック
  • HealthKit — センサーにアクセスするためのフレームワーク:心拍数、SpO2、温度、加速度計

watchOSとは?

watchOSはAppleのスマートウォッチ向けオペレーティングシステムで、Darwin XNUカーネルをベースにしています。2015年4月24日にApple Watch Series 0とともに初めてリリースされました。システムはiOSと同じアーキテクチャ上に構築されていますが、小型ディスプレイ(1.5〜1.9インチ)、限られたメモリ(Series 9で最大1GB RAM)、および最小限の消費電力向けに最適化されています。

StatCounter(2026年)によると、watchOSはスマートウォッチOS市場の約55%を占め、Wear OSや中国メーカーの独自システムをリードしています。Appleは毎年メジャーなwatchOSアップデートをリリースし、発売から最大5年間ウォッチをサポートします。

watchOSの主な特徴はiPhoneへの依存です。ほとんどのアプリはデータ同期にWatch Connectivityを使用します。watchOS 6以降、ウォッチはApp Storeから直接アプリをインストールできますが、iPhoneからの完全な独立性はwatchOS 9でのみサポートされています。

watchOSのバージョン履歴

最初のバージョンWatch OS 1.0はサードパーティアプリをサポートしておらず、プリインストールされたAppleアプリのみでした。watchOS 2(2015年)は開発者向けにSDKを公開しました。watchOS 3(2016年)はアプリの起動を7倍高速化しました。watchOS 6(2019年)はウォッチにApp Storeを導入しました。watchOS 9(2022年)は服薬管理と改善された睡眠トラッキングを追加しました。watchOS 10(2023年)はリリース以来最大のインターフェースアップデートとなりました。

watchOSバージョン主な革新
Watch OS 12015最初のバージョン、Appleネイティブアプリのみ
watchOS 22015オープンSDK、サードパーティアプリ、Watch Connectivity
watchOS 32016アプリの瞬時起動、Dock、Scribble
watchOS 62019ウォッチのApp Store、Cycle Tracking、Noiseアプリ
watchOS 92022服薬管理、睡眠ステージ、改良されたランニングコンパニオン
watchOS 102023Smart Stack、Double Tap、新しい文字盤

watchOSのアーキテクチャ

watchOSのアーキテクチャは3つのレイヤーで構成され、ハードウェアをユーザーアプリケーションから分離しています。iOSとは異なり、watchOSはコンポーネントベースのアプローチを採用しています。アプリは2つのターゲット(拡張機能とiPhoneホスト)で構成されます。

カーネルとシステムサービス

最下層は、AppleのS4/S5/S6/S7/S8/S9チップ用ドライバーを備えた修正版XNUカーネルです。Apple Watch Series 9は、56億トランジスタと4コアNeural Engineを搭載したS9 SiPを使用しています。システムサービスには、Core Bluetooth、Watch Connectivity、HealthKit、Core Motionが含まれます。すべてのバックグラウンドタスクは、消費電力を最適化するシステムスケジューラBGTaskSchedulerによって管理されます。

WatchKit — アプリケーションレイヤー

WatchKitはwatchOSアプリのインターフェースを作成するためのフレームワークです。WKInterfaceController、WKInterfaceGroup、WKInterfaceLabel、WKInterfaceButtonが含まれます。watchOS 6以降、AppleはWatchKitではなくSwiftUIを推奨しています。SwiftUIは同じ機能を提供しますが、宣言的構文と画面サイズへの自動適応を備えています:38mm(272×340)、42mm(312×390)、40mm(324×394)、44mm(368×448)、45mm(396×484)、49mm(Apple Watch Ultraで410×502)。

バックグラウンドモードと消費電力

watchOSはバッテリー節約のため、アプリのバックグラウンドアクティビティを制限しています。利用可能なバックグラウンドモード:Workout(ワークアウト)、HealthKit(健康モニタリング)、Location(位置情報)、Audio(オーディオプレーヤー)、Complication(文字盤データ)。各モードにはentitlementsで個別のcapabilityが必要です。一般的な消費電力:アクティブアプリ — 50-80mA、バックグラウンドモード — 5-15mA、スタンバイ — 1-3mA。

swift
import BackgroundTasks
import WatchKit

/// watchOSでのバックグラウンドデータ更新のスケジュール設定
class BackgroundTaskManager: NSObject {

    func scheduleBackgroundRefresh() {
        let request = BGAppRefreshTaskRequest(identifier: "com.example.refresh")
        request.earliestBeginDate = Date(timeIntervalSinceNow: 30 * 60)

        try? BGTaskScheduler.shared.submit(request)
    }

    func handleAppRefresh(task: BGAppRefreshTask) {
        task.expirationHandler = { task.setTaskCompleted(success: false) }

        DataService.shared.fetchData { result in
            switch result {
            case .success:
                ComplicationController.reloadComplications()
                task.setTaskCompleted(success: true)
            case .failure:
                task.setTaskCompleted(success: false)
            }
        }
    }
}

/// WKExtensionDelegateでのバックグラウンドタスクの登録
class ExtensionDelegate: NSObject, WKExtensionDelegate {
    let manager = BackgroundTaskManager()

    func handle(_ backgroundTasks: Set<WKBackgroundTask>) {
        for task in backgroundTasks {
            switch task {
            case let refreshTask as BGAppRefreshTask:
                manager.handleAppRefresh(task: refreshTask)
            default:
                task.setTaskCompleted(success: false)
            }
        }
    }
}

BGTaskSchedulerは、バックグラウンドタスクが最適なタイミング(ウォッチが充電中でiPhoneに接続されているとき)に実行されることを保証します。WKExtensionDelegateは受信したバックグラウンドタスクを処理し、文字盤のデータを更新します。ComplicationController.reloadComplicationsは選択された文字盤のウィジェットを更新します。

watchOS 10: Smart StackとDouble Tap

watchOS 10 — プラットフォーム史上最大のインターフェースアップデートで、2023年9月にリリースされました。システムは階層型ナビゲーションからコンテンツ指向ナビゲーションに移行し、メイン画面はアプリドックを置き換えるインテリジェントウィジェットスタックSmart Stackになりました。

Smart Stack

Smart Stackは文字盤の下に表示されるウィジェットの縦方向リストです。ウィジェットはコンテキストに応じてランク付けされます:朝は天気とカレンダー、日中はアクティビティとリマインダー、夕方は瞑想と睡眠準備を表示します。開発者はiOS 17と同じAPIを使用して、WidgetKit for watchOSでカスタムウィジェットを追加できます。

Double Tap

Double Tapは人差し指と親指を合わせるジェスチャーで、画面に触れずに加速度計とジャイロスコープで認識されます。Apple Watch Series 9とUltra 2では、このジェスチャーはNeural Engineを介してハードウェアレベルで処理されます。開発者はUIDoubleTapGestureRecognizerまたはSwiftUI修飾子.onTapGesture(count: 2)を介してイベントを受け取ります。このジェスチャーはキャリブレーションを必要とせず、任意の手の向きで機能します。

開発者向け新API

watchOS 10では以下が導入されました:SpringおよびKeyframeアニメーションをサポートするSwiftUI Animation、ウォッチで地図を表示するMapKit、短い動画(最大30秒)を再生するVideoPlayer、ジェスチャー対応の改善されたVoiceOver、そしてNavigationViewに代わる新しいナビゲーションパラダイムNavigationStack。

API目的利用可能開始
WidgetKit for watchOSSmart Stack用ウィジェットwatchOS 10
UIDoubleTapGestureDouble TapジェスチャーwatchOS 10 (S9+)
MapKitウォッチでの地図表示watchOS 10
NavigationStack新しいナビゲーションパラダイムwatchOS 10
SwiftUI Keyframeフレーム単位のアニメーションwatchOS 10

Apple Watch向けSwiftUI

SwiftUIはwatchOSインターフェースを開発するための主要フレームワークです。AppleはwatchOS 7以降のすべての新規プロジェクトでSwiftUIを推奨しています。ウォッチ向けSwiftUIはiOSと同じ原則を使用しますが、watchOS固有の修飾子とコンポーネントを備えています。

watchOS固有のSwiftUIコンポーネント

watchOS向けSwiftUIには以下が含まれます:画面間をスワイプするページスタイルのTabView、クラウン回転を処理するDigitalCrownRotation、起動間で状態を保持するSceneStorage、カスタム通知用のWKNotificationScene、文字盤データ用のComplicationDescriptor

swift
import SwiftUI
import HealthKit

/// 心拍数モニタリング用watchOSアプリ
@main
struct HeartMonitorApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        WKNotificationScene(
            controller: NotificationController.self,
            category: "heartAlert"
        )
    }
}

struct ContentView: View {
    @State private var heartRate: Double = 0
    private let healthStore = HKHealthStore()

    var body: some View {
        TabView {
            HeartRateView(rate: heartRate)
                .tabItem { Label("心拍数", systemImage: "heart.fill") }

            StepsView()
                .tabItem { Label("歩数", systemImage: "figure.walk") }

            SettingsView()
                .tabItem { Label("設定", systemImage: "gear") }
        }
        .tabViewStyle(.page)
        .onAppear(perform: setupHealthKit)
    }

    private func setupHealthKit() {
        guard HKHealthStore.isHealthDataAvailable() else { return }
        let heartType = HKQuantityType(.heartRate)

        healthStore.requestAuthorization(toShare: nil, read: [heartType]) { success, error in
            guard success else { return }
            startHeartRateQuery()
        }
    }

    private func startHeartRateQuery() {
        let heartType = HKQuantityType(.heartRate)
        let query = HKObserverQuery(sampleType: heartType, predicate: nil) { _, _, error in
            guard error == nil else { return }
            fetchLatestHeartRate()
        }
        healthStore.execute(query)
    }

    private func fetchLatestHeartRate() {
        let heartType = HKQuantityType(.heartRate)
        let sort = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false)
        let query = HKSampleQuery(sampleType: heartType, predicate: nil,
                                    limit: 1, sortDescriptors: [sort]) { _, samples, _ in
            guard let sample = samples?.first as? HKQuantitySample else { return }
            let rate = sample.quantity.doubleValue(for: HKUnit(from: "count/min"))
            DispatchQueue.main.async { heartRate = rate }
        }
        healthStore.execute(query)
    }
}

struct HeartRateView: View {
    let rate: Double

    var body: some View {
        VStack(spacing: 12) {
            Image(systemName: "heart.fill")
                .foregroundStyle(.red)
                .font(.system(size: 48))
                .symbolEffect(.pulse)

            Text("\(Int(rate))")
                .font(.system(.title, design: .rounded))
                .contentTransition(.numericText())
                .bold()

            Text("bpm")
                .font(.caption)
                .foregroundStyle(.secondary)
        }
    }
}

HeartMonitorAppは、SwiftUIでの典型的なwatchOSアプリ構造を示しています:画面間をスワイプするページスタイルのTabView、リアルタイム心拍数読み取りのためのHealthKit統合、通知処理のためのWKNotificationScene。パルスアニメーション付きのSymbolEffectは、Neural Engineのハードウェアアクセラレーションを使用して、CPU負荷なしでスムーズなアニメーションを実現します。

Digital Crownとジェスチャー

Digital CrownはApple Watch側面のホイールです。SwiftUIはクラウンの回転に値をバインドするDigitalCrownRotationを提供します。修飾子はバインディング、範囲、ステップを受け入れます。ジェスチャー:tap(タップ)、longPress(長押し)、swipe(スワイプ)、pan(ドラッグ)はすべてSwiftUI標準で、ウォッチの画面サイズに適応しています。

WatchKitとwatchOSアプリコンポーネント

WatchKitはUIKitアプローチを使用するオリジナルのwatchOSフレームワークです。AppleはSwiftUIを推奨していますが、WatchKitはレガシープロジェクトや特定のタスク(WKInterfaceGroupでの複雑なアニメーションやSiriKit統合)に関連性を維持しています。

watchOSアプリの構造

watchOSアプリは2つのターゲットで構成されます:WatchKit Extension(ロジックとインターフェース)とiOS Companion App(設定と同期)。Xcode 15以降、iOSコンパニオンなしでスタンドアロンアプリを作成することが可能です。インターフェースはInterface.storyboard(WatchKit)で、またはSwiftUIを介してプログラム的に記述されます。

コンポーネントWatchKitSwiftUI
画面WKInterfaceControllerView
ボタンWKInterfaceButtonButton
テーブルWKInterfaceTableList
グループWKInterfaceGroupVStack / HStack
画像WKInterfaceImageImage / AsyncImage
ラベルWKInterfaceLabelText
マップWKInterfaceMapMap (watchOS 10+)
コンプリケーションCLKComplicationDataSourceComplicationDescriptor

コンプリケーション — 文字盤のデータ

コンプリケーションはApple Watchの文字盤にデータを表示するウィジェットです。開発者はCLKComplicationDataSourceプロトコルを実装し、さまざまな文字盤タイプ(circular、rectangular、modular、extraLarge)のテンプレートを提供します。watchOS 10はSwiftUI向けの簡略化APIであるComplicationDescriptorをサポートしています。データは最大30分間隔のバックグラウンドタスクで更新されます。

Watch ConnectivityによるiPhone統合

Watch ConnectivityはBluetoothまたはWi-Fiを介してApple WatchとiPhone間でデータを交換するためのフレームワークです。ペアリングされたデバイス間の唯一の通信方法です。WCSessionはセッションを管理する中心的なクラスです。iOSアプリとwatchOS拡張機能はWCSessionDelegateを実装する必要があります。

データ転送方法

Watch Connectivityは4つのデータ転送方法を提供します:sendMessage — 確認付き即時送信(両方のアプリがアクティブな場合のみ機能)、transferUserInfo — データ辞書のバックグラウンド配信、transferFile — メタデータ付きファイル転送、updateApplicationContext — 共有状態の同期。すべての方法は接続が復元されたときに配信を保証します。

swift
import WatchConnectivity

/// iPhoneとApple Watch間の同期マネージャー
final class ConnectivityManager: NSObject, WCSessionDelegate {

    static let shared = ConnectivityManager()
    private let session = WCSession.default

    override private init() {
        super.init()
        session.delegate = self
        session.activate()
    }

    // MARK: — iPhoneからウォッチへのデータ送信
    func sendWorkoutData(_ data: [String: Any]) {
        guard session.isReachable else {
            // ウォッチが利用不可の場合 — コンテキストに保存
            try? session.updateApplicationContext(data)
            return
        }
        session.sendMessage(data, replyHandler: nil) { error in
            print("送信エラー: \(error.localizedDescription)")
        }
    }

    // MARK: — ウォッチでのデータ受信
    func session(_ session: WCSession,
                 didReceiveMessage message: [String: Any]) {
        DispatchQueue.main.async {
            NotificationCenter.default.post(
                name: NSNotification.Name("dataReceived"),
                object: message
            )
        }
    }

    func session(_ session: WCSession,
                 activationDidCompleteWith activationState: WCSessionActivationState,
                 error: Error?) {
        print("WCSessionがアクティブ化されました: \(activationState.rawValue)")
    }

    // watchOSでは不要だがプロトコルでは必須
    func sessionDidBecomeInactive(_ session: WCSession) {}
    func sessionDidDeactivate(_ session: WCSession) {
        session.activate()
    }
}

ConnectivityManagerはWCSessionを操作するためのシングルトンを実装しています。sendWorkoutDataはisReachableをチェックします:ウォッチがアクティブな場合、データはsendMessageを介して即座に送信されます。そうでない場合は、遅延配信用にapplicationContextに保存されます。受信側のonReceiveMessageは受信メッセージを処理し、NotificationCenterを介してアプリに通知します。

ファイル交換と同期

transferFileは大量のデータ(画像、音声ファイル、アーカイブ)を転送できます。最大ファイルサイズは100MBです。ファイルは受信デバイスのInboxディレクトリに保存されます。transferUserInfoは最大100KBのJSONデータに適しています。すべての方法はバックグラウンドで動作します:デバイスが利用不可の場合、転送はキューに入れられ、接続が復元されると自動的に再開されます。

watchOSアプリの公開

watchOSアプリの公開はiOSと同じルールに従います:Apple Developer Programのサブスクリプション(年間99ドル)とApp Reviewの審査通過が必要です。アプリはiOSアプリの一部として、またはスタンドアロンアプリとしてApp Store Connectにアップロードされます。

ビルドと配布

watchOSアプリは2つの方法で配布できます:iOSアプリの組み込み拡張機能として(iOSアプリバンドルにwatchOS .appが含まれる)、またはスタンドアロンアプリとして(iPhoneなしでダウンロードして実行)。スタンドアロンモードにはInfo.plistでWKRunsIndependently = YESが必要です。watchOSアプリのサイズはセルラーネットワークダウンロードで50MBに制限されています。

App Reviewの要件

watchOSの特別な要件:アプリはアクティブなiPhoneなしで正しく動作する必要があり(スタンドアロンとして主張する場合)、インターフェースは拡大なしで読み取り可能でなければならず、すべてのインタラクティブ要素は少なくとも44ポイントのサイズが必要です。組み込み機能を複製するアプリ(例えば、付加価値のない心拍数モニター)は禁止されています。

要件説明
アプリサイズセルラーダウンロードで最大50MB、Wi-Fiで最大4GB
スタンドアロンモードInfo.plistでWKRunsIndependently = YES
タッチターゲットすべてのインタラクティブ要素で最低44pt
セキュリティHealthKitデータは同意なしにサーバーに送信不可
パフォーマンスアプリ起動は5秒以内

よくある質問

watchOS開発にはどの言語が使用されますか?

主要言語はSwiftUIフレームワークを使用したSwiftです。UIKit上のWatchKitもサポートされていますが、Appleはすべての新しいwatchOSプロジェクトでSwiftUIを推奨しています。Objective-Cは2019年より前にリリースされたレガシーアプリでのみ使用されます。watchOS 7以降、すべてのAppleの例は排他的にSwiftUIを使用しています。

watchOSアプリの動作にiPhoneは必要ですか?

watchOS 6以降、Apple WatchはiPhoneなしでApp Storeから直接アプリをインストールできます。ただし、多くの機能(データ同期、プッシュ通知、位置情報)はiPhoneとのペアリングが必要です。完全なスタンドアロンアプリはwatchOS 9とビルド設定のWKRunsIndependentlyで可能です。

アクティブなアプリ使用時のApple Watchのバッテリー持続時間は?

Apple Watch Series 9の標準的なバッテリー持続時間は混合モードで最大18時間です。GPSと心拍数モニターをアクティブに使用した場合 — 5〜7時間。watchOS 10はSmart StackとBGTaskSchedulerを通じて消費電力を最適化し、watchOS 9と比較してバックグラウンドアプリアクティビティを最大4倍削減します。

iPhoneとApple Watch間でデータを転送するには?

Watch Connectivityフレームワークは4つの方法を提供します:sendMessage(即時転送)、transferUserInfo(バックグラウンド)、transferFile(最大100MBのファイル)、updateApplicationContext(状態同期)。すべての方法はBluetoothまたはWi-Fi経由で動作し、接続が切れた場合は自動的にキューイングされます。

Apple Watchで利用可能なセンサーは?

Apple Watch Series 9とUltra 2には以下が含まれます:加速度計、ジャイロスコープ、光学式および電気式心拍数センサー、SpO2(酸素飽和度)、手首温度センサー、気圧計、コンパス、GPS L1+L5、マイク。センサーへのアクセスはHealthKitとCore Motionを介して行われます。心拍数とSpO2データにはユーザーの明示的な許可が必要です。

まとめ

  • watchOS — XNUカーネル上のAppleのスマートウォッチ用OS、エネルギー効率とiPhone統合に重点
  • SwiftUI — watchOSの主要フレームワーク、宣言的レイアウトと自動画面サイズ適応を提供
  • watchOS 10はSmart Stack、Double Tap(S9+)、NavigationStack、ウィジェット用WidgetKitを導入
  • Watch Connectivity — 4つの転送モードを持つBluetooth/Wi-Fi経由のiPhoneとの唯一の通信チャネル
  • HealthKitはApple Watchセンサーへのアクセスを提供:心拍数、SpO2、温度、加速度計、GPS
  • コンプリケーション — CLKComplicationDataSourceまたはSwiftUIで実装される文字盤ウィジェット
  • 公開にはApple Developer Program、最大50MB(セルラー)、厳格なパフォーマンス管理が必要

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください