diff --git a/14th-team5-iOS/Core/Sources/Bibbi/BBNetwork/BBAPISpec.swift b/14th-team5-iOS/Core/Sources/Bibbi/BBNetwork/BBAPISpec.swift index 7c4c67c8b..44d3056f0 100644 --- a/14th-team5-iOS/Core/Sources/Bibbi/BBNetwork/BBAPISpec.swift +++ b/14th-team5-iOS/Core/Sources/Bibbi/BBNetwork/BBAPISpec.swift @@ -110,7 +110,7 @@ extension APISpecable { guard let queryParameters = try? queryParametersEncodable?.toDictionary() - ?? self.queryParameters?.toDictionary() ?? [:] + ?? self.queryParameters?.toDictionary() ?? [:] else { throw URLGenerationError.invalidUrl } queryParameters.forEach { urlQueryItems.append(URLQueryItem(name: $0.key, value: "\($0.value)")) diff --git a/14th-team5-iOS/Core/Sources/Bibbi/BBNetwork/Network/BBNetworkHeader.swift b/14th-team5-iOS/Core/Sources/Bibbi/BBNetwork/Network/BBNetworkHeader.swift index c3595da60..7ddca5b4e 100644 --- a/14th-team5-iOS/Core/Sources/Bibbi/BBNetwork/Network/BBNetworkHeader.swift +++ b/14th-team5-iOS/Core/Sources/Bibbi/BBNetwork/Network/BBNetworkHeader.swift @@ -78,19 +78,16 @@ public extension BBNetworkHeader { private extension BBNetworkHeader { func fetchXAppKey() -> String { - // TODO: - Bundle에서 Key를 가져오도록 코드 수정하기 + // TODO: - Bundle에서 가져오도록 코드 수정하기 return "7c5aaa36-570e-491f-b18a-26a1a0b72959" } func fetchXAuthTokenValue() -> String { let keychain = KeychainWrapper.standard - guard - let string = keychain.string(forKey: .accessToken), - let encodedData = string.data(using: .utf8), - let accessToken = encodedData.decode(AccessToken.self) - else { return "" /* 예외 코드 작성 */ } - - return accessToken.accessToken ?? "" /* 예외 코드 작성 */ + if let authToken: AuthToken = keychain[.accessToken] { + return authToken.refreshToken + } + return "" // TODO: - 예외 코드 작성하기 } func fetchXUserPlatform() -> String { @@ -100,11 +97,10 @@ private extension BBNetworkHeader { func fetchXuserId() -> String { let userDefaults = UserDefaultsWrapper.standard - guard - let memberId = userDefaults.string(forKey: .memberId) - else { return "" /* 예외 코드 작성 */ } - - return memberId /* 예외 코드 작성 */ + if let memberId: String = userDefaults[.memberId] { + return memberId + } + return "" // TODO: - 예외 코드 작성하기 } func fetchContentType() -> String { diff --git a/14th-team5-iOS/Core/Sources/Bibbi/BBNetwork/Network/BBNetworkInterceptor.swift b/14th-team5-iOS/Core/Sources/Bibbi/BBNetwork/Network/BBNetworkInterceptor.swift index 0ad878a7d..df7cda5df 100644 --- a/14th-team5-iOS/Core/Sources/Bibbi/BBNetwork/Network/BBNetworkInterceptor.swift +++ b/14th-team5-iOS/Core/Sources/Bibbi/BBNetwork/Network/BBNetworkInterceptor.swift @@ -16,9 +16,10 @@ final class BBNetworkInterceptor: Interceptor { // MARK: - Properties - private let keychain = KeychainWrapper.standard private let network = BBNoInterceptorNetworkSession() + private let keychain = KeychainWrapper.standard + // MARK: - Retry public override func retry( @@ -32,12 +33,12 @@ final class BBNetworkInterceptor: Interceptor { return } - guard let refreshToken = fetchRefreshToken(), let authToken = refreshAuthToken(refreshToken) else { + guard let authToken = fetchAuthToken(), let newAuthToken = refreshAuthToken(authToken) else { completion(.doNotRetryWithError(error)) return } - saveAuthToken(authToken) + saveAuthToken(newAuthToken) completion(.retry) } @@ -59,26 +60,23 @@ final class BBNetworkInterceptor: Interceptor { private extension BBNetworkInterceptor { /// 키체인에 토큰 정보를 저장합니다. - func saveAuthToken(_ token: AccessToken) { - if let encodedString = token.encodeToString() { - keychain[.accessToken] = encodedString - } + @discardableResult + func saveAuthToken(_ token: AuthToken) -> Bool { + KeychainWrapper.standard.set(token, forKey: "accessToken") } /// 키체인으로부터 토큰 정보를 불러옵니다. - func fetchRefreshToken() -> String? { - guard let tokenString = keychain.string(forKey: .accessToken), - let encodedData = tokenString.encodeToData(), - let refreshToken = encodedData.decode(AccessToken.self)?.refreshToken else { - return nil + func fetchAuthToken() -> AuthToken? { + if let authToken: AuthToken = KeychainWrapper.standard.object(forKey: .accessToken) { + return authToken } - return refreshToken + return nil } /// 토큰을 리프레시합니다. - func refreshAuthToken(_ refreshToken: String) -> AccessToken? { + func refreshAuthToken(_ refreshToken: AuthToken) -> AuthToken? { let spec = BBAPISpec( - method: .get, + method: .post, path: "/auth/refresh", bodyParameters: ["refreshToken": "\(refreshToken)"], headers: .unAuthorized @@ -88,18 +86,20 @@ private extension BBNetworkInterceptor { return nil } - var tokenResult: AccessToken? = nil - let semaphore = DispatchSemaphore(value: 0) - - network.session.request(urlRequest).validate().responseData { response in - if let data = response.data, let accessToken = data.decode(AccessToken.self) { - tokenResult = accessToken + var tokenResult: AuthToken? = nil + network.session.request(urlRequest).validate().response { response in + switch response.result { + case let .success(data): + if let accessToken = data?.decode(AuthToken.self) { + tokenResult = accessToken + } + case let .failure(error): + // MARK: - Logger로 로그 출력하기 + debugPrint("🔴리프레시 실패: \(String(describing: error.errorDescription))") } -// semaphore.signal() } - -// semaphore.wait() - + return tokenResult } } + diff --git a/14th-team5-iOS/Core/Sources/Bibbi/BBStorages/KeychainWrapper/KeychainWrapper.swift b/14th-team5-iOS/Core/Sources/Bibbi/BBStorages/KeychainWrapper/KeychainWrapper.swift index c76c65355..e9477540e 100644 --- a/14th-team5-iOS/Core/Sources/Bibbi/BBStorages/KeychainWrapper/KeychainWrapper.swift +++ b/14th-team5-iOS/Core/Sources/Bibbi/BBStorages/KeychainWrapper/KeychainWrapper.swift @@ -10,6 +10,7 @@ import Foundation final public class KeychainWrapper { // MARK: - Properties + public static let standard = KeychainWrapper() private let SecMatchLimit: String! = kSecMatchLimit as String @@ -30,7 +31,9 @@ final public class KeychainWrapper { return Bundle.main.bundleIdentifier ?? "KeychainWrapper" }() + // MARK: - Intializer + public init( serviceName: String, accessGroup: String? = nil @@ -131,7 +134,7 @@ final public class KeychainWrapper { forKey key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil, isSynchronizable: Bool = false - ) -> NSCoding? { + ) -> (any NSCoding)? { guard let keychainData = data( forKey: key, withAccessibility: accessibility, @@ -143,6 +146,22 @@ final public class KeychainWrapper { return try? NSKeyedUnarchiver.unarchivedObject(ofClass: NSNumber.self, from: keychainData) } + public func object( + forKey key: String, + withAccessibility accessibility: KeychainItemAccessibility? = nil, + isSynchronizable: Bool = false + ) -> T? where T: Decodable { + guard let keychainData = data( + forKey: key, + withAccessibility: accessibility, + isSynchronizable: isSynchronizable + ) else { + return nil + } + + return try? JSONDecoder().decode(T.self, from: keychainData) + } + public func data( forKey key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil, @@ -251,7 +270,7 @@ final public class KeychainWrapper { @discardableResult public func set( - _ value: NSCoding, + _ value: any NSCoding, forKey key: String, withAccessibility accessibiilty: KeychainItemAccessibility? = nil, isSynchronizable: Bool = false @@ -271,6 +290,25 @@ final public class KeychainWrapper { } } + @discardableResult + public func set( + _ value: any Encodable, + forKey key: String, + withAccessibility accessibiilty: KeychainItemAccessibility? = nil, + isSynchronizable: Bool = false + ) -> Bool { + if let data = try? JSONEncoder().encode(value) { + return set( + data, + forKey: key, + withAccessibility: accessibiilty, + isSynchronizable: isSynchronizable + ) + } else { + return false + } + } + @discardableResult public func set( _ value: Data, @@ -384,7 +422,8 @@ final public class KeychainWrapper { } - // MARK: - KeychainQueryDictionary + // MARK: - Keychain Query Dictionary + private func setupKeychainQueryDictionary( forkey key: String, withAccessibility accessibility: KeychainItemAccessibility? = nil, diff --git a/14th-team5-iOS/Core/Sources/Bibbi/BBStorages/KeychainWrapper/KeychainWrapperSubscript.swift b/14th-team5-iOS/Core/Sources/Bibbi/BBStorages/KeychainWrapper/KeychainWrapperSubscript.swift index c63af1c1b..d41ceb7bf 100644 --- a/14th-team5-iOS/Core/Sources/Bibbi/BBStorages/KeychainWrapper/KeychainWrapperSubscript.swift +++ b/14th-team5-iOS/Core/Sources/Bibbi/BBStorages/KeychainWrapper/KeychainWrapperSubscript.swift @@ -49,7 +49,15 @@ public extension KeychainWrapper { } } - subscript(key: Key) -> NSCoding? { + subscript(key: Key) -> (any NSCoding)? { + get { object(forKey: key) } + set { + guard let value = newValue else { return } + set(value, forKey: key.rawValue) + } + } + + subscript(key: Key) -> T? where T: Codable { get { object(forKey: key) } set { guard let value = newValue else { return } @@ -89,7 +97,11 @@ public extension KeychainWrapper { string(forKey: key.rawValue) } - func object(forKey key: Key) -> NSCoding? { + func object(forKey key: Key) -> (any NSCoding)? { + object(forKey: key.rawValue) + } + + func object(forKey key: Key) -> T? where T: Decodable { object(forKey: key.rawValue) } diff --git a/14th-team5-iOS/Core/Sources/Bibbi/BBStorages/UserDefaultsWrapper/Models/AuthToken.swift b/14th-team5-iOS/Core/Sources/Bibbi/BBStorages/UserDefaultsWrapper/Models/AuthToken.swift new file mode 100644 index 000000000..4196385ae --- /dev/null +++ b/14th-team5-iOS/Core/Sources/Bibbi/BBStorages/UserDefaultsWrapper/Models/AuthToken.swift @@ -0,0 +1,24 @@ +// +// AuthToken.swift +// Core +// +// Created by 김건우 on 10/3/24. +// + +import Foundation + +public struct AuthToken: Codable { + + public let accessToken: String + public let refreshToken: String + public let isTemporaryToken: Bool + + public init(accessToken: String, refreshToken: String, isTemporaryToken: Bool) { + self.accessToken = accessToken + self.refreshToken = refreshToken + self.isTemporaryToken = isTemporaryToken + } + +} + +extension AuthToken: Equatable { } diff --git a/14th-team5-iOS/Core/Sources/Bibbi/BBStorages/UserDefaultsWrapper/UserDefaultsWrapper.swift b/14th-team5-iOS/Core/Sources/Bibbi/BBStorages/UserDefaultsWrapper/UserDefaultsWrapper.swift index fffd9640b..30a91d43d 100644 --- a/14th-team5-iOS/Core/Sources/Bibbi/BBStorages/UserDefaultsWrapper/UserDefaultsWrapper.swift +++ b/14th-team5-iOS/Core/Sources/Bibbi/BBStorages/UserDefaultsWrapper/UserDefaultsWrapper.swift @@ -10,6 +10,7 @@ import Foundation final public class UserDefaultsWrapper { // MARK: - Properties + public static let standard = UserDefaultsWrapper() private let userDefaults: UserDefaults! @@ -20,7 +21,9 @@ final public class UserDefaultsWrapper { "UserDefaultsWrapper" }() + // MARK: - Intializer + convenience init() { self.init(suitName: UserDefaultsWrapper.defaultSuitName) } @@ -166,4 +169,25 @@ final public class UserDefaultsWrapper { userDefaults.removePersistentDomain(forName: suitName) } + + // MARK: - Register + + /// 해당 키에 값이 비어있다면 넣을 기본 값을 등록합니다. + /// + /// 앱 델리게이트의 `application(_ application:didFinishLaunchingWithOptions:)` 메서드에서 등록해야 합니다. + /// - Parameter values: [UserDefaultsWrapper.Key: Any] + public func register(_ values: [Key: Any]) { + var newValues = [String: Any]() + values.forEach { newValues.updateValue($0.value, forKey: $0.key.rawValue) } + register(newValues) + } + + /// 해당 키에 값이 비어있다면 넣을 기본 값을 등록합니다. + /// + /// 앱 델리게이트의 `application(_ application:didFinishLaunchingWithOptions:)` 메서드에서 등록해야 합니다. + /// - Parameter values: [String: Any] + public func register(_ values: [String: Any]) { + userDefaults.register(defaults: values) + } + } diff --git a/14th-team5-iOS/Core/Sources/Extensions/Dictionary+Ext.swift b/14th-team5-iOS/Core/Sources/Extensions/Dictionary+Ext.swift index 66ca96612..0e36e4d55 100644 --- a/14th-team5-iOS/Core/Sources/Extensions/Dictionary+Ext.swift +++ b/14th-team5-iOS/Core/Sources/Extensions/Dictionary+Ext.swift @@ -7,15 +7,16 @@ import Foundation -public extension Dictionary where Key: RawRepresentable, Value: RawRepresentable { +public extension Dictionary where Key == BBNetworkParameterKey, Value == BBNetworkParameterValue { /// RawReprsentable 프로토콜을 준수하는 Key와 Value를 가진 딕셔너리를 [String: Any]로 변환합니다. /// - Returns: [String: Any] + /// /// - Authors: 김소월 func toDictionary() -> [String: Any] { var dict = [String: Any]() self.forEach { key, value in - dict.updateValue(value.rawValue as Any, forKey: "\(key)") + dict.updateValue(value.rawValue as Any, forKey: "\(key.rawValue)") } return dict } diff --git a/14th-team5-iOS/Core/Sources/Extensions/Encodable+Ext.swift b/14th-team5-iOS/Core/Sources/Extensions/Encodable+Ext.swift index f625740c1..2cb941a10 100644 --- a/14th-team5-iOS/Core/Sources/Extensions/Encodable+Ext.swift +++ b/14th-team5-iOS/Core/Sources/Extensions/Encodable+Ext.swift @@ -14,33 +14,36 @@ public extension Encodable { /// - Returns: Data? /// /// - Authors: 김소월 - func encodeToData(using encoder: JSONEncoder = JSONEncoder()) -> Data? { - guard - let data = try? encoder.encode(self) - else { return nil } - return data + func toData(using encoder: JSONEncoder = JSONEncoder()) -> Data? { + var res: Data? = nil + do { + res = try encoder.encode(self) + } catch { + // MARK: - Logger로 로그 출력하기 + debugPrint("\(Self.self) Data Parsing Error: \(error)") + } + return res } /// 인코딩이 가능한 객체를 String으로 변환합니다. /// - Parameter encoder: JSONEncoder 객체 /// - Returns: String? - func encodeToString( + /// + /// - Authors: 김소월 + func toString( using encoder: JSONEncoder = JSONEncoder(), encoding: String.Encoding = .utf8 ) -> String? { - guard - let data = self.encodeToData(using: encoder) - else { return nil } - - return String(data: data, encoding: encoding) + guard let data = self.toData() else { return nil } + return String(data: data, encoding: .utf8) } /// 인코딩이 가능한 객체를 딕셔너리로 변환합니다. /// - Returns: [String: Any]? /// /// - Authors: 김소월 - func toDictionary() throws -> [String: Any]? { - let data = try JSONEncoder().encode(self) + func toDictionary(using encoder: JSONEncoder = JSONEncoder()) throws -> [String: Any]? { + let data = try encoder.encode(self) let jsonData = try JSONSerialization.jsonObject(with: data) return jsonData as? [String: Any] } diff --git a/14th-team5-iOS/Core/Sources/Trash/BBRx/Repositories/Token/TokenRepository.swift b/14th-team5-iOS/Core/Sources/Trash/BBRx/Repositories/Token/TokenRepository.swift index dcb86bd9f..01c6b7657 100644 --- a/14th-team5-iOS/Core/Sources/Trash/BBRx/Repositories/Token/TokenRepository.swift +++ b/14th-team5-iOS/Core/Sources/Trash/BBRx/Repositories/Token/TokenRepository.swift @@ -10,7 +10,7 @@ import Foundation import RxCocoa import RxSwift -// 이게 왜 여기 있는데!!!!!!! +@available(*, deprecated, renamed: "AuthToken") public struct AccessToken: Codable, Equatable { public var accessToken: String? public var refreshToken: String? diff --git a/14th-team5-iOS/Data/Sources/APIs/Comment/CommentAPI/CommentAPIs.swift b/14th-team5-iOS/Data/Sources/APIs/Comment/CommentAPI/CommentAPIs.swift index 6368a13c4..99a8a70d0 100644 --- a/14th-team5-iOS/Data/Sources/APIs/Comment/CommentAPI/CommentAPIs.swift +++ b/14th-team5-iOS/Data/Sources/APIs/Comment/CommentAPI/CommentAPIs.swift @@ -31,7 +31,7 @@ enum CommentAPIs: BBAPI { return BBAPISpec( method: .post, path: "/posts/\(postId)/comments", - bodyParametersEncodable: body + bodyParameters: ["content": "\(body.content)"] ) case let .updatePostComment(postId, commentId): diff --git a/14th-team5-iOS/Data/Sources/APIs/OAuth/OAuthAPI/Repository/OAuthRepository.swift b/14th-team5-iOS/Data/Sources/APIs/OAuth/OAuthAPI/Repository/OAuthRepository.swift index ed2a1ab6e..98a960184 100644 --- a/14th-team5-iOS/Data/Sources/APIs/OAuth/OAuthAPI/Repository/OAuthRepository.swift +++ b/14th-team5-iOS/Data/Sources/APIs/OAuth/OAuthAPI/Repository/OAuthRepository.swift @@ -39,12 +39,12 @@ extension OAuthRepository { guard let keychain = self?.tokenKeychainStorage else { return } - let accessToken = OldAccessToken( + let accessToken = AccessToken( accessToken: $0?.accessToken, refreshToken: $0?.refreshToken, isTemporaryToken: $0?.isTemporaryToken ) - keychain.saveOldAccessToken(accessToken) + keychain.saveAccessToken(accessToken) }) .asObservable() } @@ -65,12 +65,12 @@ extension OAuthRepository { guard let keychain = self?.tokenKeychainStorage else { return } - let accessToken = OldAccessToken( + let accessToken = AccessToken( accessToken: $0?.accessToken, refreshToken: $0?.refreshToken, isTemporaryToken: $0?.isTemporaryToken ) - keychain.saveOldAccessToken(accessToken) + keychain.saveAccessToken(accessToken) }) .asObservable() } @@ -89,12 +89,12 @@ extension OAuthRepository { guard let keychain = self?.tokenKeychainStorage else { return } - let accessToken = OldAccessToken( + let accessToken = AccessToken( accessToken: $0?.accessToken, refreshToken: $0?.refreshToken, isTemporaryToken: $0?.isTemporaryToken ) - keychain.saveOldAccessToken(accessToken) + keychain.saveAccessToken(accessToken) }) .asObservable() } diff --git a/14th-team5-iOS/Data/Sources/Storages/Keychain/TokenKeychain/Models/OldAccessToken.swift b/14th-team5-iOS/Data/Sources/Storages/Keychain/TokenKeychain/Models/OldAccessToken.swift deleted file mode 100644 index 653944adb..000000000 --- a/14th-team5-iOS/Data/Sources/Storages/Keychain/TokenKeychain/Models/OldAccessToken.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// AccessToken.swift -// Data -// -// Created by 김건우 on 8/24/24. -// - -import Foundation - -public struct OldAccessToken: Codable, Equatable { - - public let accessToken: String? - public let refreshToken: String? - public let isTemporaryToken: Bool? - - public init( - accessToken: String?, - refreshToken: String?, - isTemporaryToken: Bool? - ) { - self.accessToken = accessToken - self.refreshToken = refreshToken - self.isTemporaryToken = isTemporaryToken - } -} diff --git a/14th-team5-iOS/Data/Sources/Storages/Keychain/TokenKeychain/TokenKeychain.swift b/14th-team5-iOS/Data/Sources/Storages/Keychain/TokenKeychain/TokenKeychain.swift index 4f0da9494..1f3112ed9 100644 --- a/14th-team5-iOS/Data/Sources/Storages/Keychain/TokenKeychain/TokenKeychain.swift +++ b/14th-team5-iOS/Data/Sources/Storages/Keychain/TokenKeychain/TokenKeychain.swift @@ -15,18 +15,12 @@ public protocol TokenKeychainType: KeychainType { func saveSignInType(_ type: SignInType?) func loadSignInType() -> SignInType? + + func saveAuthToken(_ authToken: AuthToken?) + func loadAuthToken() -> AuthToken? - func saveAccessToken(_ accessToken: String?) - func loadAccessToken() -> String? - - func saveIsTemporaryToken(_ isTemporary: Bool?) - func loadIsTemporaryToken() -> Bool? - - func saveOldAccessToken(_ tokenResult: OldAccessToken?) - func loadOldAccessToken() -> OldAccessToken? - - func saveRefreshToken(_ refreshToken: String?) - func loadRefreshToken() -> String? + func saveAccessToken(_ accessToken: AccessToken?) + func loadAccessToken() -> AccessToken? func saveFCMToken(_ fcmToken: String?) func loadFCMToken() -> String? @@ -68,43 +62,6 @@ final public class TokenKeychain: TokenKeychainType { } - // MARK: - AccessToken - - /// 삐삐 서버로부터 발급받은 접근 토큰을 저장합니다. - public func saveAccessToken(_ accessToken: String?) { - keychain[.newAccessToken] = accessToken - } - - /// 삐삐 서버로부터 발급받은 접근 토큰을 불러옵니다. - public func loadAccessToken() -> String? { - keychain[.newAccessToken] - } - - - // MARK: - RefreshToken - - /// 삐삐 서버로부터 발급받은 리프레시 토큰을 저장합니다. - public func saveRefreshToken(_ refreshToken: String?) { - keychain[.newRefreshToken] = refreshToken - } - - /// 삐삐 서버로부터 발급받은 리프레시 토큰을 불러옵니다. - public func loadRefreshToken() -> String? { - keychain[.newRefreshToken] - } - - - // MARK: - Is Temporary Token - - public func saveIsTemporaryToken(_ isTemporary: Bool?) { - keychain[.newIsTemporaryToken] = isTemporary - } - - public func loadIsTemporaryToken() -> Bool? { - keychain[.newIsTemporaryToken] - } - - // MARK: - FCM Token /// FCM 서버로부터 발급받은 FCM 토큰을 저장합니다. @@ -119,25 +76,28 @@ final public class TokenKeychain: TokenKeychainType { + // MARK: - Auth AccessToken + + public func saveAuthToken(_ authToken: AuthToken?) { + keychain[.accessToken] = authToken + } + + public func loadAuthToken() -> AuthToken? { + keychain[.accessToken] + } + + + // MARK: - Old AccessToken - @available(*, deprecated) - public func saveOldAccessToken(_ tokenResult: OldAccessToken?) { - guard - let data = try? JSONEncoder().encode(tokenResult), - let str = String(data: data, encoding: .utf8) - else { return } - keychain[.accessToken] = str + @available(*, deprecated, renamed: "saveAuthToken") + public func saveAccessToken(_ accessToken: AccessToken?) { + keychain[.accessToken] = accessToken } - @available(*, deprecated) - public func loadOldAccessToken() -> OldAccessToken? { - guard - let str: String = keychain[.accessToken], - let data = str.data(using: .utf8), - let tokenResult = try? JSONDecoder().decode(OldAccessToken.self, from: data) - else { return nil } - return tokenResult + @available(*, deprecated, renamed: "loadAuthToken") + public func loadAccessToken() -> AccessToken? { + keychain[.accessToken] } } diff --git a/14th-team5-iOS/Data/Sources/Trash/APIWorker.swift b/14th-team5-iOS/Data/Sources/Trash/APIWorker.swift index 7989826ed..6ba2b0925 100644 --- a/14th-team5-iOS/Data/Sources/Trash/APIWorker.swift +++ b/14th-team5-iOS/Data/Sources/Trash/APIWorker.swift @@ -133,7 +133,7 @@ public class APIWorker: NSObject { headers: [APIHeader]? = nil, jsonEncodable: Encodable ) -> Observable<(HTTPURLResponse, Data)> { - guard let jsonData = jsonEncodable.encodeToData() else { + guard let jsonData = jsonEncodable.toData() else { return Observable.error(AFError.explicitlyCancelled) }