watchOSはApple Watch向けのAppleのオペレーティングシステムで、2015年に初代Apple Watchとともに初めてリリースされました。watchOSアプリ開発はSwiftUIとWatchKitを使用してSwiftで行われます。特徴:小型の長方形ディスプレイ、0.3Whの限られたバッテリー消費、Bluetoothを介したiPhoneとの緊密な統合。Counterpoint Researchによると、Apple Watchは世界のスマートウォッチ市場の30%以上を占めています。
重要なポイント
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でのみサポートされています。
最初のバージョン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 1 | 2015 | 最初のバージョン、Appleネイティブアプリのみ |
| watchOS 2 | 2015 | オープンSDK、サードパーティアプリ、Watch Connectivity |
| watchOS 3 | 2016 | アプリの瞬時起動、Dock、Scribble |
| watchOS 6 | 2019 | ウォッチのApp Store、Cycle Tracking、Noiseアプリ |
| watchOS 9 | 2022 | 服薬管理、睡眠ステージ、改良されたランニングコンパニオン |
| watchOS 10 | 2023 | Smart Stack、Double Tap、新しい文字盤 |
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は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。
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 — プラットフォーム史上最大のインターフェースアップデートで、2023年9月にリリースされました。システムは階層型ナビゲーションからコンテンツ指向ナビゲーションに移行し、メイン画面はアプリドックを置き換えるインテリジェントウィジェットスタックSmart Stackになりました。
Smart Stackは文字盤の下に表示されるウィジェットの縦方向リストです。ウィジェットはコンテキストに応じてランク付けされます:朝は天気とカレンダー、日中はアクティビティとリマインダー、夕方は瞑想と睡眠準備を表示します。開発者はiOS 17と同じAPIを使用して、WidgetKit for watchOSでカスタムウィジェットを追加できます。
Double Tapは人差し指と親指を合わせるジェスチャーで、画面に触れずに加速度計とジャイロスコープで認識されます。Apple Watch Series 9とUltra 2では、このジェスチャーはNeural Engineを介してハードウェアレベルで処理されます。開発者はUIDoubleTapGestureRecognizerまたはSwiftUI修飾子.onTapGesture(count: 2)を介してイベントを受け取ります。このジェスチャーはキャリブレーションを必要とせず、任意の手の向きで機能します。
watchOS 10では以下が導入されました:SpringおよびKeyframeアニメーションをサポートするSwiftUI Animation、ウォッチで地図を表示するMapKit、短い動画(最大30秒)を再生するVideoPlayer、ジェスチャー対応の改善されたVoiceOver、そしてNavigationViewに代わる新しいナビゲーションパラダイムNavigationStack。
| API | 目的 | 利用可能開始 |
|---|---|---|
| WidgetKit for watchOS | Smart Stack用ウィジェット | watchOS 10 |
| UIDoubleTapGesture | Double Tapジェスチャー | watchOS 10 (S9+) |
| MapKit | ウォッチでの地図表示 | watchOS 10 |
| NavigationStack | 新しいナビゲーションパラダイム | watchOS 10 |
| SwiftUI Keyframe | フレーム単位のアニメーション | watchOS 10 |
SwiftUIはwatchOSインターフェースを開発するための主要フレームワークです。AppleはwatchOS 7以降のすべての新規プロジェクトでSwiftUIを推奨しています。ウォッチ向けSwiftUIはiOSと同じ原則を使用しますが、watchOS固有の修飾子とコンポーネントを備えています。
watchOS向けSwiftUIには以下が含まれます:画面間をスワイプするページスタイルのTabView、クラウン回転を処理するDigitalCrownRotation、起動間で状態を保持するSceneStorage、カスタム通知用のWKNotificationScene、文字盤データ用のComplicationDescriptor。
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はApple Watch側面のホイールです。SwiftUIはクラウンの回転に値をバインドするDigitalCrownRotationを提供します。修飾子はバインディング、範囲、ステップを受け入れます。ジェスチャー:tap(タップ)、longPress(長押し)、swipe(スワイプ)、pan(ドラッグ)はすべてSwiftUI標準で、ウォッチの画面サイズに適応しています。
WatchKitはUIKitアプローチを使用するオリジナルのwatchOSフレームワークです。AppleはSwiftUIを推奨していますが、WatchKitはレガシープロジェクトや特定のタスク(WKInterfaceGroupでの複雑なアニメーションやSiriKit統合)に関連性を維持しています。
watchOSアプリは2つのターゲットで構成されます:WatchKit Extension(ロジックとインターフェース)とiOS Companion App(設定と同期)。Xcode 15以降、iOSコンパニオンなしでスタンドアロンアプリを作成することが可能です。インターフェースはInterface.storyboard(WatchKit)で、またはSwiftUIを介してプログラム的に記述されます。
| コンポーネント | WatchKit | SwiftUI |
|---|---|---|
| 画面 | WKInterfaceController | View |
| ボタン | WKInterfaceButton | Button |
| テーブル | WKInterfaceTable | List |
| グループ | WKInterfaceGroup | VStack / HStack |
| 画像 | WKInterfaceImage | Image / AsyncImage |
| ラベル | WKInterfaceLabel | Text |
| マップ | WKInterfaceMap | Map (watchOS 10+) |
| コンプリケーション | CLKComplicationDataSource | ComplicationDescriptor |
コンプリケーションはApple Watchの文字盤にデータを表示するウィジェットです。開発者はCLKComplicationDataSourceプロトコルを実装し、さまざまな文字盤タイプ(circular、rectangular、modular、extraLarge)のテンプレートを提供します。watchOS 10はSwiftUI向けの簡略化APIであるComplicationDescriptorをサポートしています。データは最大30分間隔のバックグラウンドタスクで更新されます。
Watch ConnectivityはBluetoothまたはWi-Fiを介してApple WatchとiPhone間でデータを交換するためのフレームワークです。ペアリングされたデバイス間の唯一の通信方法です。WCSessionはセッションを管理する中心的なクラスです。iOSアプリとwatchOS拡張機能はWCSessionDelegateを実装する必要があります。
Watch Connectivityは4つのデータ転送方法を提供します:sendMessage — 確認付き即時送信(両方のアプリがアクティブな場合のみ機能)、transferUserInfo — データ辞書のバックグラウンド配信、transferFile — メタデータ付きファイル転送、updateApplicationContext — 共有状態の同期。すべての方法は接続が復元されたときに配信を保証します。
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アプリの公開はiOSと同じルールに従います:Apple Developer Programのサブスクリプション(年間99ドル)とApp Reviewの審査通過が必要です。アプリはiOSアプリの一部として、またはスタンドアロンアプリとしてApp Store Connectにアップロードされます。
watchOSアプリは2つの方法で配布できます:iOSアプリの組み込み拡張機能として(iOSアプリバンドルにwatchOS .appが含まれる)、またはスタンドアロンアプリとして(iPhoneなしでダウンロードして実行)。スタンドアロンモードにはInfo.plistでWKRunsIndependently = YESが必要です。watchOSアプリのサイズはセルラーネットワークダウンロードで50MBに制限されています。
watchOSの特別な要件:アプリはアクティブなiPhoneなしで正しく動作する必要があり(スタンドアロンとして主張する場合)、インターフェースは拡大なしで読み取り可能でなければならず、すべてのインタラクティブ要素は少なくとも44ポイントのサイズが必要です。組み込み機能を複製するアプリ(例えば、付加価値のない心拍数モニター)は禁止されています。
| 要件 | 説明 |
|---|---|
| アプリサイズ | セルラーダウンロードで最大50MB、Wi-Fiで最大4GB |
| スタンドアロンモード | Info.plistでWKRunsIndependently = YES |
| タッチターゲット | すべてのインタラクティブ要素で最低44pt |
| セキュリティ | HealthKitデータは同意なしにサーバーに送信不可 |
| パフォーマンス | アプリ起動は5秒以内 |
よくある質問
主要言語はSwiftUIフレームワークを使用したSwiftです。UIKit上のWatchKitもサポートされていますが、Appleはすべての新しいwatchOSプロジェクトでSwiftUIを推奨しています。Objective-Cは2019年より前にリリースされたレガシーアプリでのみ使用されます。watchOS 7以降、すべてのAppleの例は排他的にSwiftUIを使用しています。
watchOS 6以降、Apple WatchはiPhoneなしでApp Storeから直接アプリをインストールできます。ただし、多くの機能(データ同期、プッシュ通知、位置情報)はiPhoneとのペアリングが必要です。完全なスタンドアロンアプリはwatchOS 9とビルド設定のWKRunsIndependentlyで可能です。
Apple Watch Series 9の標準的なバッテリー持続時間は混合モードで最大18時間です。GPSと心拍数モニターをアクティブに使用した場合 — 5〜7時間。watchOS 10はSmart StackとBGTaskSchedulerを通じて消費電力を最適化し、watchOS 9と比較してバックグラウンドアプリアクティビティを最大4倍削減します。
Watch Connectivityフレームワークは4つの方法を提供します:sendMessage(即時転送)、transferUserInfo(バックグラウンド)、transferFile(最大100MBのファイル)、updateApplicationContext(状態同期)。すべての方法はBluetoothまたはWi-Fi経由で動作し、接続が切れた場合は自動的にキューイングされます。
Apple Watch Series 9とUltra 2には以下が含まれます:加速度計、ジャイロスコープ、光学式および電気式心拍数センサー、SpO2(酸素飽和度)、手首温度センサー、気圧計、コンパス、GPS L1+L5、マイク。センサーへのアクセスはHealthKitとCore Motionを介して行われます。心拍数とSpO2データにはユーザーの明示的な許可が必要です。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。