header

Join Contentful Community Slack   Join Contentful Community Forum

contentful.swift - Contentful 的 Swift 内容交付库

Contentful 内容交付 API内容预览 API 的 Swift 库。 它可以帮助您使用 Swift 应用程序轻松访问存储在 Contentful 中的内容。

This repository is actively maintained   MIT License   Build Status   Codebeat badge

Version   Carthage compatible   Swift Package Manager compatible   iOS | macOS | watchOS | tvOS  

什么是 Contentful?

Contentful 为数字团队提供内容基础设施,以支持网站、应用程序和设备。 与 CMS 不同,Contentful 旨在与现代软件堆栈集成。 它为结构化内容、强大的管理和交付 API 以及可定制的 Web 应用程序提供了一个中心枢纽,使开发人员和内容创建者能够更快地交付他们的产品。

目录

核心功能

开始使用

为了开始使用 Contentful Swift 库,您不仅需要安装它,还需要获取凭据,这些凭据将允许您访问 Contentful 中的内容。

安装

CocoaPods 安装
platform :ios, '9.0'
use_frameworks!
pod 'Contentful'

您可以根据需要指定 Contentful 的特定版本。 要了解有关 Podfile 中依赖版本控制运算符的更多信息,请参阅 CocoaPods 关于 Podfile 的文档

pod 'Contentful', '~> 5.0.0'

Carthage 安装

您还可以使用 Carthage 进行集成,方法是将以下内容添加到您的 Cartfile

github "contentful/contentful.swift" ~> 5.0.0

Swift Package Manager [swift-tools-version 5.0]

将以下行添加到您的依赖项数组中

.package(url: "https://github.com/contentful/contentful.swift", .upToNextMajor(from: "5.0.0"))

您的第一个请求

以下代码片段是您可以使用此库从 Contentful 获取内容的最基本片段

import Contentful

let client = Client(spaceId: "cfexampleapi",
                    environmentId: "master", // Defaults to "master" if omitted.
                    accessToken: "b4c0n73n7fu1")

client.fetch(Entry.self, id: "nyancat") { (result: Result<Entry, Error>) in
    switch result {
    case .success(let entry):
        print(entry)
    case .failure(let error):
        print("Error \(error)!")
    }
}

访问预览 API

要访问内容预览 API,请使用您的预览访问令牌并将您的客户端配置设置为如下所示使用预览。

let client = Client(spaceId: "cfexampleapi",
                    accessToken: "e5e8d4c5c122cf28fc1af3ff77d28bef78a3952957f15067bbc29f2f0dde0b50",
                    host: Host.preview) // Defaults to Host.delivery if omitted.

授权

通过导航到 Contentful Web 应用程序的“API”部分,获取 Contentful 空间的凭据。 如果您没有应用程序的访问令牌,请为交付和预览 API 创建一组新的令牌。 接下来,将您的空间 ID 和交付访问令牌传递到如下所示的初始化程序中

通过 EntryDecodable 将 Contentful 条目映射到 Swift 类

EntryDecodable 协议允许您定义内容类型和 Swift 类之间的映射,条目将序列化到这些类。 当使用诸如以下方法时

let query = QueryOn<Cat>.where(field: .color, .equals("gray"))

client.fetchArray(of: Cat.self, matching: query) { (result: Result<ArrayResponse<Cat>>) in
    guard let cats = result.value?.items else { return }
    print(cats)
}

异步返回的结果将是 ArrayResponse 的一个实例,其中泛型类型参数与您传递到 fetch 方法中的类型相同。 如果您使用的是 Query,它不限制响应包含一种内容类型的条目,您将使用返回 MixedArrayResponse 而不是 ArrayResponse 的方法。 EntryDecodable 协议扩展了 Swift 4 Foundation 标准 SDK 中的 Decodable 协议。 该库提供了用于解析 EntryDecodable 之间关系以及从每个资源的 JSON 中的字段容器中获取值的辅助方法。

在上面的示例中,Cat 是我们自己的定义类型,符合 EntryDecodableFieldKeysQueryable。 为了让库在接收 JSON 时正确创建您的模型类型,您必须将这些类型传递到您的 Client 实例

let contentTypeClasses: [EntryDecodable.Type] = [
    Cat.self
    Dog.self,
    Human.self
]

let client = Client(spaceId: spaceId,
                    accessToken: deliveryAPIAccessToken,
                    contentTypeClasses: contentTypeClasses)

