watchOSで高負荷な処理を安定させるための工夫

>100 Views

September 20, 25

スライド概要

2025年9月20日 iOSDC Japan 2025 day 1

profile-image

Webフロントエンドエンジニア

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

ダウンロード

関連スライド

各ページのテキスト
1.

【iOSDC Japan 2025】 watchOSで高負荷な処理 を安定させるための工夫 Github: junseinagao / Twitter: @junpai_code

2.

自己紹介 長尾准誠 (ながおじゅんせい) 1997年2月生まれ (27歳) 普段は KODANSHAtech 合同会社 で Webフロントエンドエンジニアとして業務 チューバという金管楽器( 🎺の仲間)を高校の頃から続けています 最近は、オーボエを吹くパートナーと一緒に吹奏楽の演奏活動に力を入れています

3.

メトロノームが楽器練習の鍵 「https://youtu.be/trl5vwdAQpI?si=vl4XERS3E08AGay9」より引用

4.

Apple Watchで動くメトロノームを実装 watchOSでメトロノームを実装 針アニメーション+ハプティクス(振動)+音 身につけているデバイスならではの体験

5.

だんだんテンポが遅くなる シミュレータ:問題なし/軽快 実機:テンポが徐々に遅れる 原因はwatchOSのリソース制約か...?

6.

[補足]:高負荷ではなく安定実行かも

7.

watchOS 開発特有の問題 watchOSアプリのライフサイクル: active / inactive / background / suspended を OS が積極的に切り替え 非対応なフレームワーク1: Core AnimationのCALayerはwatchOSでは操作できない 非対応なフレームワーク2: Haptic Feedbackは`WKInterfaceDevice.play()`で固定パターンのみ WKInterfaceDevice 9種類 + SwiftUI SensoryFeedback 1種類

8.

watchOSアプリのライフサイクル バッテリー節約などのためにアプリケーションの実行にOSが 積極的に関与している 例えば...「Apple Watchを身につけて腕を降ろすと Inactive に 移行する」 「https://developer.apple.com/documentation/watchkit/working-with-the-watchos-app-life-cycle」より引用

9.

柔軟な操作ができるフレームワークは非対応

10.

どうやって音のズレを解決したか... メトロノームのタイミング管理を行っている AVAudioEngine の処理の優先度を下げない

11.

Debuggerに接続してると安定する...?! XCodeからDebuggerを繋いで検証中は安定して動作する しかし、Macから離してApple Watch単体で実行すると3~5秒ほどでズレ 始める... → デバッガー非接続の時はwatchos によって処理 が割り込んでいるのでは...? (特にテンポのタイミング管理をしているAVAudioEngineの処理が遅れると音 の再生の遅れに繋がる)

12.

メトロノームアプリの仕組み AVAudioEngine + AVAudioPlayerNode でサンプル時刻に再生を予約 テンポから各ビートのサンプル位置を算出 `AVAudioTime()` で再生時刻を作り、 `AVAudioPlayerNode.scheduleBuffer()` へ Haptic と UI の同期は、`DispatchQueue.global()` を使う デリゲートでHapticとUIへビートを通知する

13.

対策 1:Extended Runtime Session WKExtendedRuntimeSession を起動して長時間実行を確保 WKBackgroundModes の目的で挙動が変化 (mindfulness → Frontmost / Physical Therapy → Background) 観測: Mind fullness では音ズレが残存する、Physical Therapy で解消 考察: Background 継続前提で他処理介入時の優先度低下の影響が小さい(?)

14.

対策 2:非同期に処理を投げる 同期 `.sync` を廃止し、`.async` で非同期スケジューリング Haptic は事前予約(DispatchQueue.main.asyncAfter)、オーディオと独立 `DispatchQueue`で専用キューを用意(QoS: .userInteractive) 備考: QoS は状況によりシステムに無視される

15.

対策 3:スケジューリングをまとめて投げる 予約の粒度を拡大(約1秒 → 約10秒分を一括) 再スケジューリング境界を減らし、ズレ発生箇所を回避

16.

まとめ メトロノームのタイミング管理を行っている AVAudioEngine + AVAudioPlayerNode のスケジューリング再実行が優先度低く実行されるのを 避けるために 1. Extended Runtime Session を使用する 2. DispatchQueue を非同期に実行する 3. 処理毎にスケジューリングを並列して実行する という対策実施

17.

【演奏デモ】 Csárdás (チャルダッシュ) 作曲:Vittorio Monti (ヴィットーリオ・モンティ)