更好的表格视图数据源:捕获和传达状态

关于本机应用程序中更健壮的表和集合视图的实用指南

我构建的几乎每个本机UI都植根于表或集合视图。 我已经写了关于 表视图及其数据源的方法 ,这是高级入门。

这篇文章概述了开发人员编写代码时面临的常见问题; 倾向于将边缘案例处理推迟到以后的日期,这永远不会发生。 我关注的主要情况是加载,加载错误和无数据,但是我下面介绍的方法可以满足您的任何需要。

并非所有人都忽略了这些极端情况,但是我注意到,如果对它们进行处理,它们通常是在表视图之前处理并通过UI的生命周期进行管理(例如,当前视图控制器,启动加载,显示旋转磁盘,从DA返回,隐藏旋转磁盘,重新加载表)。 我更喜欢将加载/错误/无数据UI直接合并到表视图本身中,更重要的是,我希望数据访问和状态捕获独立于UI及其生命周期。 当您具有由依赖于可能处于不同加载状态的不同数据源的节组成的表视图时,这将带来很多好处。 当数据可用时(逐节)呈现数据通常很重要,而不是等待所有数据全部可用。 而且只有通过内联生命周期通信才有可能。

表格视图是数据访问失败和错误无声消失的地方

场景 :您出差在外的3G连接糟糕,当您意识到应用程序远离加利福尼亚州的高速LTE连接时感觉如何破损时,您会感到羞愧和厌恶。

问题 :通信基于网络的数据加载并启用故障重试对于专业构建的应用程序和UI至关重要。 请记住,这是一个面临连接挑战的移动平台。 如果您的表视图中充满了// TODO:handle error ,则可以尝试以下方法来改善它们

方法 :在数据源中创建数据类型的标准枚举,并让表视图处理每个枚举案例。 这是我的:

您的大多数数据块的类型都是“自定义”,但其他数据块则值得

当数据源通过从模型层读取数据进行组装时,它还可以向您的数据访问对象询问任何相关暂挂请求的状态。 当前正在加载东西吗? 有错误吗? 这是什么错误?

如果数据源对这些问题有任何有趣的答案,则可以使用相应的类型枚举值将数据块组装并附加到其自己的内部数据哈希中。 假设模型层为空,数据访问对象说请求仍在进行中。 数据源可以在加载块或加载错误块后附加相关的错误对象。

您会注意到,我对数据访问服务对象使用了类似的枚举,以便在状态枚举的上下文中轻松地传达状态

当向数据源请求给定索引(路径)处的数据块时,表格视图便能够快速切换所有可能的块类型,并做出相应的响应。 通过在应用程序范围内设置一些简单的加载和重试单元格,并将其注册到表格视图中,处理这些状态便成为样板代码。 也有机会自定义每种情况,但至关重要的是,它提供了一种快速一致的方式来传达这些经常被忽略的状态:加载,加载错误(具有重试能力)和无数据。 视图还可以选择完全忽略这些枚举值,并且数据源(例如,如果它不依赖于加载)可以明确表示从不使用它们。

我的视图控制器严重依赖数据管理器及其返回的块的类型

我构建的标准LoadError单元需要使用Load Error Retry Delegate进行初始化,然后视图控制器将其分派回数据管理器。

您可以看到如何将我们在cellForRowAtIndexPath中使用的相同开关逻辑应用于所有其他表视图委托和数据源协议实现方法。

在viewDidLoad中的单元格注册可实现对每个状态的良好,标准,简单的处理,它位于util中,如下所示:

将简单的可重用生命周期单元格注册到任何表视图

结论

我到处都使用这种模式。 它的维护成本低,这意味着我可以将开发工作重点放在我们要在要构建的表中呈现给用户的产品和UI上。 但这使我充满信心,在连接不畅或数据访问有问题的情况下,我正在构建的应用程序的用户将知道正在发生的事情(正在加载),并有权采取行动(重试错误) 。 永远不会出现这样的情况:他们不得不强制关闭应用程序以重试失败的数据访问,或者来回导航以尝试重新启动某些数据访问。

注意:不要在块类型切换语句中使用默认处理程序。 如果添加新的枚举值,则希望编译器向我提醒我需要添加对新状态的支持的位置,它可以帮助您建立对使用这些数据块的所有方式的信心。 例如,这意味着您可能会考虑点击加载单元格和点击自定义单元格。