>100 Views
September 20, 25
スライド概要
2025年9月20日 iOSDC Japan 2025 day 1
Webフロントエンドエンジニア
【iOSDC Japan 2025】 watchOSで高負荷な処理 を安定させるための工夫 Github: junseinagao / Twitter: @junpai_code
自己紹介 長尾准誠 (ながおじゅんせい) 1997年2月生まれ (27歳) 普段は KODANSHAtech 合同会社 で Webフロントエンドエンジニアとして業務 チューバという金管楽器( 🎺の仲間)を高校の頃から続けています 最近は、オーボエを吹くパートナーと一緒に吹奏楽の演奏活動に力を入れています
メトロノームが楽器練習の鍵 「https://youtu.be/trl5vwdAQpI?si=vl4XERS3E08AGay9」より引用
Apple Watchで動くメトロノームを実装 watchOSでメトロノームを実装 針アニメーション+ハプティクス(振動)+音 身につけているデバイスならではの体験
だんだんテンポが遅くなる シミュレータ:問題なし/軽快 実機:テンポが徐々に遅れる 原因はwatchOSのリソース制約か...?
[補足]:高負荷ではなく安定実行かも
watchOS 開発特有の問題 watchOSアプリのライフサイクル: active / inactive / background / suspended を OS が積極的に切り替え 非対応なフレームワーク1: Core AnimationのCALayerはwatchOSでは操作できない 非対応なフレームワーク2: Haptic Feedbackは`WKInterfaceDevice.play()`で固定パターンのみ WKInterfaceDevice 9種類 + SwiftUI SensoryFeedback 1種類
watchOSアプリのライフサイクル バッテリー節約などのためにアプリケーションの実行にOSが 積極的に関与している 例えば...「Apple Watchを身につけて腕を降ろすと Inactive に 移行する」 「https://developer.apple.com/documentation/watchkit/working-with-the-watchos-app-life-cycle」より引用
柔軟な操作ができるフレームワークは非対応
どうやって音のズレを解決したか... メトロノームのタイミング管理を行っている AVAudioEngine の処理の優先度を下げない
Debuggerに接続してると安定する...?! XCodeからDebuggerを繋いで検証中は安定して動作する しかし、Macから離してApple Watch単体で実行すると3~5秒ほどでズレ 始める... → デバッガー非接続の時はwatchos によって処理 が割り込んでいるのでは...? (特にテンポのタイミング管理をしているAVAudioEngineの処理が遅れると音 の再生の遅れに繋がる)
メトロノームアプリの仕組み AVAudioEngine + AVAudioPlayerNode でサンプル時刻に再生を予約 テンポから各ビートのサンプル位置を算出 `AVAudioTime()` で再生時刻を作り、 `AVAudioPlayerNode.scheduleBuffer()` へ Haptic と UI の同期は、`DispatchQueue.global()` を使う デリゲートでHapticとUIへビートを通知する
対策 1:Extended Runtime Session WKExtendedRuntimeSession を起動して長時間実行を確保 WKBackgroundModes の目的で挙動が変化 (mindfulness → Frontmost / Physical Therapy → Background) 観測: Mind fullness では音ズレが残存する、Physical Therapy で解消 考察: Background 継続前提で他処理介入時の優先度低下の影響が小さい(?)
対策 2:非同期に処理を投げる 同期 `.sync` を廃止し、`.async` で非同期スケジューリング Haptic は事前予約(DispatchQueue.main.asyncAfter)、オーディオと独立 `DispatchQueue`で専用キューを用意(QoS: .userInteractive) 備考: QoS は状況によりシステムに無視される
対策 3:スケジューリングをまとめて投げる 予約の粒度を拡大(約1秒 → 約10秒分を一括) 再スケジューリング境界を減らし、ズレ発生箇所を回避
まとめ メトロノームのタイミング管理を行っている AVAudioEngine + AVAudioPlayerNode のスケジューリング再実行が優先度低く実行されるのを 避けるために 1. Extended Runtime Session を使用する 2. DispatchQueue を非同期に実行する 3. 処理毎にスケジューリングを並列して実行する という対策実施
【演奏デモ】 Csárdás (チャルダッシュ) 作曲:Vittorio Monti (ヴィットーリオ・モンティ)