Was this page helpful?

Using the Delivery API on iOS

This guide will show you how to get started using our Objective-C SDK to consume content.

Contentful's Content Delivery API (CDA) is a read-only API for retrieving content from Contentful. All content, both JSON and binary, is fetched from the server closest to a user's location by using our global CDN.

We publish SDKs for various languages to make developing applications easier.


This tutorial assumes that you understand the Contentful data model.


For every request, clients need to provide an API key, which is created per space and used to delimit applications and content classes.

You can create an access token using the Contentful web app or the Content Management API.

Setup the client

There are three different ways to integrate the SDK into your own apps, described in detail in the README. This guide will use CocoaPods, the dependency manager for Cocoa projects, which makes it easier to keep the SDK up-to-date:

target "Guide" do
  pod 'ContentfulDeliveryAPI'

You are free to use Git submodules or download a static framework if that suits your workflow better.

Configuring the API client

The class CDAClient manages all requests to the API. For most apps, you will have a single Space which contains all your data. In this case, we recommend you create a singleton category on top of CDAClient to make it simple to dispatch requests from any part of your app.

Initialize the client

You need an API key and a space ID to initialize a client. You can use the API key and space ID pre-filled below from our example space or replace them with your own values.

@implementation CDAClient (Guide)

  +(instancetype)sharedClient {
    static dispatch_once_t once;
    static CDAClient *sharedClient;
    dispatch_once(&once, ^ {
      sharedClient = [[self alloc] initWithSpaceKey:@"<space_id>" accessToken:@"<access_token>"];
    return sharedClient;


Accessing data

Now that the client is available everywhere, you can fetch entries:

[[CDAClient sharedClient] fetchEntriesMatching:@{ @"content_type": @"3hEsRfcKgMGSaiocGQaqCo" }
  success:^(CDAResponse *response, CDAArray *array) {
     self.places = array.items;
  } failure:nil];

The CDA supports a variety of parameters to search, filter and sort your content. The SDK passes these parameters as a dictionary, which in this case will retrieve entries of a certain content type. You can learn more about search parameters in this guide.

A CDAArray contains a list of CDAResource objects whose concrete type depends on the query. In this case, the items property will contain a list of CDAEntry objects.

Each CDAEntry has a fields property, containing the values for fields defined in the content model. To decouple your app from Contentful, you can register custom subclasses for content types, like this:

[sharedClient registerClass:[BBUPlace class] forContentTypeWithIdentifier:@"3hEsRfcKgMGSaiocGQaqCo"];

The BBUPlace class defines properties, so that you can deal with entries like with any other value object:

-(NSString *)name {
  return self.fields[@"name"];

In the guide app, the class also implements the MKAnnotation protocol, which enables directly showing Entries in a map view.

Simple views for your data

The initial view of the guide app is a list of all cafes it knows about. For common tasks like this, the SDK adds UI components which you can customize to your needs. In this case, you will create a subclass of CDAEntriesViewController, a UITableViewController optimized for showing a list of Entries matching a certain query.

You create the basic setup in your subclass's init method:

-(id)init {
  self = [super initWithCellMapping:@{ @"textLabel.text": @"fields.name",
                                       @"detailTextLabel.text": @"fields.type" }];
  if (self) {
    self.client = [CDAClient sharedClient];
    self.query = @{ @"content_type": @"3hEsRfcKgMGSaiocGQaqCo" };
  return self;

The cell mapping is a dictionary for specifying which property of the UITableViewCell corresponds to properties in the content model. In addition to that, the shared client is specified as the client to use and the entries are limited to a certain content type. Setting the query property is optional, in that case all entries will be shown.

\*CDAEntriesViewController\* in action

If you want to show resources in a UICollectionView, there is CDAResourcesCollectionViewController, which works in a similar way to the Entries view controller:

self = [super initWithCollectionViewLayout:layout cellMapping:@{ @"imageURL": @"URL" }];
if (self) {
    self.client = [CDAClient sharedClient];
    self.resourceType = CDAResourceTypeAsset;

You need to specify a layout and cell mapping, as with a normal UICollectionViewController. For convenience, there is a ready made collection view cell class which fetches images from the URL in its imageURL property, which this example will use. The resourceType property defines which resource type is fetched, in this case 'Assets'. A CDAAsset has a direct accessor for the URL, used in the field mapping. Like the previous example, you need to specifiy the client.

\*CDAResourcesCollectionViewController\* in action

Presenting data your own way

It's possible and often necessary to write normal UIViewController subclasses and fetch content from Contentful. The BBULocationViewController class in the guide app does this, utilizing the BBUPlace class mentioned earlier in the tutorial. This way, it does not have specific knowledge about the Contentful SDK.

Links might not be resolved, depending on your query. If this is the case, use the resolveWithSuccess:failure: method on any CDAResource inside your custom class. Look at the fetchPictureAssetsWithCompletionBlock: method from BBUPlace for an example. You can add the include parameter to your query to adjust how many levels of links are automatically included as part of the API response. This helps to keep the number of API requests your app has to make low and therefore improves performance. You learn more about includes in this guide.

Fields can include Markdown. This example app which shows how to use the Bypass library to converting Markdown into a NSAttributedString which you can display in a UITextView. Depending on your use case and target platform, you might want to evaluate other options, for example converting to HTML. Keep in mind that the library does not support the whole range of GitHub flavoured Markdown syntax available in the Contentful entry editor.

Next steps

Not what you’re looking for? Try our FAQ.