Swiftpack.co - Package - contentful/contentful.swift


Join Contentful Community Slack   Join Contentful Community Forum

contentful.swift - Swift Delivery SDK for Contentful

Swift SDK for the Contentful Content Delivery API and Content Preview API. It helps you to easily access your Content stored in Contentful with your Swift applications.

This repository is actively maintained   MIT License   Build Status   Coverage Status   Codebeat badge

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

What is Contentful?

Contentful provides content infrastructure for digital teams to power websites, apps, and devices. Unlike a CMS, Contentful was built to integrate with the modern software stack. It offers a central hub for structured content, powerful management and delivery APIs, and a customizable web app that enable developers and content creators to ship their products faster.

Table of contents

Core Features

Getting started

In order to get started with the Contentful Swift SDK you'll need not only to install it, but also to get credentials which will allow you to have access to your content in Contentful.


CocoaPods installation
platform :ios, '9.0'
pod 'Contentful'

You can specify a specific version of Contentful depending on your needs. To learn more about operators for dependency versioning within a Podfile, see the CocoaPods doc on the Podfile.

pod 'Contentful', '~> 5.0.0'

Carthage installation

You can also use Carthage for integration by adding the following to your Cartfile:

github "contentful/contentful.swift" ~> 5.0.0

Swift Package Manager [swift-tools-version 5.0]

Add the following line to your array of dependencies:

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

Your first request

The following code snippet is the most basic one you can use to fetch content from Contentful with this SDK:

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>) in
    switch result {
    case .success(let entry):
    case .error(let error):
        print("Error \(error)!")

Accessing the Preview API

To access the Content Preview API, use your preview access token and set your client configuration to use preview as shown below.

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


Grab credentials for your Contentful space by navigating to the "APIs" section of the Contentful Web App. If you don't have access tokens for your app, create a new set for the Delivery and Preview APIs. Next, pass the id of your space and delivery access token into the initializer like so:

Map Contentful entries to Swift classes via EntryDecodable

The EntryDecodable protocol allows you to define a mapping between your content types and your Swift classes that entries will be serialized to. When using methods such as:

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 }

The asynchronously returned result will be an instance of ArrayResponse in which the generic type parameter is the same type you've passed into the fetch method. If you are using a Query that does not restrict the response to contain entries of one content type, you will use methods that return MixedArrayResponse instead of ArrayResponse. The EntryDecodable protocol extends the Decodable protocol in Swift 4's Foundation standard library. The SDK provides helper methods for resolving relationships between EntryDecodables and also for grabbing values from the fields container in the JSON for each resource.

In the example above, Cat is a type of our own definition conforming to EntryDecodable and FieldKeysQueryable. In order for the SDK to properly create your model types when receiving JSON, you must pass in these types to your Client instance:

let contentTypeClasses: [EntryDecodable.Type] = [

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

The source for the Cat model class is below; note the helper methods the SDK adds to Swift 4's Decoder type to simplify for parsing JSON returned by Contentful. You also need to pass in these types to your Client instance in order to use the fetch methods which take EntryDecodable type references:

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]?

    // 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.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

If you want to simplify the implementation of an EntryDecodable, declare conformance to Resource and add let sys: Sys property to the class and assign via sys = try decoder.sys() during initialization. Then, id, localeCode, updatedAt, and createdAt are all provided via the sys property and don't need to be declared as class members. However, note that this style of implementation may make integration with local database frameworks like Realm and CoreData more cumbersome.

Additionally, the SDK requires that instances of a type representing an entry or asset must be a class instance, not a struct—this is because the SDK ensures that the in-memory object graph is complete, but also that it has no duplicates.

Documentation & References

Reference Documentation

The SDK has 100% documentation coverage of all public variables, types, and functions. You can view the docs on the web or browse them in Xcode. For further information about the Content Delivery API, check out the Content Delivery API Reference Documentation.

Tutorials & other resources

  • This library is a wrapper around our Contentful Delivery REST API. Some more specific details such as search parameters and pagination are better explained on the REST API reference, and you can also get a better understanding of how the requests look under the hood.
  • Check the Contentful for Swift page for Tutorials, Demo Apps, and more information on other ways of using Swift with Contentful

Swift playground

If you'd like to try an interactive demo of the API via a Swift Playground, do the following:

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

