在iOS App中使用核心数据背景上下文获取远程数据

核心数据是Apple提供的用于开发iOS应用程序的对象图和持久性框架。 它处理对象生命周期,对象图管理和持久性。 它支持用于处理应用程序内部模型层的许多功能,例如:

  • 对象之间的关系管理。
  • 使用撤消管理器更改跟踪
  • 延迟加载对象和属性
  • 验证方式
  • 使用NSPredicate进行分组,过滤和查询
  • 模式迁移
  • 使用SQLite作为后备存储的选项之一。

Core Data自动提供了许多高级功能,它具有陡峭的学习曲线,可供开发人员首次学习和使用。 在iOS 10之前,要在我们的应用程序中设置Core Data,我们需要执行许多配置和样板代码来构建Core Data Stack。 幸运的是,在iOS 10中,Apple引入了NSPersistentContainer,我们可以使用它初始化所有堆栈并以很少的代码获得NSManagedObject上下文。

在本文中,我们将构建一个简单的演示应用程序,该应用程序可从远程《星际大战》 API获取电影列表,并使用后台队列天真地在没有同步策略的情况下同步Core Data存储中的数据。 我们将建立:

  1. 受管对象模型架构和影片实体。
  2. 电影实体的托管对象。
  3. CoreDataStack:负责使用该模式构建NSPersistentContainer。
  4. ApiRepository:一个类,负责使用URL会话数据任务从StarWars API中获取电影数据列表。
  5. DataProvider:一个类,提供接口以从后台存储库中使用NSManagedObjectContext从数据存储库中获取电影列表并将其同步到Core Data存储。
  6. FilmsViewController:与数据提供者进行通信并使用NSFetchedResultsController从核心数据视图上下文中获取并观察更改的视图控制器,然后在UITableView中显示电影列表。

您可以在项目GitHub存储库中签出该应用程序的完整源代码。

alfianlosari / CoreData-Fetch-API-Background
使用核心数据背景上下文获取Star Wars API的iOS应用– alfianlosari / CoreData-Fetch-API-Background github.com

您还可以通过单击以下网站的链接来结帐并尝试使用StarWars API。

SWAPI –星际大战API
星球大战(Star Wars)API或“ swapi”(Swah-pee)是世界上第一个量化且可通过编程访问的数据源…… swapi.co

受管对象模型架构和影片实体

我们将执行的第一步是创建包含影片实体的托管对象模型架构。 从Xcode创建新文件,然后从核心数据模板中选择数据模型。 将文件命名为StarWars,它将以.xcdatamodeld作为文件扩展名保存。

单击我们刚刚创建的数据模型文件,Xcode将打开数据模型编辑器,在其中我们可以将实体添加到托管对象模型模式中。 单击添加实体,然后将新实体的名称设置为电影。 确保将代码生成设置为“手动/无”,这样Xcode不会自动生成Model类。 然后添加所有类型的属性,如下图所示:

为电影实体创建托管对象

在使用Film Entity创建架构之后,我们需要使用NSManagedObject作为超类为Film类创建新文件。 当我们将Film Entity插入NSManagedObjectContext中时,将使用此类。 在内部,我们声明与具有关联类型的实体相关的所有属性,还需要使用@NSManaged关键字声明该属性,以使编译器了解该属性将在其后备存储区使用Core Data。 我们需要将NSNumber用于基本类型(例如Int,Double或Float),以将值存储在ManagedObject中。 我们还创建了一个简单的函数,该函数映射JSON字典属性并将其分配给Film Managed Object的属性。

创建一个名为FilmListViewController的新文件。 FilmListViewController继承自UITableViewController作为超类。 内部需要声明两个实例属性:

  1. DataProvider:我们将用于触发影片同步的DataProvider类。 应用程序启动时将从AppDelegate注入。
  2. NSFetchedResultsController:NSFetchedResultsController是Apple Core Data类,它充当控制器,您可以使用该控制器来管理Core Data提取请求的结果并向用户显示数据。 它还提供委托给委托,以便在商店中的相关实体发生更改时接收更改并对更改做出反应。 在我们的例子中,我们使用NSFetchRequest来获取Film实体,然后告诉它按照EpisodeId的升序对结果进行排序。 我们使用FetchRequest和DataProvider View Context初始化NSFetchedResultController。 FilmListViewController也将被分配为委托,以便它可以在基础数据更改时做出反应并更新TableView。

TableViewDataSource方法将向NSFetchedResultsController询问其节,节中的行数以及给定IndexPath处的表视图单元格的实际数据。 我们设置单元格的文本标签和详细文本标签,以及电影对象的电影标题和电影导演。

对于NSFetchedResultController委托,为了这个示例,我们重写controllerDidChangeObject只是天真地重新加载TableView。 如果要使用给定的indexPath,则可以在此处使用动画执行细粒度的TableView更新。

最后,确保在情节提要中设置UITableViewController的类以使用FilmListViewController类。 生成并运行项目进行测试。

结论

核心数据是一个非常强大的框架,当我们要构建一个应用程序以同步来自云的数据并具有可脱机工作的功能时,可以使用它。 对于具有关系功能的其他持久性框架,还有其他解决方案,例如Realm Database,我们可以将其用作其他选项。