Skip to content

Instantly share code, notes, and snippets.

@fxm90
Last active October 24, 2019 06:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fxm90/cd7a92049f68bc453a70c5f80d82feda to your computer and use it in GitHub Desktop.
Save fxm90/cd7a92049f68bc453a70c5f80d82feda to your computer and use it in GitHub Desktop.
Wrapper around `dataTask(with, completionHandler:)` that uses swifts result type in the completion handler.
//
// URLSession+Result.swift
// HttpRequestSample
//
// Created by Felix Mau on 08/16/19.
// Copyright © 2019 Felix Mau. All rights reserved.
//
import Foundation
extension URLSession {
// MARK: - Types
/// Custom error type, used to describe the missing data.
enum DataTaskError: Error {
/// The response object is missing.
case invalidResponse
/// The data object is missing.
case invalidData
}
/// Tuple combining the response object (e.g. HTTP headers) and
/// data of a successfully URLSession `dataTask`.
typealias DataTaskResponse = (URLResponse, Data)
/// Result type for a data task.
typealias DataTaskResult = Result<DataTaskResponse, Error>
// MARK: - Public methods
/// Wrapper around `dataTask(with:URL, completionHandler:...)` that uses swift's result type in the completion handler.
///
/// > Creates a task that retrieves the contents of the specified URL,
/// > then calls a handler upon completion.
///
/// - Parameters:
/// - url: The URL to be retrieved.
/// - completion: The completion handler to call when the request is completed.
///
/// - Returns: The new session data task.
///
/// - SeeAlso: [Apple documentation](https://developer.apple.com/documentation/foundation/urlsession/1410330-datatask)
func dataTask(with url: URL,
completion: @escaping (DataTaskResult) -> Void) -> URLSessionDataTask {
return dataTask(with: url) { [weak self] data, response, error in
self?.handleDataTaskCompleted(data: data,
response: response,
error: error,
completion: completion)
}
}
/// Wrapper around `dataTask(with:URLRequest, completionHandler:...)` that uses swift's result type in the completion handler.
///
/// > Creates a task that retrieves the contents of the specified URL,
/// > then calls a handler upon completion.
///
/// - Parameters:
/// - request: A URL request object that provides the URL, cache policy, request type, body data or body stream, and so on.
/// - completion: The completion handler to call when the load request is completed.
///
/// - Returns: The new session data task.
///
/// - SeeAlso: [Apple documentation](https://developer.apple.com/documentation/foundation/urlsession/1407613-datatask)
func dataTask(with request: URLRequest,
completion: @escaping (DataTaskResult) -> Void) -> URLSessionDataTask {
return dataTask(with: request) { [weak self] data, response, error in
self?.handleDataTaskCompleted(data: data,
response: response,
error: error,
completion: completion)
}
}
// MARK: - Private methods
private func handleDataTaskCompleted(data: Data?,
response: URLResponse?,
error: Error?,
completion: (DataTaskResult) -> Void) {
if let error = error {
completion(.failure(error))
return
}
guard let response = response else {
completion(.failure(DataTaskError.invalidResponse))
return
}
guard let data = data else {
completion(.failure(DataTaskError.invalidData))
return
}
completion(.success((response, data)))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment