【问题标题】:iOS what is the highest level networking abstraction that is appropriate for handling bi-directional sync over http?iOS 适用于通过 http 处理双向同步的最高级别网络抽象是什么?
【发布时间】:2026-01-22 05:55:01
【问题描述】:

在处理网络问题时,我正在查看Apple networking guidelines that suggest that the user should try to work with the highest level of abstraction possible

我正在开发一个客户端-服务器应用程序,其中服务器是主设备,而 iOS 设备是从设备。它们通过 HTTP 进行通信,建立在应用程序使用会话的整个生命周期内都存在的连接。应用程序和服务器通过此连接同步资产。

我的问题是 - 哪种抽象级别适合通过 HTTP 实现双向同步? 是套接字、NSURLConnection、一些 AFNetworking 子类、输入/输出流吗?

【问题讨论】:

  • 我认为这首先是关于您的应用程序问题域的问题。在不知道您需要同步多少数据、如何表达这些更改或您想要提供什么样的用户体验的情况下,没有足够的信息来提出准确的建议。无论您做什么,都将在响应能力、功耗、数据一致性和实施成本之间进行权衡。你想优先考虑什么?
  • 大部分数据是1Kb以下的字符串和JSON对象。理想情况下,我希望保留数据的本地缓存,以防止每次呈现视图控制器时都必须进行网络调用。这意味着我需要考虑某种后台同步,在应用程序运行并启动界面更新时每 X 秒检查一次服务器更新。
  • 特别是,我担心服务器无法通过 IP 轻松定位特定设备,因此我希望设备启动某种连接,并且服务器保持此连接处于活动状态以进行数据交换.不过我不确定这是一种什么样的联系。

标签: ios http network-programming synchronization afnetworking-2


【解决方案1】:

对此有很多可能的好答案。我认为我所能做的就是提供一种对我来说效果很好的模式,但它可能不适用于您的需求和用例。重申我上面的评论“无论您做什么,都将在响应能力、功耗、数据一致性和实施成本之间进行权衡。”

我所追求的抽象级别是一组服务对象,它们根据应用程序的域模型公开一个接口。应用程序的其余部分,主要是控制器层中的对象,应该能够通过将模型传递给方法(例如“fetchUserWithId:userId”或“createUser:user”)与这些服务进行通信,而无需了解 URL、路径、或网络层涉及的 HTTP 动词。

这些服务对象可以将域模型操作映射到路径、HTTP 动词以及可能的请求正文或标头。在大多数情况下,我发现服务本身可以共享一个较低级别的服务,该服务接受这些值并构造实际的 HTTP 请求。这为通过 NSURLRequest、NSURLSession、AFNetworking 或您喜欢的任何库配置主机名、设置全局标头和管理请求队列提供了一个位置。

我将在我的服务对象方法中包含完成块,以便控制器可以收到成功或失败的通知,但尽量不要使用这些块将模型传递回控制器层。相反,我更喜欢让控制器监控核心数据或其他一些持久层并对变化做出反应。这样,控制器就可以保持灵活性并对他们关注的模型中的任何更新做出响应,并且不会假设他们知道这些模型的所有可能更改来源。

到目前为止,这些都没有解决您应该如何检查模型的远程更改。最好的选择可能是设计一个不需要这样做的系统。如果您的客户端仅在将数据发布到服务器时才获得一组最近的更改,它仍然可以提供良好的用户体验吗?服务器是否可以使用推送通知偶尔通知客户端更新?

如果您必须检查更改,则套接字或长轮询通常比短轮询响应更快,但漫游移动客户端可能难以保持这些连接打开。所有这些方法还倾向于保持客户端的无线电处于活动状态并在此过程中消耗大量电力。

在不了解更多有关问题的情况下,我会默认使用短轮询,但尝试设计交互以使其尽可能不频繁(例如,在应用恢复时进行一次检查)。我还使用 HTTP 功能(etags、if-modified-since 或自定义内容范围)来限制没有更改时的响应大小。如果您有一个很好的服务层来管理网络请求,这也为您提供了一个引入速率限制的好地方。允许控制器表达对获取最新信息的兴趣,但推迟服务以根据应用程序的其余部分正在执行的操作来限制或批处理请求(例如,如果这些模型最近更新,则不要重复相同的请求,除非用户故意触发了动作)。

【讨论】:

    最近更新 更多