一些背景
我正在开发一个 iOS 应用程序,我们希望保留应用程序的状态。
在此应用发布之前,iOS 7 可能已经发布或即将发布,并且大多数似乎已经远离 iOS 5。因此,我们决定为 iOS 6 及更高版本进行开发。
在 iOS 6 中,有一些非常好的功能可以保存状态。只需给故事板中的所有视图唯一的 ID,并在“AppDelegate”中实现这两个功能:
- (BOOL)application:(UIApplication*)application shouldSaveApplicationState:(NSCoder*)coder;
- (BOOL)application:(UIApplication*)application shouldRestoreApplicationState:(NSCoder*)coder;
然后,iOS 将“自动”保留应用程序的导航历史记录。方法:
- (void)encodeRestorableStateWithCoder:(NSCoder*)coder;
- (void)decodeRestorableStateWithCoder:(NSCoder*)coder;
然后可以用于存储和检索数据。
那里没有问题,它可以正常工作。但是,保存状态的方法只有在应用程序进入后台时才会触发。
假设我们有一个带有四个 ViewController 的 NavigationController:A、B、C 和 D。用户从 A 导航到 B,在 B 中他切换到 Safari 以搜索某些内容。应用程序状态保存在 B 中。然后用户切换回应用程序并导航到 C,然后导航到 D。在 D 中,应用程序不幸遇到异常并关闭。当用户重新启动应用程序时,iOS 会尝试恢复保存的状态。然而,这个状态被保存在 B 中。这意味着当应用程序启动时,它不会从头开始,不是用户离开它的地方 (D),甚至不是前一个视图 (C),而是在 B 中。
一个可能的解决方案
如果应用程序在每个新视图中保存其状态,则可以避免上述情况。但是(据我所知)没有任何公共方法可以触发状态保存过程。我在调试时检查了调用堆栈,发现 iOS 在 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
.