Created
May 4, 2019 15:26
-
-
Save pofat/f36b6a506a1c34125a6b2813be7520d0 to your computer and use it in GitHub Desktop.
Rx + Network Request
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 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