IOS 为复杂应用程序保存状态
我正在 iPad IOS 4.2 上构建一个相当复杂的业务应用程序:4 个选项卡,每个选项卡上都有潜在的深层导航路径。
在一些更有经验的 IOS 开发人员看来,用户对于在启动之间保存应用程序状态(即应用程序完全终止并随后重新启动后)的总体期望是什么?我正在使用 Core Data 并涵盖了所有数据问题,但我担心应用程序的导航树。如果用户在屏幕 3 上留下了第一个选项卡,在屏幕 4 上留下了第二个选项卡,在屏幕 2 上留下了第三个选项卡,他在其中留下了一半完整的新记录条目,并且在应用程序进入后台时,处理屏幕 3 上的第四个选项卡...您认为普通用户会期望应用程序在下次启动时记住所有这些内容吗? (我的直觉说是的,尽管我不确定会持续多久。)
如果答案是肯定的,您能否建议一个处理此问题的一般策略(并且,再说一遍,我在这里谈论的是导航树,而不是核心数据的东西)?例如,如果导航控制器用作每个选项卡的根视图控制器,那么记录有关其导航堆栈的足够信息以便以后能够恢复它们就足够简单了。但是像弹出窗口、警报/操作表或动态创建的模态 VC 之类的东西又如何呢?每个视图控制器是否应该记录其 UI 对象的状态?如果是,建议的方法是什么?
我知道这很大程度上取决于用户,但我要求的是对这些问题的总体看法,即经验之声。
I'm building a fairly complex business application on the iPad IOS 4.2: 4 tabs, with potentially deep navigational paths on each tab.
In the opinion of some of your more experienced IOS developers, what would the general expectation of a user be with respect to saving application state between launches (i.e. after an app's been fully terminated and subsequently restarted)? I'm using Core Data and have all the data issues covered, but I'm concerned about the application's navigational tree. If the user had left the 1st tab on screen 3, the 2nd tab on screen 4, the third on screen 2, where he left the entry of a new record half-complete, and was, at the time of the app entering the background, working on the 4th tab on screen 3...do you think the average user would expect the application to remember all that the next time it launched? (My gut says yes, though I'm unsure for how long.)
If the answer is yes, can you suggest a general strategy for handling this (and, again, I'm talking about the navigational tree here, not Core Data stuff)? For example, if navigational controllers were used as the root view controller for each tab, it would be simple enough to record enough info about their navigational stacks to be able to restore them later. But what about things like popovers, alert/action sheets, or modal VCs created on the fly? Should each view controller record the state of its UI objects and, if so, what is the recommended way to do this?
I know a lot of this is up to the user, but I'm asking for the general perspective on these issues, i.e. the voice of experience.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
原则上非常简单,但在实践中可能会变得相当复杂,要遍历导航层次结构并存储无法从数据模型派生的内容。
有一个名为 DTResurrectionKit 的开源实现。我还在我的网站上的应用程序中记录了我是如何做到这一点的。它类似于(但比)DTResurectionKit。
It's pretty simple in principle, but it can get quite complex in practice, to go through your navigation hierarchy and storing stuff that can't be derived from the data model.
There's an open source implementation of this called DTResurectionKit. I also documented how I do it in my apps on my website. It's similar to (but simpler than) DTResurectionKit.
考虑这个问题的最佳方法是确保用户永远不必弄清楚应用程序首次打开时他们为何或如何到达当前位置。
这完全取决于您拥有的应用程序类型以及自上次打开以来的时间长度。听起来您有一个相当复杂的向下钻取应用程序,因此我认为最好在预先确定的时间范围内记住导航堆栈。我使用 Three20 框架,它会自动为我执行此操作,但如果您要实现它,它会是这样的:
当然,现在这些值会根据您的应用程序功能和用例而有所不同,但您已经明白了。通过对人们如何使用您的应用程序以及何时使用您的应用程序做出一些广泛的假设,您可以通过在用户不记得如何到达那里时将他们推入应用程序的深处来增加用户体验。
至于实现,这只是数据。您不需要序列化活动对象来存储堆栈,只需实现在下次启动时重新创建状态所需的数据即可。您需要存储的内容很大程度上取决于您自己的设置......里程会有所不同。我使用 NSUserDefaults 来存储所有实例变量和通过 Three20 的导航堆栈。查看 TTNavigator 以获得出色的实现。
The best way to think about this is to make sure the user never has to figure out why or how they got to where they are when the app first opens.
This depends completely on the type of app you have and the length of time since the last open. It sounds like you have a fairly complex drill-down app so I think it is definitely best to remember the navigation stack, within a pre-determined time frame. I use the three20 framework which does this automatically for me, but if you were to implement it, it would be something like this:
Now of course, these values will differ based on your apps function and use cases, but you get the idea. By you making some broad assumptions about how people are using your app and when, you can increase the user experience by not shoving them so deep in your app when they won't remember how they got there.
As for implementation, it is all just data.. You dont need to serialize live objects to store the stack, just implement the data needed to recreate the state on the next launch. What you need to store is highly dependent on your own setup... mileage will vary. I use
NSUserDefaults
to store all instance vars and the navigational stack through Three20. Check out TTNavigator for a great implementation.我建议保留每个选项卡视图的状态。仅在“页面”级别。不必担心弹出窗口或不完整的数据输入(希望在将其保存到核心数据存储之前没有太多的临时状态。)
就像您所说的,很容易记住您所在的选项卡以及哪个控制器您将在每个选项卡中导航到。更多没有必要。
听起来您已经控制住了它,但为了其他人的利益:1)当您更改选项卡时,保存“活动选项卡”,2)当您在选项卡内导航时,保存“选项卡中的活动控制器”,3)当您启动应用程序时,设置“活动选项卡”,4)当您更改选项卡时,设置/确认“选项卡中的活动控制器”。
4) 的原因是选项卡的视图/控制器将延迟加载,或者可能永远不会加载。您不想为不可见且可能永远不会加载到应用程序中的选项卡设置“选项卡中的活动控制器”,这只会导致不必要的加载。通常(在应用程序加载后)您不需要更改它,因为它已经处于正确的状态。
I would suggest keeping the state of each tab view. Only at the "page" level. Don't worry about popovers or incomplete data entry (hopefully there's not too much interim state before you're saving it to your core data store.)
Like you said, it's easy enough to remember what tab you're on, and what controller you're navigated to in each tab. More isn't necessary.
It sounds like you've got it under control, but for the benefit of others: 1) when you change tabs, save "active tab", 2) when you navigate within a tab, save "active controller in tab", 3) when you launch the app, set the "active tab", 4) when you change tabs, set/confirm the "active controller in tab".
The reason for 4) is that the view/controllers for the tabs will be delayed in their loading, or perhaps never loaded. You don't want to set the "active controller in tab" for a tab that is not visible and may never be loaded into the app, it would just cause unnecessary loading. It will often happen (after the app has been loaded) that you don't need to change it because it's already in the correct state.
我认为你的时间最好花在其他地方。当然,您的应用程序可能非常适合于此,但在我们的情况下,数据部分在线,可能已经过时,同时影响不同选项卡中不同导航视图中的视图状态,等等。这不是一个无法克服的挑战,但绝对是困难且耗费大量时间。
我们决定花时间修复错误和改进功能。如果您必须做出同样的选择,我很确定您的用户会更喜欢哪个选项。特别是现在您的应用程序将在后台拨打电话时继续存在。
I think your time is better spent elsewhere. Of course, your app might be perfectly suited for this, but in our case data was partly online, could have gone stale, influenced view state in different navigation views in different tabs simultaneously, etc. etc. It's not an insurmountable challenge, but definitely hard and a huge time-sink.
We decided to spend our time on fixing the bugs and improving functionality. If you have to make the same kind of choice, I'm pretty sure which option your users would prefer. Particularly now that your app will survive a phone call in the background.