Skip to content

Playback Clock Observation

log5r edited this page Oct 7, 2026 · 1 revision

再生時計の監視範囲と回帰検証

Issue #23 を修正する PR #40 の記録。2026-10-07、main の 86eb6b9 を基点に調査し、3e7a3b6 で修正した。再生中に時計を読む範囲を表示部品へ限定し、一覧・デッキ・LED パネル全体が時刻更新に依存しないようにした。

時計の状態と更新範囲

先頭曲では「前の曲へ戻れるか」の判定が currentTime >= 3 を直接読み、詳細エリアとコンパクト一覧のメニュー生成も時計に依存していた。LED は外側のパネルから時刻を値で渡し、iPhone の歌詞表示もデッキから時刻を渡していたため、時刻を読む画面の範囲が広がっていた。

時計には小数を含む現在時刻、整数秒、3 秒以上という真偽値を別々の Observation プロパティとして保持する。更新値が変わったプロパティだけを書き換える。現在時刻の setter を通すため、ポーリング・シーク・曲切り替え・停止・クリアでも整数秒と真偽値が一致する。前の曲ボタンの有効判定は、前のキュー項目の有無とこの真偽値を使う。

LED の時刻と Dock の時刻・VoiceOver 値は整数秒を読み、シークバー・進捗線・歌詞・解析の拍とタイムラインは小数を含む時刻を読む。解析ストリップでは時間依存の表示とアクセシビリティ値を子ビュー・修飾子へ移し、二つの候補を持つ ViewThatFits は時計を読まない。既に取得済みの長さを時計の更新ごとに再代入する処理も削除した。

動画側の時計は、0.5 秒間隔で保存していた値から AVPlayer.currentTime() の読み取りへ変更した。ビューは従来どおり PlayerViewModel の時計を読み、直接 AVPlayer を監視する構成にはしていない。新しい OS 限定 API は追加していない。

修正前後の確認

条件 確認方法 結果
LED の body が時刻に依存する 実際の LEDDisplayView.body を withObservationTracking で評価し、時刻を 0.1 秒へ更新 修正前は通知 1 回で回帰テスト失敗、修正後は通知 0 回で成功
Phone LED と解析ストリップの外側の監視範囲 各 body の評価後に時刻と長さを更新 外側には通知なし
整数秒と小数の分離 0.1→0.9→1.0 秒へ更新 小数の時計は更新し、整数秒表示は 1.0 秒で通知
先頭曲の前の曲ボタン 30Hz 相当の 89 回更新、3.0 秒への更新、先頭へのシーク 3 秒未満では通知なし、3 秒境界とリセットで有効状態が変更
再生状態の遷移 一時停止中のシーク、再開、停止、同一曲の再読み込み、クリア、前のキュー項目への移動 時計・整数秒・操作の有効状態が一致
同じ時刻と既知の長さ 同値で 30 回ポーリング、未取得の長さの補完 同値の通知なし、長さの補完は初回のみ
AVPlayer の時計 生成した無音 WAV を AVPlayer で再生し、40ms 間隔で 8 回取得 3 種類以上の位置を取得し、AVPlayer の時刻との差は 30ms 未満。一時停止中は位置を維持

Xcode 27.1 Beta、Swift 6 で macOS と iOS Simulator のビルドが成功した。macOS の関連単体テスト 51 ケース、iPhone 18 Pro(iOS 27.0)の関連単体テスト 32 件が成功した。./scripts/lint.sh は成功し、既存警告 42 件が残る。ベースラインを除いた診断も修正前後で 115 件で、ファイル・ルール別の追加はなく、ベースラインは変更していない。

iPhone の testEnglishDarkDeck、testJapaneseLightBacklitDeck、testFirstTrackRestartAvailabilityFollowsSeekingAndPlayback が成功した。追加の境界テストでは、XCTest のスライダー正規化操作で先頭を指定しても表示が 00:03 に残り、3 秒未満という前提が成立しなかった。端を越える実際のドラッグで先頭へのシークを再現し、シーク後・再生後のボタンの有効状態を確認した。

iPad Pro 13-inch(M5、iOS 27.0)の時計の単体テスト 10 件と、標準画面・設定の UI テストも成功した。

この環境ではシミュレータのテスト終了後、Xcode の診断収集が停滞した。プロセスのサンプルで XCTHRunDestinationAllocator.collectSimulatorDiagnostics のセマフォ待機を確認し、診断収集を -collect-test-diagnostics never で無効にして再実行した。再実行では iPhone の関連単体テスト 32 件と UI テスト 3 件、iPad の単体テスト 10 件と UI テスト 1 件がすべて成功し、両方の xcodebuild が exit code 0 で正常終了した。

未検証の範囲

Instruments の SwiftUI View Body による実際の描画評価回数、CPU 占有、実機 iPhone/iPad での応答時間は測定していない。単体テストは body の Observation 依存関係を確認しており、実際の描画回数そのものを計測していない。AVPlayer の時計テストは無音音源を使い、動画画面の表示の滑らかさは目視で検証していない。

音声フレームの通知、マーキー、FFT、アルバム行の再グループ化など、時計以外から発生する更新は別 Issue の対象として残る。

Clone this wiki locally