一个简化将数据从 Contentful 持久化到本地 CoreData 数据库的集成方案;构建于官方 Contentful Swift 库之上。该库专门使用 Content Delivery API 的
/sync
端点,将 Contentful 空间中的所有内容同步到设备。
什么是 Contentful?
Contentful 为数字团队提供内容基础设施,以便在网站、应用程序和设备中提供内容。与 CMS 不同,Contentful 旨在与现代软件栈集成。它为结构化内容提供了一个中央枢纽、强大的管理和交付 API,以及一个可定制的 Web 应用程序,使开发人员和内容创建者能够更快地交付数字产品。
在开始之前,强烈建议您熟悉 Apple 的 CoreData 框架,因为开发过程中遇到的许多问题可能特定于 CoreData。阅读 CoreData 编程指南并查看其他(非 Contentful)示例。
SynchronizationManager
管理您的 CoreData 数据库的状态,并使其与来自您的 Contentful 空间的数据保持同步。
// Tell the library which of your `NSManagedObject` subclasses that conform to `EntryPersistable` should be used when mapping API responses to CoreData entities.
let entryTypes = [Author.self, Category.self, Post.self]
// Initialize the data store and it's schema.
let store = CoreDataStore(context: self.managedObjectContext)
let persistenceModel = PersistenceModel(spaceType: SyncInfo.self, assetType: Asset.self, entryTypes: entryTypes)
// Initialize the Contentful.Client with a persistenceIntegration which will receive messages about changes when calling `sync methods`
self.client = Client(spaceId: "<YOUR_SPACE_ID>", accessToken: "<YOUR_ACCESS_TOKEN>")
// Create the manager.
self.syncManager = SynchronizationManager(
client: self.client,
localizationScheme: LocalizationScheme.all, // Save data for all locales your space supports.
persistenceStore: self.store,
persistenceModel: persistenceModel
)
// Sync with the API.
self.syncManager.sync { _ in
do {
// Fetch all `Posts` from CoreData
let post: Post? = try self.store.fetchAll(type: Post.self, predicate: NSPredicate(value: true))
} catch {
// Handle error thrown by CoreData fetches.
}
}
PersistenceModel
需要同时指定 spaceType
和 assetType
。这些分别对应于 Core Data 实体,用于存储 SyncInfo
和 Asset
对象。
为了正常运行,这些对象必须
NSManagedObject
类型。SyncSpacePersistable
和 AssetPersistable
协议。xcdatamodel
文件中定义。class SyncInfo: NSManagedObject, SyncSpacePersistable {
@NSManaged var syncToken: String?
@NSManaged var dbVersion: NSNumber?
}
class Asset: NSManagedObject, AssetPersistable {
@NSManaged var id: String
@NSManaged var localeCode: String?
@NSManaged var title: String?
@NSManaged var assetDescription: String?
@NSManaged var urlString: String?
@NSManaged var createdAt: Date?
@NSManaged var updatedAt: Date?
@NSManaged var size: NSNumber?
@NSManaged var width: NSNumber?
@NSManaged var height: NSNumber?
@NSManaged var fileType: String?
@NSManaged var fileName: String?
}
要将您的模型类与 contentful-persistence.swift
集成,您必须遵循 Contentful Assets 的 AssetPersistable
协议或 Contentful 条目类型的 EntryPersistable
协议。
接下来,您需要在项目的 xcdatamodel
文件中创建相应的模型。EntryPersistable
和 AssetPersistable
类型都需要一个非可选 id
属性,以及可选的 localeCode
、createdAt
和 updatedAt
属性。
注意: Core Data 实体中的可选性与 Swift 可选性不同。对于 Core Data 实体,可选性意味着在保存到数据库操作期间,属性可能不存在。要配置属性的可选性,请打开 Xcode "Utilities" 右侧边栏中的“数据模型检查器”,然后切换“可选”复选框。
Contentful 字段到您的数据模型实体的映射将自动派生,但您也可以通过在您的类上实现 static func fieldMapping() -> [FieldName: String]?
来定制它。
下面是一个模型类的示例。
import Foundation
import CoreData
import ContentfulPersistence
import Contentful
// The following @objc attribute is only necessary if your xcdatamodel Default configuration doesn't have your module
// name prepended to the Swift class. To enable removing the @objc attribute, change the Class for your entity to `ModuleName.Post`
@objc(Post)
class Post: NSManagedObject, EntryPersistable {
// The identifier of the corresponding Content Type in Contentful.
static let contentTypeId = "post"
// Properties of the `sys` object of Contentful resources.
@NSManaged var id: String
@NSManaged var localeCode: String?
@NSManaged var createdAt: Date?
@NSManaged var updatedAt: Date?
// Custom fields on the content type.
@NSManaged var body: String?
@NSManaged var comments: NSNumber?
// NOTE: Unlike date fields in sys properties, this library can't store `Date` for custom fields.
// Use `String` and map to date after fetching from CoreData
@NSManaged var customDateField: String?
@NSManaged var date: Date?
@NSManaged var slug: String?
@NSManaged var tags: Data?
@NSManaged var title: String?
@NSManaged var authors: NSOrderedSet?
@NSManaged var category: NSOrderedSet?
@NSManaged var theFeaturedImage: Asset?
// Define the mapping from the fields on your Contentful.Entry to your model class.
// In the below example, only the `title`, `date` and `author` fields and `featuredImage` link will be populated.
// IMPORTANT: This should not include metadata from the `sys` object (e.g. id, createdAt, etc.)
static func fieldMapping() -> [FieldName: String] {
return [
"title": "title",
"featuredImage": "theFeaturedImage",
"author": "authors"
"date": "date"
]
}
}
假设我们在 Contentful 空间中有以下内容模型
Product
- name: String
- relatedProducts: [Product]
它表示具有名称和相关产品的产品。这将转换为我们的 Swift 模型,如下所示
class Product: NSManagedObject {
// Contentful metadata
@NSManaged var id: String
@NSManaged var localeCode: String?
@NSManaged var createdAt: Date?
@NSManaged var updatedAt: Date?
// Defined properties in Contentful
@NSManaged public var name: String?
@NSManaged public var relatedProducts: NSOrderedSet?
}
extension Product: EntryPersistable {
public static var contentTypeId = "product"
public static func fieldMapping() -> [FieldName: String] {
return [
"name": "name",
"relatedProducts": "relatedProducts",
]
}
}
注意类型和设置为 ordered
的排列。
从数据库获取产品后,可以像这样访问相关产品
for product in products {
if let relatedProductsSet = product.relatedProducts,
let productsArray = relatedProductsSet.array as? [Product]
{
// productsArray is now [Product]
for product in productsArray {
// Access product properties here, e.g., product.name
print("Related product:", product.id, product.name)
}
} else {
print("No related products or unable to cast")
}
}
您还可以使用 Xcode(Swift 3.0+)捆绑的 Swift Package Manager 将 Contentful Persistence 作为依赖项添加到您的项目中。为此,请选择您的项目,将选项卡更改为“Package Dependencies”,然后添加以下 URL
https://github.com/contentful/contentful-persistence.swift
您需要使用 "master" 分支。
CocoaPods 是 Objective-C 和 Swift 的依赖项管理器,它可以自动化和简化在您的项目中使用 ContentfulPersistence 等第三方库的过程。
platform :ios, '9.3'
use_frameworks!
target :MyApp do
pod 'ContentfulPersistenceSwift', '~> 0.13.0'
end
您还可以使用 Carthage 进行集成,方法是将以下内容添加到您的 Cartfile
中
github "contentful/contentful.swift" ~> 0.13.0
有关更多信息,请查看 开发人员文档或浏览 API 文档。后者也可以作为 Docset 加载到 Xcode 中。
要开始贡献,请克隆项目,cd
到根目录并运行以下命令:make setup_env
。
make setup_env
carthage bootstrap --platform all
此命令将安装构建项目并执行测试所需的所有开发依赖项。要从命令行运行测试,请执行 make test
。测试也应该都可以直接从 Xcode 应用程序运行。
版权所有 (c) 2018 Contentful GmbH。有关更多详细信息,请参见 LICENSE。