A delightful Swift interface to Contentful's content delivery API.
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.
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.
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.
platform :ios, '9.0' use_frameworks! 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'
You can also use Carthage for integration by adding the following to your
Cartfile:
github "contentful/contentful.swift" ~> 5.0.0
Add the following line to your array of dependencies:
.package(url: "https://github.com/contentful/contentful.swift", .upToNextMajor(from: "5.0.0"))
The following code snippet is the most basic one you can use to fetch content from Contentful with this SDK:
import Contentfullet client = Client(spaceId: "cfexampleapi", environmentId: "master", // Defaults to "master" if omitted. accessToken: "b4c0n73n7fu1")
client.fetch(Entry.self, id: "nyancat") { (result: Result) in switch result { case .success(let entry): print(entry) case .error(let error): print("Error (error)!") } }
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:
EntryDecodable
The
EntryDecodableprotocol 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.where(field: .color, .equals("gray"))client.fetchArray(of: Cat.self, matching: query) { (result: Result>) in guard let cats = result.value?.items else { return } print(cats) }
The asynchronously returned result will be an instance of
ArrayResponsein which the generic type parameter is the same type you've passed into the
fetchmethod. If you are using a
Querythat does not restrict the response to contain entries of one content type, you will use methods that return
MixedArrayResponseinstead of
ArrayResponse. The
EntryDecodableprotocol extends the
Decodableprotocol 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,
Catis a type of our own definition conforming to
EntryDecodableand
FieldKeysQueryable. In order for the SDK to properly create your model types when receiving JSON, you must pass in these types to your
Clientinstance:
let contentTypeClasses: [EntryDecodable.Type] = [ Cat.self Dog.self, Human.self ]let client = Client(spaceId: spaceId, accessToken: deliveryAPIAccessToken, contentTypeClasses: contentTypeClasses)
The source for the
Catmodel class is below; note the helper methods the SDK adds to Swift 4's
Decodertype to simplify for parsing JSON returned by Contentful. You also need to pass in these types to your
Clientinstance in order to use the fetch methods which take
EntryDecodabletype 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
Resourceand add
let sys: Sysproperty to the class and assign via
sys = try decoder.sys()during initialization. Then,
id,
localeCode,
updatedAt, and
createdAtare all provided via the
sysproperty 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
classinstance, not a
struct—this is because the SDK ensures that the in-memory object graph is complete, but also that it has no duplicates.
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.
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
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.
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|
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.
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.