Building a SwiftUI app using MVVM architecture — Part 4: Implementing a network request with Combine

Jullian Mercier
2 min readSep 22, 2019

--

A view will often use an observable object to reflect the latest data fetched from a web-service.

Apple has introduced the Combine framework, a way to handle asynchronous events by combining event-processing operators.

If you’re not familiar with Combine, checkout my article here.

In Headlines, I needed to retrieve some data for each category and return a publisher containing the requested elements once all networks calls had completed.

Using the built-in `dataTaskPublisher` comes in handy to create these multiple asynchronous requests and merge them into a single publisher sequence.

The collect() operator allowed me to group all the elements from that sequence into a single array.

typealias HeadlinesResult = AnyPublisher<(HeadlinesSection, Result), Error>class Webservice {
func fetch(preferences: UserPreferences) -> AnyPublisher<[(HeadlinesSection, Result)], Never> {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let recency = preferences
.recencies
.filter { $0.isSelected }
.first?.date

let country = preferences
.countries
.filter { $0.isSelected }
.first?.country

let categories = preferences
.categories
.filter { $0.isSelected }

let publishers = categories.map { category -> HeadlinesResult in
let endpoint = Endpoint.search(
recency: recency ?? .today,
country: country ?? .france,
category: category.name.rawValue
)
let publisher = URLSession.shared.dataTaskPublisher(for: endpoint.url!)
.retry(2)
.map { $0.data }
.decode(type: Result.self, decoder: decoder)
.receive(on: RunLoop.main)
.map { (category.name, $0) }
.eraseToAnyPublisher()
return publisher
}
return Publishers.MergeMany(publishers)
.collect()
.replaceError(with: [])
.eraseToAnyPublisher()
}
}

Chaining operators on the `dataTaskPublisher` enable us to implement successive operations on the upstream publisher delivering the expected HeadlinesResult type.

Combine facilitates the handling of asynchronous calls using a declarative approach resulting in clarity and code legibility.

SwiftUI and Combine works well together as they provide both that very declarative approach.

Continue with Part 5: Connecting the models with the UI using MVVM.

--

--

Jullian Mercier
Jullian Mercier

Written by Jullian Mercier

Senior iOS engineer. jullianmercier.com. @jullian_mercier. Currently looking for new job opportunities.

No responses yet