Then build the "Contentful_macOS" scheme, open the playground file and go! Note: make sure the "Render Documentation" button is switched on in the Utilities menu on the right of Xcode, and also open up the console to see the outputs of the calls to print.

Example application

See the Swift iOS app on Github and follow the instructions on the README to get a copy of the space so you can see how changing content in Contentful affects the presentation of the app.


We gathered all information related to migrating from older versions of the library in our Migrations.md document.

Swift Versioning

It is recommended to use Swift 5.0, as older versions of the SDK will not have fixes backported. If you must use older Swift versions, see the compatible tags below.

Swift version | Compatible Contentful tag | | --- | --- | | 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 |

Reach out to us

Have questions about how to use this library?

  • Reach out to our community forum: Contentful Community Forum
  • Jump into our community slack channel: Contentful Community Slack

You found a bug or want to propose a feature?

  • File an issue here on GitHub: File an issue. Make sure to remove any credential from your code before sharing it.

You need to share confidential information or have other questions?

  • File a support ticket at our Contentful Customer Support: File support ticket

Get involved

PRs Welcome

We appreciate any help on our repositories. For more details about how to contribute see our Contributing.md document.


This repository is published under the MIT license.

Code of Conduct

We want to provide a safe, inclusive, welcoming, and harassment-free space and experience for all participants, regardless of gender identity and expression, sexual orientation, disability, physical appearance, socioeconomic status, body size, ethnicity, nationality, level of experience, age, religion (or lack thereof), or other identity markers.

Read our full Code of Conduct.


Stars: 109



5.1.2 - 2020-08-05 09:17:46

  • Properly parse nil value on decoded JSON data
  • Bump JSON from 2.2.0 to 2.3.1

5.1.1 - 2020-07-07 16:06:08


  • Send only SyncSpace parameters when accessing the next page of data to be synced

5.1.0 - 2020-06-10 07:52:52

  • Switched to using Swift.ResultType (Breaking Change)
  • Updated Venmo/DVR
  • Fixed race condition issues with link resolutions
  • Updated QueryTests to work with new Contentful response
  • Exposed a method that allows filtering content by link reference's id
  • Updated docs

- 2020-04-28 08:02:32

- 2020-03-23 13:01:03

- 2020-03-10 12:33:35

- 2020-02-20 10:57:29

5.0.6 - 2019-12-23 08:41:35

Release 5.0.6

5.0.5 - 2019-11-26 13:51:19

5.0.0 - 2019-06-19 11:09:09

4.2.4 - 2018-12-27 10:01:40


  • A bug in which one-to-many links could become out-of-order in #253 by @chrisozenne

4.2.3 - 2018-12-06 09:29:56


  • Check for protocol conformance when fetching an EntryDecodable by id that prevented links from being resolved.

4.2.2 - 2018-12-03 16:10:12


  • All reference documentation has been improved.

4.2.1 - 2018-11-22 17:13:19


  • All reference documentation has been improved.

4.2.0: Logging - 2018-11-13 14:01:07


  • A ContentfulLogger singleton which will log messages to the console. ContentfulLogger can be configured with a CustomLogger in order to use any third-party logging frameworks of your choice.

4.1.3 - 2018-11-08 14:07:53


  • 4.1.1, 4.1.2, and 4.1.3 are all hotfix releases that fixed small corruptions in the Xcode project configuration. 4.1.3 specifically sets the deployment version on the macOS target, even though the correct deployment version was set on the macOS framework target.

4.1.2 - 2018-11-07 16:15:23

The iOS deployment target was accidentally bumped when updating the SDK from version 4.0.0 to 4.1.0 and that caused an unexpected "breaking" change. This release reverts that mistake and also fixed a corrupted tvOS target (still a mystery how it was corrupted).

4.1.1 — Carthage only release - 2018-11-07 10:57:45

Release to fix issue when building projects that have spaces in the name: see #233


4.1.0 - 2018-11-06 10:16:06


  • The RichTextDocument type which can be used in EntryDecodable instances as a field type corresponding to rich text fields in Contentful.


  • Support for iOS 8.

4.0.1 - 2018-10-25 16:50:24

