[Watch OS] 歩数を表示するだけの機能を実装してみる

# はじめに
Watch OSアプリでCoreMotionを使い歩数の値を取得・表示する実装をやってみました。
初めてのWatch OSアプリ開発なので基礎的なところからまとめました。

# 環境
Xcode 14.3

# 内容

プロジェクトの新規作成からやっていきます
まずはwatch OSのAppを選択
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/87101e56-4e03-ee3b-3fae-0cca2b5fa89a.png">

その後、Watch OS専用アプリかどうかを選択します。今回は`Watch-only App`を選択
- Watch-only App　
- Watch App With New Companion iOS App 


デフォルトはこんな形
![スクリーンショット 2023-09-16 22.45.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/fd4cc858-c883-ea8e-8583-ac3e94359df0.png)

`ContentView`に歩数を表示する最低実装をしてみる

```swift
import SwiftUI
import CoreMotion

struct ContentView: View {
    @State private var steps: Int = 0
    @State private var isUpdating: Bool = false
    private let pedometer = CMPedometer()

    var body: some View {
        VStack(spacing: 20) {
            Label(String(steps), systemImage: "figure.walk")
                .font(.title)

            Button(isUpdating ? "Stop Tracking" : "Start Tracking") {
                if isUpdating {
                    stopPedometerUpdates()
                } else {
                    startPedometerUpdates()
                }
                isUpdating.toggle()
            }
            .foregroundColor(isUpdating ? .red : .primary)
        }
        .padding()
    }

    private func startPedometerUpdates() {
        pedometer.startUpdates(from: Date()) { (data, error) in
            guard let data = data, error == nil else { return }

            Task { @MainActor in
                steps = Int(truncating: data.numberOfSteps)
            }
        }
    }

    private func stopPedometerUpdates() {
        pedometer.stopUpdates()
        steps = 0
    }
}
```

ここでは`import CoreMotion`してから`CMPedometer`を使います
歩数計オブジェクト（`CMPedometer`）を使って、歩数や移動距離、昇降階数などの情報を取得することができます

https://developer.apple.com/documentation/coremotion/cmpedometer

UIはこんな感じに

<img width="200" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/0318413f-3ddc-8bbf-b9a7-35a4ce5ad35f.png">

この状態で動かしたらエラーがでました

`This app has crashed because it attempted to access privacy-sensitive data without a usage description.  The app's Info.plist must contain an NSMotionUsageDescription key with a string value explaining to the user how the app uses this data.`

CoreMotionを使う上での許可をとってないよとのこと

こちらの`NSMotionUsageDescription`をInfo.plistに追加します

<img width="600" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/26bf77a0-6ef6-0ff0-5257-bd7beabcb788.png">

https://developer.apple.com/documentation/bundleresources/information_property_list/nsmotionusagedescription

もう一度動かす

<img width="200" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/dc267113-37fc-c06f-78f0-d0293189a97e.png">

プライバシー許可の確認が表示され、シミュレーターでアプリも動くようになりました🎉

歩数の値は実機で動かさないと取得できませんが、後ほど動かしたところ上記の実装で問題なく動きました〜


# おわりに
初めてのWatch OSアプリでしたがサクッと作れて驚きでした。
iOS17より追加される`High Frequency Motion API`などはとても気になっているので少しずつWatch OSでできることを調べていこうと思います！

https://developer.apple.com/jp/watchos/

# 参考

https://zenn.dev/moutend/articles/feebf0120dce6e6426fa

https://zenn.dev/oka_yuuji/articles/d91204beb37f9e

https://zenn.dev/yorifuji/articles/af1b54285c1c4f7a3249