シリーズ:iOS版『見開きPDFビューア』開発記録
この記事は、ChatGPTと壁打ちしながら作成しました。また、開発時の作業ログと、Gitの変更履歴・ソースコードを調査した結果を含みます。
毎日iPadでアプリを試していると、たまにあれ?と思う時があります。それを流したり忘れたりしないで、何が起きたのだろう?中でどのような動きがあったのだろう?と考えると、デバッグ作業で役に立つことがあります。今回は、そのような気づきから問題を解決した話となります。
図1 iPad(A16)/iOS 26.5のSimulatorで、サンプルPDF「tameshibu_episode1_2_ja.pdf」を表示した画面。
第3回では、公開できるテストPDFを用意し、プロパティ識別、検索、大容量ファイルの動作を確かめた経緯を紹介しました。今回は、PDFを開いた後の状態と、外部ファイルの取り込みの話です。
読んでいたPDFやページへ戻れるか。高画質化やシャープネスの設定は残るか。普段使ううえでは残っていてほしい状態が、テストしてみると保存されていませんでした。
2026年9月8日の作業ログを中心に振り返ります。ここで紹介する自動テストは、iPad(A16)/iOS 26.5のSimulator上の記録です。
別のアプリから戻る場合と、起動し直す場合
PDFを読んでいる途中で別のアプリへ切り替え、また戻ってくる。まずは、この操作を確認しました。
作業ログでは、30ページのPDFの15ページを開いた状態で、アプリを一度閉じてからアプリに戻っています。このときは、読んでいたページを維持できていました。
ところが、プロセスを終了してからアプリを起動し直すと、「PDFファイルを選択してください」という画面へ戻ってしまいました。PDFもページ位置も復元されませんでした。
図2 ホーム画面を経由してアプリへ戻る場合(上段)と、プロセス終了後に起動し直す場合(下段)の比較。修正前は、通常の復帰ではページを維持できても、プロセス終了後にはPDF選択画面へ戻っていました。
| 確認した操作 | 修正前の結果 |
|---|---|
| 別アプリへ切り替えて戻る | 15/30ページを維持 |
| アプリのプロセスを終了し、起動し直す | PDF選択画面へ戻る |
別のアプリから戻る場合には、メモリ上に残っていた状態を使えます。一方、プロセスが終了すれば、その状態は失われます。次の起動時にも続きを読めるようにするには、文書やページ位置を保存し、読み戻す処理が必要でした。
ここでは、OSのメモリ不足によるアプリの終了を、テストからのプロセス終了で代替しています。実際にメモリ不足を起こして確認したわけではありません。
読んでいたPDFへ戻れるようにする
失敗を確認した後、アプリ本体の修正を依頼しました。文書、ページ位置、見開き設定、検索語を保存し、起動時に復元する対応です。
修正後の作業ログには、通常のPDFで15/30ページと検索語の復元に成功したことが残っています。暗号化されたPDFでは、パスワードを再入力した後に元のページへ戻ることも確認しています。
もう一つ確認したのが、自分でPDFを閉じた場合です。アプリの終了と、文書を明示的に閉じる操作は区別したいところです。閉じた文書まで次回起動時に開くと、閉じたつもりなのにまた出てきてしまいます。この場合は復元対象から外すようにしています。
現在のテストコードにも、読書状態の復元、文書を閉じた場合の保存状態の消去、保護された文書のパスワード再入力後の復帰などを確認する項目があります。
高画質化とシャープネスも、再起動するとオフになる
同じ日の作業で、第2回の記事に登場した「高画質化」と「シャープネス」の設定も確認しました。
両方をオンにしてからアプリを完全終了し、起動し直します。結果は、どちらもオフでした。画面上では切り替えられていても、その値が保存・復元の対象に入っていなかったわけです。
図3 高画質化とシャープネスの設定が、再起動するとオンからオフに戻っていた修正前の動作。
このときは、先に再現用テストを追加して失敗を確認し、その後でアプリ本体を修正しています。修正後には、再起動だけでなく、PDFを閉じる操作や設定リセットも確認しました。
| 確認内容 | 修正後の結果(作業ログ) |
|---|---|
| 高画質化をオンにして再起動 | 設定を保持 |
| シャープネスをオンにして再起動 | 設定を保持 |
| PDFを閉じる | 描画設定を保持 |
| 設定をリセットする | 両項目をオフに戻す |
| 既存のページ復元 | 関連テストに成功 |
この二つは、文書を閉じても残るアプリ全体の設定として扱うようにしました。一方、設定リセットではオフに戻します。
第2回では、高画質化の追加によって通常モードまできれいになった話を書きました。しかし、その機能の設定が次回も残るかどうかは、また別に確かめる必要があります。
「テストが通った」の中身も残す
修正後の対象テストを実行したコマンドには、正常終了を示す終了コード0が残っています。Codexの作業報告にも、設定の保持とリセット、既存のページ復元の確認に成功したとあります。
ただ、この記事を書くにあたって、当時の一時保存先にあったテスト結果ファイルをすべて読み直したわけではありません。今回参照しているのは、作業ログに残る実行記録と報告です。
また、現在のPDFViewerModelTests.swiftにも、描画設定の保存や読書状態の復元を確かめるテストがあります。当時の実行結果と、現在のコードにテストが残っていることを分けて見ています。今回、アプリのテストを再実行したわけではありません。
9月8日の関連コミットには、PDFの取り込みや状態管理の変更と、多くのUIテストがまとまっています。一つのコミットに複数の作業が入っているため、個々の作業ログとの対応はコードの内容も併せて確認しています。
iCloud Driveについては、確認できた範囲が違う
第2回で、端末の容量を気にせず読めるよう、クラウド上のPDFを開く操作を重視したことを書きました。外部から受け取ったPDFの取り込みも、テストを依頼した項目です。
図4 iCloud Driveと「このiPhone内」からPDFを開く一般的な流れ。iCloud Driveでは必要に応じてファイルをダウンロードします。端末に保存済みなら、そのまま開けます。
このときの自動テストでは、ローカルのPDFを外部受け取り処理へ渡し、コピー後の表示、ページ移動、検索入力などを確認しています。日本語・英語の検索用PDFで、検索件数が期待値と一致したという報告もあります。
一方、作業ログには、実際のiCloud Driveからの直接起動は未確認と明記されています。実機の「ファイル」アプリから操作する代わりに、ローカルPDFで検証したためです。
現在の取り込み処理には、外部ファイルへのアクセス権を扱い、NSFileCoordinatorで読み取りを調整して、アプリの管理領域へコピーする実装があります。ただ、その実装があることやローカル入力のテストが通ったことだけでは、クラウドからの取得まで確認したことにはなりません。
日常の実機試用と、今回の自動テストで確認した範囲を、ひとまとめにしないようにしています。
普段の操作を、確認できる条件にする
PDFを読み終わるまで、アプリを開き続けるとは限りません。別のアプリへ切り替えたり、アプリを終了したり、文書を閉じたりします。どれも普段の操作ですが、残しておきたい状態は少しずつ違います。
今回の作業では、「通常の復帰ではページを維持できるが、プロセス終了後は復元されない」という違いが、修正の手掛かりになりました。描画設定も、オンにできることだけでなく、文書を閉じても残るか、再起動しても残るか、リセットで戻るかを分けて確認しています。
実機で使い続けることに加え、同じ条件で繰り返せるテストを用意することで、保存漏れが分かりました。外部PDFについても、取り込み処理のテストと、実際のiCloud Driveでの操作を分けて記録しています。
次の記事では、機能が増えた後のコード整理と、不具合を調べるための診断機能について紹介したいと思います。
ソースコードと本稿の対象
ソースコードはGitHubのtyamada/MihirakiPDFViewerで公開しています。
本稿は2026年9月8日の作業ログと、10月20日時点で調査したtestingブランチの91f0853をもとにしています。紹介したテスト結果は当時のSimulatorでの記録で、今回再実行したものではありません。



