Last active
June 19, 2023 16:35
-
-
Save mecid/bfb7201b6436b68ba9a29a933ad91e05 to your computer and use it in GitHub Desktop.
Networking layer in Swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | |
} | |
} |
@getbiks Hey, first of all create an enum or struct which conforms to Request protocol. Then you can use one of the extension methods of URLSession to make a request with that enum or struct ;)
Hi, If you could help me with an example using the code I hv presented in the first post. Thanks.
Hey dude, if you don't figure out how to use this class, follow an example.
enum CountryProvider {
case listCountries
}
extension CountryProvider: Request {
var path: String {
switch self {
case .listCountries:
return "value"
}
}
var host: String {
return "www.google.com"
}
var queryItems: [URLQueryItem] {
return [URLQueryItem(name: "", value: "")]
}
var method: HTTPMethod {
return .post
}
}
If i understood well this is how you should use it.
I suggest that you read this article, is more clarify than just a gist.
URLSessionProtocol
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
Hi, If you could help me with an example using the code I hv presented in the first post. Thanks.