Cat 模型类的源代码如下; 请注意库添加到 Swift 4 的 Decoder 类型的辅助方法,以简化对 Contentful 返回的 JSON 的解析。 您还需要将这些类型传递到您的 Client 实例,以便使用采用 EntryDecodable 类型引用的 fetch 方法

final class Cat: EntryDecodable, FieldKeysQueryable {

    static let contentTypeId: String = "cat"

    // FlatResource members.
    let id: String
    let localeCode: String?
    let updatedAt: Date?
    let createdAt: Date?

    let color: String?
    let name: String?
    let lives: Int?
    let likes: [String]?
  
    // Metadata object if available
    let metadata: Metadata?

    // Relationship fields.
    var bestFriend: Cat?

    public required init(from decoder: Decoder) throws {
        let sys         = try decoder.sys()
        id              = sys.id
        localeCode      = sys.locale
        updatedAt       = sys.updatedAt
        createdAt       = sys.createdAt

        let fields      = try decoder.contentfulFieldsContainer(keyedBy: Cat.FieldKeys.self)
        self.metadata   = try decoder.metadata()
        self.name       = try fields.decodeIfPresent(String.self, forKey: .name)
        self.color      = try fields.decodeIfPresent(String.self, forKey: .color)
        self.likes      = try fields.decodeIfPresent(Array<String>.self, forKey: .likes)
        self.lives      = try fields.decodeIfPresent(Int.self, forKey: .lives)

        try fields.resolveLink(forKey: .bestFriend, decoder: decoder) { [weak self] linkedCat in
            self?.bestFriend = linkedCat as? Cat
        }
    }

    enum FieldKeys: String, CodingKey {
        case bestFriend
        case name, color, likes, lives
    }
}

如果您想简化 EntryDecodable 的实现,请声明符合 Resource 并添加 let sys: Sys 属性到该类,并在初始化期间通过 sys = try decoder.sys() 进行赋值。 然后,idlocaleCodeupdatedAtcreatedAt 都通过 sys 属性提供,不需要声明为类成员。 但是,请注意,这种实现风格可能会使与 Realm 和 CoreData 等本地数据库框架的集成更加繁琐。

可选地,解码器有一个辅助函数来解码元数据。

此外,该库要求表示条目或资产的类型实例必须是 class 实例,而不是 struct——这是因为该库确保内存中的对象图是完整的,而且它没有重复项。

文档和参考

参考文档

该库对所有公共变量、类型和函数都有 100% 的文档覆盖率。 您可以在 web 上查看文档或在 Xcode 中浏览它们。 有关内容交付 API 的更多信息,请查看 内容交付 API 参考文档

教程和其他资源

Swift playground

如果您想通过 Swift Playground 尝试 API 的交互式演示,请执行以下操作

git clone --recursive https://github.com/contentful/contentful.swift.git
cd contentful.swift
make open

然后构建“Contentful_macOS”方案,打开 playground 文件即可开始! 注意:确保在 Xcode 右侧的“实用工具”菜单中开启了“渲染文档”按钮,并打开控制台以查看对 print 的调用输出。

示例应用程序

Github 上查看 Swift iOS 应用程序,并按照 README 上的说明获取空间副本,以便您了解 Contentful 中内容更改如何影响应用程序的呈现。

迁移

我们收集了与从旧版本库迁移相关的所有信息,并放在我们的 Migrations.md 文档中。

Swift 版本控制

建议使用 Swift 5.0,因为较旧版本的库将不会向后移植修复程序。 如果您必须使用较旧的 Swift 版本,请参阅下面的兼容标签。

Swift 版本 兼容的 Contentful 标签
Swift 5.0 [ ≥ 5.0.0 ]
Swift 4.2 [ ≥ 4.0.0 ]
Swift 4.1 [2.0.0 - 3.1.2]
Swift 4.0 [0.10.0 - 1.0.1]
Swift 3.x [0.3.0 - 0.9.3]
Swift 2.3 0.2.3
Swift 2.2 0.2.1

联系我们

对如何使用此库有疑问?

您发现了一个错误或想要提出一个功能建议吗?

您需要分享机密信息或有其他问题吗?

参与进来

PRs Welcome

我们感谢您对我们的代码仓库提供的任何帮助。有关如何贡献的更多详细信息,请参阅我们的 Contributing.md 文档。

许可证

此代码仓库在 MIT 许可下发布。

行为准则

我们希望为所有参与者提供一个安全、包容、友好的、免受骚扰的空间和体验,无论其性别认同和表达、性取向、残疾、外貌、社会经济地位、体型、种族、国籍、经验水平、年龄、宗教(或缺乏宗教信仰)或其他身份标识。

阅读我们的完整行为准则.