いくつかの背景
アプリケーションの状態を保持したいiOSアプリに取り組んでいます。
このアプリがリリースされる前に、iOS 7 がリリースされたか、まもなくリリースされる可能性が高く、大部分は iOS 5 から離れているようです。したがって、iOS 6 以降向けに開発することにしました。
iOS 6 には、状態を保持するための非常に優れた機能がいくつかあります。ストーリーボードのすべてのビューに一意の ID を指定し、「AppDelegate」に次の 2 つの関数を実装するだけです。
- (BOOL)application:(UIApplication*)application shouldSaveApplicationState:(NSCoder*)coder;
- (BOOL)application:(UIApplication*)application shouldRestoreApplicationState:(NSCoder*)coder;
その後、iOS はアプリのナビゲーション履歴を「自動的に」保存します。メソッド:
- (void)encodeRestorableStateWithCoder:(NSCoder*)coder;
- (void)decodeRestorableStateWithCoder:(NSCoder*)coder;
その後、データの保存と取得に使用できます。
問題なく動作します。ただし、状態を保存するメソッドは、アプリがバックグラウンドに入ったときにのみトリガーされます。
A、B、C、D の 4 つの ViewController を持つ 1 つの NavigationController があるとします。ユーザーは A から B に移動し、B で Safari に切り替えて何かをグーグルで検索します。アプリケーションの状態は B に保存されます。その後、ユーザーはアプリに戻り、C に移動してから D に移動します。D では、残念ながら例外が発生し、ダウンします。ユーザーがアプリを再起動すると、iOS は保存された状態を復元しようとします。ただし、この状態は B.
可能な解決策
アプリがすべての新しいビューで状態を保存した場合、上記のシナリオは回避できます。ただし、(私の知る限り)状態保存プロセスをトリガーするパブリック メソッドはありません。デバッグ中にコール スタックを調べたところ、iOS 6 の UIApplication オブジェクトで次のメソッドが呼び出されることがわかりました。
_saveApplicationPreservationState:
および iOS 7 の次のメソッド:
_saveApplicationPreservationState:viewController:sessionIdentifier:beginHandler:completionHandler:
iOS のバージョンによっては、上記のいずれかを呼び出す別のメソッドもあるようです。
_saveApplicationPreservationStateIfSupported
このメソッドを次のように呼び出します。
if ([[UIApplication sharedApplication] respondsToSelector:@selector(_saveApplicationPreservationStateIfSupported)])
[[UIApplication sharedApplication] performSelector:@selector(_saveApplicationPreservationStateIfSupported)];
期待されるメソッドが呼び出されていることがわかります。
実際の質問
上記の解決策を採用した場合、アプリが App Store から拒否される可能性はありますか? つまり、技術的にはプライベートメソッドではなく、公開されていないだけです。「respondsToSelector」で呼び出しをラップすることで、API が変更されてもアプリがクラッシュすることはなく、状態が頻繁に保存されなくなります。しかし、アプリが拒否される可能性がある場合、それはオプションではありません。または、上記以外の状態保存プロセスを手動で呼び出す方法はありますか? に状態を保存するカスタム ソリューションを構築するのではなく、組み込みの機能を使用できると便利ですNSUserDefaults
。