简体   繁体   English

在iOS 6及更高版本中手动调用状态保留

[英]Manually invoke state preservation in iOS 6 and onwards

Some background 一些背景

I'm working on an iOS app where we want the state of the application to be preserved. 我正在开发一个iOS应用程序,我们希望保留应用程序的状态。
Before this app is out, iOS 7 is likely to have been released or is soon to be released and the majority seems to have moved away from iOS 5. We have therefore decided to develop for iOS 6 an onwards. 在此应用程序发布之前,iOS 7很可能已经发布或即将发布,而且大多数似乎已经从iOS 5发布。因此,我们决定开发iOS 6版本。

In iOS 6 there are some really nice functionality for preserving state. 在iOS 6中,有一些非常好的功能可以保存状态。 Just give all views in the storyboard unique IDs and implement these two functions in the "AppDelegate": 只需在storyboard中提供所有视图的唯一ID,并在“AppDelegate”中实现这两个功能:

- (BOOL)application:(UIApplication*)application shouldSaveApplicationState:(NSCoder*)coder;
- (BOOL)application:(UIApplication*)application shouldRestoreApplicationState:(NSCoder*)coder;

iOS will then "automagically" preserve the navigation history of the app. 然后,iOS将“自动”保留应用程序的导航历史记录。 The methods: 方法:

- (void)encodeRestorableStateWithCoder:(NSCoder*)coder;
- (void)decodeRestorableStateWithCoder:(NSCoder*)coder;

can then be used to store and retrieve data. 然后可以用于存储和检索数据。
No problems there it works without issues. 它没有问题,没有问题。 But, the methods that save the state are only triggered when the app entered the background. 但是,只有在应用程序进入后台时才会触发保存状态的方法。

Let's say we have one NavigationController with four ViewControllers: A, B, C and D. The user navigates from A to B, in B he switches over to Safari to google something. 假设我们有一个带有四个ViewControllers的NavigationController:A,B,C和D.用户从A导航到B,在B中他切换到Safari来google。 The application state is saved in B. The user then switches back to the app and navigates on to C and then to D. In D the app unfortunately encounters an exception and goes down. 应用程序状态保存在B.然后用户切换回应用程序并导航到C然后导航到D.在D中,应用程序不幸遇到异常并且关闭。 When the user restarts the app, iOS will try to restore the saved state. 当用户重新启动应用程序时,iOS将尝试恢复已保存的状态。 This state however, was saved in B. Which means that when the app launches, it doesn't start from the beginning, not where the user left it (D) and not even the previous view (C) but in B. 然而,这个状态保存在B中。这意味着当应用程序启动时,它不会从头开始,而不是用户离开它的地方(D),甚至不是前一个视图(C),而是在B.

A possible solution 可能的解决方案

The above scenario could be avoided if the app saved its state at every new view. 如果应用程序在每个新视图中保存其状态,则可以避免上述情况。 However there aren't (as far as I know) any public methods to trigger the state preservation process. 但是,据我所知,没有任何公共方法可以触发状态保存过程。 I have examined the call stack while debugging and found out that iOS calls the following method on the UIApplication object in iOS 6: 我在调试时检查了调用堆栈,发现iOS在iOS 6中的UIApplication对象上调用了以下方法:

_saveApplicationPreservationState:

and the following method in iOS 7: 以及iOS 7中的以下方法:

_saveApplicationPreservationState:viewController:sessionIdentifier:beginHandler:completionHandler:

There also seems to be another method that calls one of the above depending on the iOS version: 似乎还有另一种方法根据iOS版本调用上述方法之一:

_saveApplicationPreservationStateIfSupported

By invoking this method like this: 通过调用此方法,如下所示:

    if ([[UIApplication sharedApplication] respondsToSelector:@selector(_saveApplicationPreservationStateIfSupported)])
        [[UIApplication sharedApplication] performSelector:@selector(_saveApplicationPreservationStateIfSupported)];

I can see that the expected methods are called. 我可以看到调用了预期的方法。

The actual question 实际的问题

If I would go with the above solution could that get my app rejected from the App Store? 如果我使用上述解决方案可以让我的应用程序被拒绝从App Store? I mean technically it's not a private method, it's just not exposed. 我的意思是技术上它不是一种私人方法,它只是没有暴露。 By wrapping the call in "respondsToSelector" the app won't crash if the APIs are changed, it just won't save the state as often. 通过将调用包装在“respondsToSelector”中,如果API被更改,应用程序将不会崩溃,它只是不会经常保存状态。 But if it could get the app rejected it's not an option. 但如果它可以让应用程序被拒绝,那么这不是一个选择。 Or is there any other way to manually invoke the state preservation process other than the one described above? 或者除了上面描述的那个之外还有其他任何手动调用状态保存过程的方法吗? I would be nice to be able to use the built-in functionality rather than building a custom solution that saves the state to NSUserDefaults . 我很高兴能够使用内置功能,而不是构建一个将状态保存到NSUserDefaults的自定义解决方案。

Event if the question is already 2 years old, i'll try my luck. 事件,如果问题已经2岁,我会试试运气。 Btw op, i guess, you'll have most likely solved it by now. 顺便说一句,我想,你现在很可能已经解决了它。

You're gonna for sure get rejected. 你肯定会被拒绝。 They are scanning the sourcecode for methods you are calling. 他们正在扫描您要调用的方法的源代码。 I had this several times, back when i was using the UDID methods. 当我使用UDID方法时,我已经好几次了。 Hope it helped. 希望它有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM