2

I am using SOAP with wsdl2objc generated code. I have multiple view controllers who need to share the data provided by the web service. I would like to have a data model part, but I am having a hard time seeing how to handle this. Naturally the calls should be asynch. My question is, what might be the best practise? Who should be responsible for fetching data? Who should store the data? How to handle concurrency? Any thoughts would be appreciated!

UPDATE: I was considering using CoreData, but was not sure if what the benefits were when the data is frequently updated. My biggest problem is how to handle the scenario where a view controller requests data from the model, but no data is available. That means performing a slow web service call and somehow informing the view controller when the data is in. Is notification centre the way to go here? how would the flow be? should the view controllers constantly be listening for update notifications? My thoughts are, that a view controller registers as an observer, populates the view with data from the model (regardless of empty data), and automatically updates on received notifications, i.e. fetches the data from the model which now has the "newest" data available. That leave all network call out of the view controllers, allows the view controllers to access shared data. Thoughts?

4

2 回答 2

3

在您更新的问题中,是的,我认为通知中心是后台网络任务在新数据可用时更新您的视图控制器的完美方式。

你问:

视图控制器是否应该不断地监听更新通知?

有点。“不断收听”一词可能意味着它不断检查更新。显然,它并没有真正这样做(或者,更重要的是,您不希望它这样做)。相反,它只是将自己注册为该通知的观察者(并确保当视图被关闭时,它也会取消注册自己)。这样,它将收到您的任何自定义通知的通知,但不会浪费大量 CPU 周期“持续监听”。

然后你跟进并询问:

我的想法是,视图控制器注册为观察者,用模型中的数据填充视图(不管空数据),并自动更新收到的通知,即从现在具有“最新”数据的模型中获取数据可用的。这将所有网络调用留在视图控制器之外,允许视图控制器访问共享数据。想法?

基本上,是的,这听起来不错。我对此的唯一细微改进是,我将使用将应用程序发布到商店时的最新数据预先填充应用程序数据库。这样,当应用程序检索最新数据时,用户可以查看一些内容。也许这在您的场景中无效,但通常最好向用户展示一些东西(即使有点过时),而不是什么都没有,而应用程序检索最新和最好的。

最后(您可能已经在考虑这个),我会确保您向用户展示一些视觉指示,表明数据正在后台下载。也许是一个放置得当的UIActivityIndicatorView(即微调器)或UIProgressView. 如果您正在处理表格视图,也许更新文本UIRefreshControl以说明下载正在进行中。也许也更新状态栏中的网络活动指示器。


我相信每个人都有自己的解决方法,但这里有一些关于我在应用程序中所做的一些观察,即数据检索过程很复杂,完全异步发生,并且应用程序可以在下载/处理过程中正常进行:

  1. 除了标准模型、视图和视图控制器类之外,我还有一个单独的“xml 控制器”,它负责下载和解析结果。我让它异步启动下载。

  2. 为了方便 xml 控制器和视图控制器之间的通信,我使用了通知。这样,xml 控制器将发布有关下载/解析过程的开始和完成特定阶段的通知。如果视图控制器在更新过程中不可靠,则视图控制器可以选择在开始时显示微调器,和/或在特定下载/解析阶段完成后相应地刷新自己。必须注意真正识别所有应用层并发问题。在每一步,您都必须处理“如果后台队列中的模型数据发生变化怎么办”的逻辑场景。

    最重要的是,在进行异步更新时,防御性编程是当今的规则。您永远不能仅仅因为您最近检索到的东西在片刻之后就有效,就做出假设。我们在代码中愉快地做出的许多假设不再成立。我也会对基于某些索引的任何操作(例如“第 5 项”)更加谨慎,并且绝对倾向于基于键的操作(例如“唯一标识符为 4027 的项”)。

  3. 就数据库层并发问题而言,它在一定程度上取决于持久存储的性质。如果您使用的是 Core Data,请查看 WWDC 2012 - 214 Best Practices with Core Data,其中讨论了并发性。或者参见Core Data Programming Guide中的Concurrency with Core Data 。如果使用 SQLite,一个简单的解决方案是为数据库操作设置一个专用的串行队列,例如FMDB 的. 顺便说一句,如果您使用后一种方法,您需要确保将数据库交互分解为尽可能小的操作,以避免占用数据库。 FMDatabaseQueue

  4. 如果您想让用户了解异步下载/更新过程的进度,您可能需要考虑您的框架。有些应用程序会做一些简单的事情,比如状态栏中的网络活动指示器。其他人在一些公共导航栏中更新一些状态消息。我还为我的通知使用了一个自定义容器,这样我就不必在每个视图控制器中添加“显示用户状态更新”。这里有很多方法,但是您可能应该避免需要在每个视图控制器中包含状态更新代码的解决方案(显然,如果视图控制器依赖于由后台队列修改的当前项目,则在在这种情况下,它不是状态更新问题,而是应用程序流程问题)。

于 2013-02-16T15:55:08.470 回答
0

由于 SOAP 信封开销,直接从 iOS 应用程序使用 SOAP 并不是非常理想的。我建议改用 REST XML/JSON 服务。

如果您没有 JSON/XML 服务,您可以使用后端移动平台来处理后端复杂的 SOAP 协议,让您在前端消费轻量级、易于处理的 REST/JSON。

一些“企业开源移动应用开发平台”确实提供这些类型的服务。

于 2013-02-18T12:35:17.137 回答