ios-nd-networking
ios-nd-networking copied to clipboard
Use Swift 5's Result type for completion handlers
When we call dataTask(with:)
, we receive a completion handler with three values: data
, response
, and error
. Similarly, the completion handlers we provide in our helper methods, return either the generic ResponseType
or an Error
- both optional so that if one has a value, the other one is nil
.
This works, but leads to excessive nil-checking at the call site. Because there's only two cases (success, in which we receive data, and failure, in which we receive an error), a common pattern is to use an enum with associated values as the single value passed back by the completion handler. This is called the Result
type, and was actually added to Swift 5 to make for cleaner completion handlers.
For example, if we use the Result
type in the taskForGETRequest
method, then the method signature would look like this.
class func taskForGETRequest<ResponseType: Decodable>(url: URL, responseType: ResponseType.Type, completion: @escaping (Result<ResponseType, Error>) -> Void) -> URLSessionDataTask { ... }
Now, the ResponseType
and Error
are not optional and can never be nil
. When we want to call the completion handler, because Result
is an enumwe either pass in an instance of the response type to the
successcase, or an error into the
failurecase. Wrapping all our completion handlers in a
Result` type eliminates the need for nil-checking, and keeps our code cleaner and easier to understand.
For more information on the Result
type, refer to the documentation and the Swift Evolution proposal.