4.0.0 - 2018-10-24 13:08:48


  • BREAKING: Interstellar has been removed as a dependency of the SDK and the SDK now has its own Result type. If you were relying on fetch methods that returned an Observable, you will need to update your code.
  • BREAKING: The syntax for many of the fetch methods on Client have changed. Refer to the v4 migration guide.
  • BREAKING: EntryQueryable has been renamed FieldKeysQueryable, the required associated type Fields has been renamed FieldKeys to accurately reflect the type's real usage.
  • BREAKING: MixedMappedArrayResponse has been renamed MixedArrayResponse.


  • Base fetch methods for fetching data, or fetching data and deserializing any type conforming to Swift.Decodable have been exposed so that SDK usage is more flexible for various development strategies.
  • Endpoint enum and EndpointAccessible protocol for clarity on endpoints available through the APIs and which resource types are returned from said endpoints.
  • ResourceQueryable protocol, which Asset, Entry, ContentType conform to; it enables querying and filtering on the API for conforming types.
  • FlatResource protocol which can be used if you prefer to have all sys properties on the top level of your EntryDecodable. All Resource types have a default implementation of FlatResource so refactoring is opt-in.


  • The DataDelegate protocol has been removed in favor of directly fetching raw Data on your own. If you want to store JSON to disk, simply fetch it and do what you like.
  • The EntryModellable protocol is now gone. Just use EntryDecodable.

3.1.2 - 2018-08-24 09:01:02


A retain cycle due to the fact that the URLSession owned by Client was not invalidated on client deallocation. Thanks to @edwardmp for identifying the issue and submitting a fix in #226.

3.1.1 - 2018-08-21 08:28:08


  • A critical bug that caused the fetchLocales(then:) method to not pass the correct error back to it's completion handler. This bug would, for example, incorrectly pass back an SDKError if internet connection dropped rather than passing back the proper NSErrror from Foundation.

3.1.0 - 2018-08-10 14:15:43


  • Query and QueryOn methods for finding entries which reference another entry (by id) with a specific linking field.

3.0.0 - 2018-07-30 14:38:07

See the guide for migrating from 2.x to 3.x of contentful.swift


  • BREAKING: PNGs can now be retrieved with .standard or .eight bits as an additional ImageOption to request PNGs from the Images API.


  • Now all error responses from the API will fallback to seraializing an SDKError if the SDK is unable to serialize an APIError


  • BREAKING: Configuring a Client to interface with Content Preview API is no longer done through the ClientConfiguration type. Instead, pass host: Host.preview to the Client initializer. Also, you can now configure the client to use any arbitrary string host if you have whitelisted via your plan in Contentful.

2.2.1 - 2018-07-29 23:29:16


  • Accessing fields on assets was not respecting fallback chain logic when assets were requested with a multi-locale format. This is now fixed.

2.2.0 - 2018-06-13 11:57:19


  • An additional configuration option, timeZone on the ClientConfiguration to specify which TimeZone should be used when normalizing dates returned by the API. The default timezone is 0 seconds offset from GMT which enables serializing the exact representation the API returns rather than transforming to the current system time.

2.1.0 - 2018-05-03 14:41:31


  • Support for using the /sync endpoint on non-master environments.

2.0.0 - 2018-04-16 08:20:59


  • Typed queries prepending "fields" two times when using the select operator. Thanks to @cysp for submitting the fix in #169.
  • Assets that contained media files that were not images failed to deserialize the metadata about the file properly.
  • null values that were present for fields were being stored in dictionaries as a Bool with a value of true. Now these values are omitted from the dictionary. The handling of null values in JSON arrays has also been improved.
  • Date formats supported by the Contentful web app that were previously not being deserialized by the SDK's JSONDecoder


  • Support for the new Environments
  • Locales are now a property of Client and can be fetched on their own with the fetchLocales methods.
  • AssetProtocol to enable data fetches for other asset data types.


  • BREAKING: Upgrades project to Swift 4.1 and Xcode 9.3
  • BREAKING: The interface for synchronization has been simplified. initialSync and nextSync have been replaced with sync with a default argument of an empty sync space to start an initial sync operation.
  • BREAKING: The SDK provided methods for creating a new Swift.JSONDecoder and updating it with locale information of your space or environment has changed.
  • BREAKING: The LocalizationContext property of Space has been moved and is now a property of Client.
  • BREAKING: ResourceQueryable has been renamed EntryQueryable for correctness and consistency.

- 2018-04-11 09:50:31