ワダチを作る #18:iPad のホーム画面のアプリだけで、ロック中の一時停止のあと音が鳴らない。実機の記録を頼りに、4 回で直した
前回(#17)は、習慣の編集の画面と記録の画面の直しでした。今回は、ずっと残っていた、坐禅のタイマーの不具合の話です。
- iPad のホーム画面のアプリだけで、ロック画面の一時停止のあと、音が鳴らない
- 最初の直し方は、実機で効かなかった
- 実機の記録で原因を確かめて、4 回目で直った
- コードの読みやすさの見直しと、本番リリース
どんな不具合か
ワダチの坐禅のタイマーは、開始の鐘・環境音(雨・波)・終わりの鐘を 1 本の音声にして、<audio> で流しています。残り時間も、音声の再生位置で決めています(#4)。
自分は、iPad mini をホーム画面のアプリ(PWA)にして、画面をロックしたまま瞑想します。そこで、次のことが起きていました。
- ロック画面で一時停止して、再生すると、環境音が鳴らない
- 一時停止 → 再生 → 一時停止すると、経過時間が戻る
端末ごとに試すと、起きるのは iPad のホーム画面のアプリだけでした。
| 端末 | Safari | ホーム画面のアプリ |
|---|---|---|
| iPhone | 問題なし | 問題なし |
| iPad | 問題なし | 不具合 |
コードは、どの端末も同じです。iPad のホーム画面のアプリにだけある癖、ということになります。
推測は、外れていた
最初の見立ては、「一時停止のあいだに、iPad がページを止めて、読み直している」でした。読み直されれば、状態が初めに戻る(時間が戻る)し、音声も読み込み直されない(音が鳴らない)からです。
確かめるため、前に、タイマーの画面に診断の記録を付けてありました。音声のすべての合図(再生・一時停止・位置の移動など)と再生位置を、時刻つきで端末に残し、あとで写せるものです。
iPad で試して、記録を貼ってもらうと、見立ては外れでした。
- ページは、読み直されていなかった(記録は、開始から止めるまで、ひと続き)
- ロック中に、一時停止のあとで再生すると、
<audio>は「再生中」と言うのに、再生位置が進まない(音が出ていない)
「本当に止めた音声を、ロック中にもう一度鳴らせない」という、iPad のホーム画面のアプリの癖でした。こちらからは、直しようがありません。
直し方:止めずに、止めたふりをする
それなら、一時停止のときに、音声を本当には止めなければよいと考えました。
- 一時停止のとき、止めた位置を覚えておき、音声は流し続ける
- 残り時間・座った時間は、覚えた位置で止める
- 再開のとき、覚えた位置に戻す
「やわらかい一時停止」と呼んでいます。iPad のホーム画面のアプリのときだけ、この形にします(ほかの端末は、今までどおり本当に止める)。
1 回目と 2 回目:まだ鳴らない
1 回目は、一時停止のあいだ、音を消して(ミュートして)流し続ける形にしました。手元の自動テストは通りました。ところが、iPad で試すと、ロック画面の再生を押しても、戻りませんでした。
2 回目は、ロック画面のボタンの受け方を直しました。やわらかい一時停止のあいだ、音声は流れ続けているので、iPad のロック画面は、ボタンを「一時停止」の形のまま出します。そこで、届いた操作の名前(再生か一時停止か)ではなく、今の状態で切り替えるようにしました。これでも、直りませんでした。
3 回目:診断の記録を、アプリで見られるようにした
ここで、もう一度、実機の記録を見ることにしました。ところが、診断の記録は、URL に ?debug を付けたときだけ出す作りです(ふだん使う人に、開発者向けの文を見せないため)。ホーム画面のアプリには、URL を打つ欄がありません。
3 回目は、そのための直しです。タイマーの画面の見出しを、3 秒以内に 5 回続けて押すと、診断の記録が出るようにしました。
4 回目:音を消すと、ロック画面の操作が届かない
記録で分かったのは、音を消すと、iOS が、ロック画面のボタンの操作を、アプリに届けなくなることでした。音が出ていない音声は、iOS にとって「再生中のもの」ではないようです。
そこで、音を消すのをやめました。
- 音声の最後に、60 秒の無音を足しておく
- 一時停止のときは、その無音の部分に飛び、音を消さずに流す(聞こえるのは無音)
- 無音の終わりが近づいたら、無音の始めに戻す(一時停止が長くても、音声が終わらない)
これで、iPad mini のホーム画面のアプリで、ロック画面の一時停止 → 再生 → 一時停止 → 再生が、どれもアプリに届き、続きから環境音が鳴り、時間も戻らなくなりました。iPhone と iPad の Safari も、前と変わらないことを確かめています。
推測で直さず、記録を持ち帰る
振り返ると、1 回目・2 回目は、どちらも推測で直していました。手元の自動テストは通りますが、実機の癖は、手元では起こせません。
直ったのは、実機の記録を持ち帰れる仕組みがあったからです。診断の記録は、公開の前に消す予定で、Issue も作ってありました。今回のことで、今の形(?debug、または見出しを 5 回)で残すことにしました。
コードの読みやすさの見直し
ほかに、公開の前にもらったレビュー(#14)の、保守についての指摘 6 件も片付けました。どれも、動きは変えない直しです。
- 習慣の編集の、保存の処理が長い → 内容の欄を読む部分を分けた(約 100 行 → 約 60 行)
- 記録を読む処理が 4 つある → 1 つにしか使っていなかったものを外した
- エラーのページに、色の値を直書きしている → 直書きは避けられない(アプリの CSS を読み込めないページ)ので、値を 1 か所にまとめ、デザインの値とずれたらテストが落ちるようにした
- 期間の判定の式が、2 か所にある → 1 か所にまとめた
- 日本の時刻(+9 時間)の計算が、4 か所にある → 1 か所にまとめた
- 習慣の並び順を、1 から振り直したほうがよい → やめた。朝と夜の習慣が同じ列を使うので、片方を振り直すと、もう片方の値と重なる
6 件のうち、何を直して、何を直さなかったかは、理由も含めて Issue に残しました。70 代の自分が読んで、「なぜこうなっているのか」が分かるように、です。
CI が、15 分で打ち切られた
今日は、PR の CI(GitHub Actions)が 2 回、15 分の上限で打ち切られました。テストが遅いのではなく、テスト用のブラウザを毎回ダウンロードする時間が、10〜14 分かかった回があったためです。やり直すと、通りました。
Actions の無料の枠(月 2,000 分。ハコヅミと共有)は、今月はぎりぎりです。ブラウザを毎回ダウンロードしない方法と合わせて、来月に直します。
本番に出した
ここまでの直しを、本番に出しました。
- iPad のホーム画面のアプリのタイマー(今回)
- やらない曜日の記録・外すときの確認・始めた日の直し・登録の画面で内容を足す(#17)
- コードの読みやすさの見直し
これで、ステップ2 から持ち越していた残件(やらない曜日の記録と、iPad のタイマー)が、どちらも片付きました。
おわりに
- 実機でしか起きない不具合は、推測で直さず、実機の記録を持ち帰る仕組みを先に作る
- 音を消した音声は、iOS には「再生中」ではない。止めたふりは、無音を流して作る
- レビューの指摘は、直さないものにも、理由を書いて残す
次は、環境音を本物の素材にする話と、CI のブラウザのダウンロードの直しを進めます。