At iOS App Templates, we are building fully coded mobile app templates in Swift, to help startups create their mobile products faster. Part of our mission is to provide highly modularized source code so that developers can easily customize and adapt our code to fit their needs. We are starting a tutorial series on iOS Design Patterns in Swift. In this article, we are going to talk about the adapter pattern, which we widely use in our Xcode projects.

adapter pattern swift

In 1994 authors Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides published a book titled Design Patterns. More than 20 years ago, the Big Four published some generic, reusable solutions for programming problems that we are still using today, regardless of the programming language we code in. In this Swift tutorial series, we are going to describe and present usage examples of the most common iOS design patterns in Swift: Adapter, Facade, Observer, Memento, Factory, and Singleton.

The Adapter Pattern

In software engineering, the adapter pattern is a software design pattern (also known as a wrapper, an alternative naming shared with the decorator pattern) that allows the interface of an existing class to be used as a different interface. It is often used to make existing classes work with each other, without modifying their source code. Check out Wikipedia for more information on the technical definition of the adapter pattern.

The adapter pattern allows two objects to understand each other’s APIs and exchange messages between themselves. Implementing Cocoa DataSource protocol into ViewController is the simplest example of using the adapter pattern. The specialized object that implements the data source protocol is an adapter for UITableView/UICollectionView. Similarly, for implementing the UITableViewDelegate, our view controller (in most cases) is adapting pieces of information about interactions between the user and UI part of the table view.

In our Swift projects, we create a specialized adapter for each model – cell pair. In this way, we can fetch any model from any data source (disk, network, mock data, etc) and we can display it in any UI cell. This is a great way to completely separate the UI from the layers in charge of providing the data. We just need to create an adapter to adopt a model to a cell.

Adapter Pattern Swift Example

We are going to describe a short example of a Swift implementation of the adapter pattern. Let’s assume that we would like to build an app to manage tasks from our tasks manager tool. We got an API structure that looks like this:

struct APITask: Decodable {
    let id: String
    let createdAt: TimeInterval
    let createdBy: String
    let developedBy: String
    let finishedAt: TimeInterval?
}

But inside the app, we would like to not rely on the API models, so we need to adopt this object using some protocol (or wrapper). We want to decouple the model layer from view model layer.

protocol Task {
    var id: String { get }
    var createdAtDate: Date { get }
    var author: String { get }
    var finishedAtDate: Date? { get }
}

And last, but not least we need to adapt APITask to conform to Task protocol:

extension APITask: Task {
    var author: String { return createdBy }
    var createdAtDate: Date { return Date(timeIntervalSince1970: createdAt) }
    var finishedAtDate: Date? { return finishedAt.map { Date(timeIntervalSince1970: $0) } }
}

In this example, the APITask extension adapts the APITask concrete object to the generic Task protocol. Now, any class that deals with a generic object conforming to Task (for instance, a view), can deal with an APITask as well, without even realizing it does so. The main benefit here is that we completely decoupled that class (e.g. a view controller) from the model layer (APITask).

The adapter pattern can be implemented in different flavors, so it can definitely be applied via concrete objects as well, rather than protocols. We’ll leave that as an exercise to the reader.

We hope you find the adapter pattern in Swift useful. Apple is using it extensively in Cocoa and once you get familiar with it, it will help you come with a more robust architecture approach in iOS app development. Don’t forget to spread the world by sharing this tutorial. Happy coding!

Categories: iOS Development

Leave a Reply

Your email address will not be published. Required fields are marked *