Skip to content

Instantly share code, notes, and snippets.

@pofat
Created May 4, 2019 15:26
Show Gist options
  • Save pofat/f36b6a506a1c34125a6b2813be7520d0 to your computer and use it in GitHub Desktop.
Save pofat/f36b6a506a1c34125a6b2813be7520d0 to your computer and use it in GitHub Desktop.
Rx + Network Request
import Foundation
import RxSwift
enum HTTPMethod: String {
case POST, GET
}
// protocol of request, should define endpoint, http method, params and response type
protocol Request {
var path: String { get }
var method: HTTPMethod { get }
var param: [String: Any] { get }
associatedtype ResponseObject: Decodable
}
// The object to send request
// You should define base URL, base headers (such as credential)
protocol RequestSender {
var base: String { get }
func send<T: Request>(_ r: T) -> Observable<T.ResponseObject?>
}
// Any object who can deal with HTTP request
struct URLSessionDebugRequestSender: 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()
}
}
}
// A real request
struct GetUserRequest: Request {
let id: String
var path: String {
return "/users/\(id)"
}
var param: [String : Any]
let method: HTTPMethod = .GET
typealias ResponseObject = User
init(id: String, param: [String: Any] = [:]) {
self.id = id
self.param = param
}
}
// An object
struct User: Decodable {
let id: String
let name: String
let gender: String
}
// usage example
func example() {
let request = GetUserRequest(id: "a12345", param: ["foo": "bar"])
_ = URLSessionDebugRequestSender().send(request)
.subscribeOn(SerialDispatchQueueScheduler.init(qos: .background))
.observeOn(MainScheduler.instance).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