Created
May 20, 2019 15:52
-
-
Save pofat/4a43ea9c75bfd50157be30796344bfa4 to your computer and use it in GitHub Desktop.
Protocol Oriented Request
This file contains hidden or 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 | |
| // 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