Skip to content

Instantly share code, notes, and snippets.

@mackankowski
Last active September 6, 2021 17:09
Show Gist options
  • Save mackankowski/0d169f76c7f5060fc26f0738d1adba7f to your computer and use it in GitHub Desktop.
Save mackankowski/0d169f76c7f5060fc26f0738d1adba7f to your computer and use it in GitHub Desktop.
Network layer in Swift (using Combine)
import Combine
import UIKit
struct Agent {
struct Response<T> {
let value: T
let response: URLResponse
}
func run<T: Decodable>(_ url: URL, _ decoder: JSONDecoder = JSONDecoder()) -> AnyPublisher<Response<T>, Error> {
return URLSession.shared
.dataTaskPublisher(for: URLRequest(url: url))
.tryMap { result -> Response<T> in
let value = try decoder.decode(T.self, from: result.data)
return Response(value: value, response: result.response)
}
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
}
struct SampleData: Codable {
let userId: Int
let id: Int
let title: String
let completed: Bool
}
enum DownloadAPI {
static let agent = Agent()
}
extension DownloadAPI {
static func get() -> AnyPublisher<Agent.Response<SampleData>, Error> {
let url = URL(string: "https://jsonplaceholder.typicode.com/todos/1")
return agent.run(url!)
}
}
final class DownloadViewModel {
var cancellables = Set<AnyCancellable>()
init() {
DownloadAPI.get().sink(receiveCompletion: { response in
print(response)
}, receiveValue: { response in
print(response.value)
}).store(in: &cancellables)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment