Last active
July 3, 2024 05:07
-
-
Save J0onYEong/fbdba77437c87ad7404a164855f967c0 to your computer and use it in GitHub Desktop.
Moya라이브러리 연습 코드
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
// | |
// Requesting.swift | |
// MoyaPractice | |
// | |
// Created by choijunios on 7/3/24. | |
// | |
import Foundation | |
import Moya | |
import RxMoya | |
import Alamofire | |
import RxSwift | |
enum APIType { | |
case users | |
case gists | |
} | |
protocol BaseAPI: TargetType { | |
var apiType: APIType { get } | |
} | |
extension BaseAPI { | |
var baseURL: URL { | |
let base = "https://api.github.com" | |
switch apiType { | |
case .users: | |
return URL(string: base + "/users")! | |
case .gists: | |
return URL(string: base + "/gists")! | |
} | |
} | |
var path: String { | |
switch apiType { | |
case .users: | |
"users" | |
case .gists: | |
"gists" | |
} | |
} | |
/// Default header | |
var headers: [String : String]? { | |
return ["Content-Type": "application/json"] | |
} | |
} | |
// MARK: Concrete | |
enum UserAPI { | |
case junyeong | |
case alice | |
} | |
extension UserAPI: BaseAPI { | |
var apiType: APIType { .users } | |
var path: String { | |
switch self { | |
case .junyeong: | |
return "junyeong" | |
case .alice: | |
return "alice" | |
} | |
} | |
var method: Moya.Method { | |
switch self { | |
case .junyeong: | |
return .get | |
case .alice: | |
return .get | |
} | |
} | |
/// body Data, Request Parameter등이 들어감 | |
/// 바디데이타와 쿼리 데이터를 하나의 타입으로 동시에 지정가능 | |
var task: Moya.Task { | |
.requestPlain | |
} | |
} | |
struct UserDTO: Decodable { | |
let login: String | |
enum CodingKeys: String, CodingKey { | |
case login | |
} | |
init(from decoder: any Decoder) throws { | |
let container = try decoder.container(keyedBy: CodingKeys.self) | |
self.login = try container.decode(String.self, forKey: .login) | |
} | |
} | |
// MARK: Service | |
class BaseService<TagetAPI: BaseAPI> { | |
lazy var provider = self.defaultProvider | |
private lazy var defaultProvider: MoyaProvider<TagetAPI> = { | |
let configuration = URLSessionConfiguration.default | |
configuration.timeoutIntervalForRequest = 10 | |
configuration.timeoutIntervalForResource = 10 | |
configuration.requestCachePolicy = .reloadIgnoringLocalCacheData | |
let session = Session(configuration: configuration) | |
let provider = MoyaProvider<TagetAPI>( | |
// endpointClosure: endpointClosure, | |
session: session | |
) | |
return provider | |
}() | |
private let endpointClosure = { (target: TagetAPI) -> Endpoint in | |
let url = target.baseURL.appendingPathComponent(target.path).absoluteString | |
var endpoint: Endpoint = Endpoint( | |
url: url, | |
sampleResponseClosure: {.networkResponse(200, target.sampleData)}, | |
method: target.method, | |
task: target.task, | |
httpHeaderFields: target.headers) | |
return endpoint | |
} | |
} | |
extension BaseService { | |
func requestDecodable<T: Decodable>(api: TagetAPI) -> Single<T> { | |
Single<T>.create { single in | |
let cancellable = self.provider.request(api) { result in | |
switch result { | |
case .success(let response): | |
do { | |
let decoded = try response.map(T.self) | |
single(.success(decoded)) | |
} catch { | |
single(.failure(error)) | |
} | |
case .failure(let error): | |
single(.failure(error)) | |
} | |
} | |
return Disposables.create { | |
cancellable.cancel() | |
} | |
} | |
} | |
func requestDecodableRx<T: Decodable>(api: TagetAPI) -> Single<T> { | |
self.provider.rx.request(api) | |
.map(T.self) | |
} | |
func requestRxProgress<T: Decodable>(api: TagetAPI) -> Single<T> { | |
Single<T>.create { single in | |
self.provider.rx | |
.requestWithProgress(api) | |
.subscribe(onNext: { response in | |
print("progress: \(response.progress)") | |
if let result = response.response { | |
do { | |
let decoded = try result.map(T.self) | |
single(.success(decoded)) | |
} catch { | |
single(.failure(error)) | |
} | |
} | |
}) | |
} | |
} | |
} | |
class UserService: BaseService<UserAPI> { | |
deinit { | |
print("UserService deinit") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment