Instruction 2
Protocol-Oriented Programming
Protocol-Oriented Programming is a design pattern that enables you to abstract implementation details across various components of your app. It’s commonly used to separate concerns in your code, such as decoupling UI logic from data logic.
For example, you might have a View to display a list of books. The view shouldn’t care about how the items are retrieved or whether it needs to make specific API calls or database queries to get the data. Instead, you can define a protocol:
protocol BookRepository {
func getBooks() async throws -> [Book]
func createBook(_ book: Book) async throws
}
This protocol outlines a few functions for retrieving and creating books Note how there are no implementation details; that’s decided by the implementer of the protocol. The view simply uses the protocol’s API to perform the actions it needs to.
This also makes it very easy to change the implementation; for example, you can easily switch between using SwiftData and an API or even some mocked data for testing.
You could then provide an implementation of this protocol that uses an API:
// 1
struct APIBookRepository: BookRepository {
// Define URLs...
// 2
func getBooks() async throws -> [Book] {
// 3
let (data, _) = try await URLSession.shared.data(from: booksURL)
return try JSONDecoder().decode([Book].self, from: data)
}
// 4
func createBook(_ book: Book) async throws {
// 5
let data = try JSONEncoder().encode(book)
// 6
var request = URLRequest(url: createBookURL)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = data
// 7
_ = try await URLSession.shared.data(for: request)
}
}
Here’s what the code does:
- Defines a new type that conforms to
BookRepositoryto retrieve books from an API. - Implements
getBooks()to retrieve books from the API. - Uses
URLSessionto retrieve the data from the API and decode the response to an array ofBooks. The function must return this information. - Implements
createBook(_:)to create a new book. - Encodes the book to JSON.
- Creates a
URLRequestto send to the API. Sets the method, header and body parameters for sending the new book data to the API. - Sends the request to the API using
URLSession.
Note: For most SwiftUI apps, the responsibility of retrieving data is usually handled by a
ViewModelrather than theViewdirectly. TheView’s sole responsibility is to display the data it receives. For more information, check out Advanced iOS App Architecture and other related Kodeco articles on the Model-View-ViewModel (MVVM) pattern.