Skip to content

Instantly share code, notes, and snippets.

@mecid
Last active June 19, 2023 16:35
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save mecid/bfb7201b6436b68ba9a29a933ad91e05 to your computer and use it in GitHub Desktop.
Save mecid/bfb7201b6436b68ba9a29a933ad91e05 to your computer and use it in GitHub Desktop.
Networking layer in Swift
import Foundation
import Combine
enum HTTPMethod: String {
case put = "PUT"
case post = "POST"
case get = "GET"
case delete = "DELETE"
case head = "HEAD"
}
protocol Request {
var scheme: String { get }
var method: HTTPMethod { get }
var path: String { get }
var host: String { get }
var queryItems: [URLQueryItem] { get }
var headers: [String: String] { get }
var body: Data? { get }
}
extension Request {
var scheme: String { return "https" }
var method: HTTPMethod { return .get }
var headers: [String: String] { return [:] }
var body: Data? { return nil }
}
extension Request {
func build() -> URLRequest {
var components = URLComponents()
components.scheme = scheme
components.host = host
components.path = path
components.queryItems = queryItems
guard let url = components.url else {
preconditionFailure("Invalid url components")
}
var request = URLRequest(url: url)
request.allHTTPHeaderFields = headers
request.httpMethod = method.rawValue
request.httpBody = body
return request
}
}
protocol RequestModifier {
func modifyRequest(_ request: URLRequest) -> URLRequest
}
struct DataLoader {
var session: URLSession
var modifiers: [RequestModifier]
func load(_ request: Request) -> AnyPublisher<Data, Error> {
let modifiedRequest = modifiers.reduce(request.build()) { $1.modifyRequest($0) }
return session
.dataTaskPublisher(for: modifiedRequest)
.map(\.data)
.mapError { $0 }
.eraseToAnyPublisher()
}
}
@mecid
Copy link
Author

mecid commented Nov 21, 2020

I've updated the networking code to use Combine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment