Network Request With Swift Combine

The basics.

Creating the Publisher.

URLSession.shared.dataTaskPublisher(for: URL(string: URLPath)!) //1
.map { $0.data } //2
.decode(type: ModelObject.self, //3
decoder: JSONDecoder())
.mapError(mapError) //4
.eraseToAnyPublisher() //5
  1. Gives us a DataTaskPublisher object. It’s a publisher to go and get response from end point and publish a value.
  2. Extract the Data object from response.
  3. Decode Data to a model object of your choice, using JSONDecoder.
  4. Map any error to an appropriate error type of your choice.
  5. This function will provide a publisher with appropriate Output and Error type, for example the return type of this code is AnyPublisher<ModelObject, Error>. AnyPublisher is simply a wrapper object that conforms to the Publisher protocol. ModelObject is the type of object the Publisher publishes and Error is an Error type that was mapped.

Getting the response.

let publisher = networkService.publisher()                       //1     
.receive(on: DispatchQueue.main)
let subscriber = publisher.sink(receiveCompletion:{completion in //2
switch completion {
case .failure(let error):
print(error)
case .finished:
break
}
}) { [weak self] viewModel in
self
?.viewModel = viewModel
}
  1. Getting the publisher response on the main thread (not necessary).
  2. Calling sink(receiveCompletion:receiveValue:) on the publisher with completion and receive value block will give you a subscriber. The first closure executes when it receives Subscribers.Completion, which is an enumeration that indicates whether the publisher finished normally or failed with an error. The second closure executes when it receives an element from the publisher which in this case will be our view model.
let publisher = networkService.publisher()
.receive(on: DispatchQueue.main)
.replaceError(with: DefaultModel())
.eraseToAnyPublisher() //1
let subscriber = publisher.assign(to: \.viewModel, on: self) //2
  1. As you can see this approach is similar to the previous example with the exception of error handling. You can see that i am replacing all the errors with a DefaultModel object and transforming the publisher to type AnyPublisher<ModelObject, Never>. Reason being the assign(to:on:) function requires the Publisher’s Failure enum to be of type Never.
  2. Finally create a subscriber and assign the published view model object to the viewModel property in self.

A Software Engineer with a passion for technology. Working as an iOS Developer @BBC

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Melvin John

Melvin John

A Software Engineer with a passion for technology. Working as an iOS Developer @BBC

More from Medium

Build your first WatchOS App with Swift — Counter App

Introduction to Swift UI

Xcode-How to change the main Storyboard

RxSwift Combination Operators: zip, combineLatest & withLatestFrom