Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moya Network 모듈 세팅 #11

Merged
merged 10 commits into from
Jul 20, 2023
Merged
12 changes: 12 additions & 0 deletions Config.xcconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// Config.xcconfig
// Keyme
//
// Created by Young Bin on 2023/07/18.
// Copyright © 2023 team.humanwave. All rights reserved.
//

// Configuration settings file format documentation can be found at:
// https://help.apple.com/xcode/#/dev745c5c974

API_BASE_URL = https:/$()/randomuser.me
2 changes: 1 addition & 1 deletion Targets/Keyme/Sources/KeymeApp.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import SwiftUI
import KeymeUI
import SwiftUI
import UserNotifications

import FirebaseCore
Expand Down
32 changes: 32 additions & 0 deletions Targets/KeymeKit/Sources/Network/API/APIRequestable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// APIRequestable.swift
// KeymeKit
//
// Created by 이영빈 on 2023/07/18.
// Copyright © 2023 team.humanwave. All rights reserved.
//

import Combine
import CombineMoya
import Moya
import Foundation

public protocol APIRequestable<APIType> {
associatedtype APIType: TargetType

/// Swift concurrency 맥락에서 네트워크 요청. 그런데 디코딩을 곁들인
///
/// - Parameters:
/// - object: `받아_볼_타입.self`
func request<T: Decodable>(_ api: APIType, object: T.Type) async throws -> T

/// Combine 맥락에서 네트워크 요청. 그런데 디코딩을 곁들인
///
/// - Parameters:
/// - object: `받아_볼_타입.self`
func request<T: Decodable>(_ api: APIType, object: T.Type) -> AnyPublisher<T, MoyaError>

/// 인증토큰 헤더에 넣어주는 메서드
@discardableResult
mutating func registerAuthorizationToken(_ token: String) -> Self
}
63 changes: 63 additions & 0 deletions Targets/KeymeKit/Sources/Network/API/KeymeAPI.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//
// KeymeAPI.swift
// Keyme
//
// Created by Young Bin on 2023/07/16.
// Copyright © 2023 team.humanwave. All rights reserved.
//

import Foundation
import Moya

public enum KeymeAPI {
case test
}

extension KeymeAPI: TargetType {
// TODO: 임시 - 서버 도메인 확정되면 변경할 것
public var baseURL: URL {
return URL(string: "https://randomuser.me")!
}

// TODO: 임시 - API 추가될 떄마다 변경
public var path: String {
switch self {
case .test:
return "/api"
}
}

public var method: Moya.Method {
switch self {
case .test:
return .get
}
}

public var task: Task {
switch self {
case .test:
return .requestPlain
}
}

public var headers: [String: String]? {
return ["Content-type": "application/json"]
}

public var sampleData: Data {
"""
{
"id": 1,
"name": "Test Item"
}
"""
.data(using: .utf8)!
}
}

// TODO: 나중에 어디로 옮기기
struct TestItem: Decodable {
let id: Int
let name: String
}
56 changes: 56 additions & 0 deletions Targets/KeymeKit/Sources/Network/API/KeymeAPIManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//
// NetworkManager.swift
// Keyme
//
// Created by Young Bin on 2023/07/16.
// Copyright © 2023 team.humanwave. All rights reserved.
//

import Combine
import CombineMoya
import Moya
import Foundation

public struct KeymeAPIManager {
public typealias APIType = KeymeAPI

private var core: CoreNetworkService<KeymeAPI>
private let decoder = JSONDecoder()

init(core: CoreNetworkService<KeymeAPI>) {
self.core = core
}

@discardableResult
public mutating func registerAuthorizationToken(_ token: String) -> Self {
core.registerAuthorizationToken(token)
return self
}
}

extension KeymeAPIManager: CoreNetworking {
public func request(_ api: KeymeAPI) async throws -> Response {
try await core.request(api)
}

public func request(_ api: KeymeAPI) -> AnyPublisher<Response, MoyaError> {
core.request(api)
}
}

extension KeymeAPIManager: APIRequestable {
public func request<T: Decodable>(_ api: KeymeAPI, object: T.Type) async throws -> T {
let response = try await core.request(api)
let decoded = try decoder.decode(T.self, from: response.data)

return decoded
}

public func request<T: Decodable>(_ api: KeymeAPI, object: T.Type) -> AnyPublisher<T, MoyaError> {
core.request(api).map(T.self)
}
}

public extension KeymeAPIManager {
static let shared = KeymeAPIManager(core: .init())
}
59 changes: 59 additions & 0 deletions Targets/KeymeKit/Sources/Network/Core/CoreNetworkService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// CoreNetworkService.swift
// Keyme
//
// Created by Young Bin on 2023/07/18.
// Copyright © 2023 team.humanwave. All rights reserved.
//

import Moya
import Combine
import Foundation

struct CoreNetworkService<APIType: TargetType> {
public private(set) var provider: MoyaProvider<APIType>

init(provider: MoyaProvider<APIType> = .init()) {
self.provider = provider
}
}

extension CoreNetworkService: CoreNetworking {
func request(_ api: APIType) async throws -> Response {
try await withCheckedThrowingContinuation { continuation in
provider.request(api) { result in
switch result {
case let .success(response):
continuation.resume(returning: response)
case let .failure(error):
continuation.resume(throwing: error)
}
}
}
}

func request(_ api: APIType) -> AnyPublisher<Response, MoyaError> {
provider.requestPublisher(api)
}

@discardableResult
mutating func registerAuthorizationToken(_ authorizationToken: String) -> Self {
let newProvider = MoyaProvider<APIType>(endpointClosure: endpointClosure(with: authorizationToken))
provider = newProvider

return CoreNetworkService(provider: newProvider)
}
}

private extension CoreNetworkService {
func endpointClosure(with token: String) -> MoyaProvider<APIType>.EndpointClosure {
return { (target: APIType) -> Endpoint in
let defaultEndpoint = MoyaProvider.defaultEndpointMapping(for: target)

switch target {
default:
return defaultEndpoint.adding(newHTTPHeaderFields: ["Authorization": token])
}
}
}
}
26 changes: 26 additions & 0 deletions Targets/KeymeKit/Sources/Network/Core/CoreNetworking.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// CoreNetworking.swift
// KeymeKit
//
// Created by 이영빈 on 2023/07/18.
// Copyright © 2023 team.humanwave. All rights reserved.
//

import Combine
import CombineMoya
import Moya
import Foundation

protocol CoreNetworking<APIType> {
associatedtype APIType: TargetType

/// Swift concurrency 맥락에서 네트워크 요청
func request(_ api: APIType) async throws -> Response

/// Combine 맥락에서 네트워크 요청
func request(_ api: APIType) -> AnyPublisher<Response, MoyaError>

/// 인증토큰 헤더에 넣어주는 메서드
@discardableResult
mutating func registerAuthorizationToken(_ authorizationToken: String) -> Self
}
Loading