Skip to content

Instantly share code, notes, and snippets.

@pofat
Created May 20, 2019 15:52
Show Gist options
  • Save pofat/4a43ea9c75bfd50157be30796344bfa4 to your computer and use it in GitHub Desktop.
Save pofat/4a43ea9c75bfd50157be30796344bfa4 to your computer and use it in GitHub Desktop.
Protocol Oriented Request
import Foundation
import RxSwift
// Requests
enum HTTPMethod: String {
case POST, GET
}
// Define what a request is
protocol Request {
var path: String { get }
var method: HTTPMethod { get }
var param: [String: Any] { get }
associatedtype ResponseObject: Decodable
}
// Define what shoud have to send a request
protocol RequestSender {
var base: String { get }
func send<T: Request>(_ r: T) -> Observable<T.ResponseObject?>
}
// An object who can send out Request
struct URLSessionRequestSender: RequestSender {
var base = "http://www.dummy.api"
func send<T: Request>(_ r: T) -> Observable<T.ResponseObject?> {
let url = URL(string: base.appending(r.path))!
var request = URLRequest(url: url)
request.httpMethod = r.method.rawValue
if let body = try? JSONSerialization.data(withJSONObject: r.param, options: .prettyPrinted) {
request.httpBody = body
}
return Observable.create { subscriber in
let task = URLSession.shared.dataTask(with: request) { data, res, error in
if let data = data, let object = try? JSONDecoder().decode(T.ResponseObject.self, from: data) {
subscriber.onNext(object)
} else {
subscriber.onError(error!)
}
}
task.resume()
return Disposables.create()
}
}
}
// An object
struct User: Decodable {
let id: String
let name: String
let gender: String
}
// A real request
struct GetUserRequest: Request {
typealias ResponseObject = User
let id: String
var path: String {
return "/users/\(id)"
var param: [String : Any]
let method: HTTPMethod = .GET
init(id: String, param: [String: Any] = [:]) {
self.id = id
self.param = param
}
}
// usage example
func example() {
let request = GetUserRequest(id: "a12345", param: ["foo": "bar"])
_ = URLSessionRequestSender().send(request)
.subscribe(onNext: { user in
if let user = user {
print("user is : \(user.name)")
} else {
print("got nothing")
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment