diff --git a/.gitignore b/.gitignore index 8ee8cb7d..9c13ae32 100644 --- a/.gitignore +++ b/.gitignore @@ -99,4 +99,7 @@ iOSInjectionProject/ !*.xcworkspace/contents.xcworkspacedata **/xcshareddata/WorkspaceSettings.xcsettings +## config ## +*.xcconfig + # End of https://www.toptal.com/developers/gitignore/api/swift diff --git a/ChatBot/ChatBot.xcodeproj/project.pbxproj b/ChatBot/ChatBot.xcodeproj/project.pbxproj index 6e350285..bf464667 100644 --- a/ChatBot/ChatBot.xcodeproj/project.pbxproj +++ b/ChatBot/ChatBot.xcodeproj/project.pbxproj @@ -10,6 +10,15 @@ 3756D96839324F046B039CE8 /* Pods_ChatBot.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 86F2885AC45A38F47FDA4AD5 /* Pods_ChatBot.framework */; }; 84149A5B2BB285B1003595D0 /* ResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84149A5A2BB285B1003595D0 /* ResponseDTO.swift */; }; 84149A5D2BB2940B003595D0 /* RequestDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84149A5C2BB2940B003595D0 /* RequestDTO.swift */; }; + 95280FAF2BBD68C90071860A /* NetworkRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95280FAE2BBD68C90071860A /* NetworkRouter.swift */; }; + 95280FB12BBD6C010071860A /* APIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95280FB02BBD6C010071860A /* APIClient.swift */; }; + 95280FB32BBD6C440071860A /* APIRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95280FB22BBD6C440071860A /* APIRouter.swift */; }; + 95280FB52BBD6CA10071860A /* NetworkResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95280FB42BBD6CA10071860A /* NetworkResult.swift */; }; + 95280FB72BBD6CF80071860A /* APIConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95280FB62BBD6CF80071860A /* APIConstants.swift */; }; + 95280FBB2BBD70AE0071860A /* RequestDTO+DictionaryRepresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95280FBA2BBD70AE0071860A /* RequestDTO+DictionaryRepresentation.swift */; }; + 95280FBD2BBD70E50071860A /* MessageDTO+DictionaryRepresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95280FBC2BBD70E50071860A /* MessageDTO+DictionaryRepresentation.swift */; }; + 95280FBF2BBD71390071860A /* ChatService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95280FBE2BBD71390071860A /* ChatService.swift */; }; + 95280FC12BBE0C880071860A /* AppConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95280FC02BBE0C880071860A /* AppConfig.swift */; }; 95B4F31B2BB2C21E00AB4952 /* .swiftlint.yml in Resources */ = {isa = PBXBuildFile; fileRef = 95B4F31A2BB2C21E00AB4952 /* .swiftlint.yml */; }; 95B4F3272BB42ED300AB4952 /* MessageDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B4F3262BB42ED300AB4952 /* MessageDTO.swift */; }; B4B3E2BD2B42D1BB00818B3C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B3E2BC2B42D1BB00818B3C /* AppDelegate.swift */; }; @@ -23,7 +32,17 @@ 548DCC0B40D1F4BC4766D293 /* Pods-ChatBot.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ChatBot.release.xcconfig"; path = "Target Support Files/Pods-ChatBot/Pods-ChatBot.release.xcconfig"; sourceTree = ""; }; 84149A5A2BB285B1003595D0 /* ResponseDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResponseDTO.swift; sourceTree = ""; }; 84149A5C2BB2940B003595D0 /* RequestDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestDTO.swift; sourceTree = ""; }; + 843E18412BBD214C003EEF6D /* Configuration.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Configuration.xcconfig; sourceTree = ""; }; 86F2885AC45A38F47FDA4AD5 /* Pods_ChatBot.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ChatBot.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 95280FAE2BBD68C90071860A /* NetworkRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkRouter.swift; sourceTree = ""; }; + 95280FB02BBD6C010071860A /* APIClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIClient.swift; sourceTree = ""; }; + 95280FB22BBD6C440071860A /* APIRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIRouter.swift; sourceTree = ""; }; + 95280FB42BBD6CA10071860A /* NetworkResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkResult.swift; sourceTree = ""; }; + 95280FB62BBD6CF80071860A /* APIConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIConstants.swift; sourceTree = ""; }; + 95280FBA2BBD70AE0071860A /* RequestDTO+DictionaryRepresentation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RequestDTO+DictionaryRepresentation.swift"; sourceTree = ""; }; + 95280FBC2BBD70E50071860A /* MessageDTO+DictionaryRepresentation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MessageDTO+DictionaryRepresentation.swift"; sourceTree = ""; }; + 95280FBE2BBD71390071860A /* ChatService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatService.swift; sourceTree = ""; }; + 95280FC02BBE0C880071860A /* AppConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppConfig.swift; sourceTree = ""; }; 95B4F31A2BB2C21E00AB4952 /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = ""; }; 95B4F3262BB42ED300AB4952 /* MessageDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageDTO.swift; sourceTree = ""; }; B4B3E2B92B42D1BB00818B3C /* ChatBot.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ChatBot.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -56,6 +75,44 @@ name = Frameworks; sourceTree = ""; }; + 95280FAA2BBD63A00071860A /* Network */ = { + isa = PBXGroup; + children = ( + 95280FAE2BBD68C90071860A /* NetworkRouter.swift */, + 95280FB02BBD6C010071860A /* APIClient.swift */, + 95280FB22BBD6C440071860A /* APIRouter.swift */, + 95280FB42BBD6CA10071860A /* NetworkResult.swift */, + 95280FB62BBD6CF80071860A /* APIConstants.swift */, + ); + path = Network; + sourceTree = ""; + }; + 95280FB82BBD70870071860A /* Util */ = { + isa = PBXGroup; + children = ( + 95280FB92BBD708E0071860A /* Extensions */, + 95280FC02BBE0C880071860A /* AppConfig.swift */, + ); + path = Util; + sourceTree = ""; + }; + 95280FB92BBD708E0071860A /* Extensions */ = { + isa = PBXGroup; + children = ( + 95280FBA2BBD70AE0071860A /* RequestDTO+DictionaryRepresentation.swift */, + 95280FBC2BBD70E50071860A /* MessageDTO+DictionaryRepresentation.swift */, + ); + path = Extensions; + sourceTree = ""; + }; + 95280FC32BBE36590071860A /* Service */ = { + isa = PBXGroup; + children = ( + 95280FBE2BBD71390071860A /* ChatService.swift */, + ); + path = Service; + sourceTree = ""; + }; 95B4F3282BB43A8E00AB4952 /* App */ = { isa = PBXGroup; children = ( @@ -78,8 +135,9 @@ 95B4F32A2BB43BDB00AB4952 /* Resources */ = { isa = PBXGroup; children = ( - B4B3E2CA2B42D1BC00818B3C /* Info.plist */, + 843E18412BBD214C003EEF6D /* Configuration.xcconfig */, B4B3E2C52B42D1BC00818B3C /* Assets.xcassets */, + B4B3E2CA2B42D1BC00818B3C /* Info.plist */, B4B3E2C72B42D1BC00818B3C /* LaunchScreen.storyboard */, ); path = Resources; @@ -126,8 +184,11 @@ children = ( 95B4F3282BB43A8E00AB4952 /* App */, 95B4F3292BB43A9C00AB4952 /* Model */, + 95280FAA2BBD63A00071860A /* Network */, + 95280FC32BBE36590071860A /* Service */, 95B4F32B2BB4714200AB4952 /* Controller */, 95B4F32A2BB43BDB00AB4952 /* Resources */, + 95280FB82BBD70870071860A /* Util */, ); path = ChatBot; sourceTree = ""; @@ -139,11 +200,12 @@ isa = PBXNativeTarget; buildConfigurationList = B4B3E2CD2B42D1BC00818B3C /* Build configuration list for PBXNativeTarget "ChatBot" */; buildPhases = ( - 95B4F3192BB2C1A100AB4952 /* SwiftLint */, CF48DBE895D16B153F73C922 /* [CP] Check Pods Manifest.lock */, + 95B4F3192BB2C1A100AB4952 /* SwiftLint */, B4B3E2B52B42D1BB00818B3C /* Sources */, B4B3E2B62B42D1BB00818B3C /* Frameworks */, B4B3E2B72B42D1BB00818B3C /* Resources */, + 157BC9F75AEC0E5F7B580B83 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -201,6 +263,23 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 157BC9F75AEC0E5F7B580B83 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ChatBot/Pods-ChatBot-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ChatBot/Pods-ChatBot-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ChatBot/Pods-ChatBot-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; 95B4F3192BB2C1A100AB4952 /* SwiftLint */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -249,12 +328,21 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 95280FBB2BBD70AE0071860A /* RequestDTO+DictionaryRepresentation.swift in Sources */, B4B3E2C12B42D1BB00818B3C /* ViewController.swift in Sources */, + 95280FB72BBD6CF80071860A /* APIConstants.swift in Sources */, + 95280FB52BBD6CA10071860A /* NetworkResult.swift in Sources */, + 95280FB32BBD6C440071860A /* APIRouter.swift in Sources */, B4B3E2BD2B42D1BB00818B3C /* AppDelegate.swift in Sources */, + 95280FC12BBE0C880071860A /* AppConfig.swift in Sources */, 84149A5B2BB285B1003595D0 /* ResponseDTO.swift in Sources */, + 95280FB12BBD6C010071860A /* APIClient.swift in Sources */, + 95280FAF2BBD68C90071860A /* NetworkRouter.swift in Sources */, + 95280FBF2BBD71390071860A /* ChatService.swift in Sources */, 84149A5D2BB2940B003595D0 /* RequestDTO.swift in Sources */, 95B4F3272BB42ED300AB4952 /* MessageDTO.swift in Sources */, B4B3E2BF2B42D1BB00818B3C /* SceneDelegate.swift in Sources */, + 95280FBD2BBD70E50071860A /* MessageDTO+DictionaryRepresentation.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -274,6 +362,7 @@ /* Begin XCBuildConfiguration section */ B4B3E2CB2B42D1BC00818B3C /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 843E18412BBD214C003EEF6D /* Configuration.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; @@ -337,6 +426,7 @@ }; B4B3E2CC2B42D1BC00818B3C /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 843E18412BBD214C003EEF6D /* Configuration.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; @@ -407,7 +497,7 @@ INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -442,7 +532,7 @@ INFOPLIST_KEY_UIMainStoryboardFile = Main; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/ChatBot/ChatBot/Controller/ViewController.swift b/ChatBot/ChatBot/Controller/ViewController.swift index 2ed5f125..597099f0 100644 --- a/ChatBot/ChatBot/Controller/ViewController.swift +++ b/ChatBot/ChatBot/Controller/ViewController.swift @@ -8,7 +8,21 @@ import UIKit class ViewController: UIViewController { + let chatService = ChatService() + override func viewDidLoad() { super.viewDidLoad() + sendTestMessage("안녕 만나서 반가워") + } + + func sendTestMessage(_ message: String) { + chatService.sendChatRequest(message: message) { result in + switch result { + case .success(let response): + print("Response: \(response)") + case .failure(let error): + print("Error: \(error)") + } + } } } diff --git a/ChatBot/ChatBot/Model/MessageDTO.swift b/ChatBot/ChatBot/Model/MessageDTO.swift index 6aa95b7d..f3ac7314 100644 --- a/ChatBot/ChatBot/Model/MessageDTO.swift +++ b/ChatBot/ChatBot/Model/MessageDTO.swift @@ -5,7 +5,7 @@ // Created by nayeon on 3/27/24. // -struct MessageDTO: Codable { +struct MessageDTO: Codable, DictionaryRepresentable { let role: Role let content: String } diff --git a/ChatBot/ChatBot/Model/RequestDTO.swift b/ChatBot/ChatBot/Model/RequestDTO.swift index 9cc251f1..6e2191ae 100644 --- a/ChatBot/ChatBot/Model/RequestDTO.swift +++ b/ChatBot/ChatBot/Model/RequestDTO.swift @@ -5,7 +5,11 @@ // Created by dopamint on 3/26/24. // -struct RequestDTO: Encodable { +protocol DictionaryRepresentable { + func dictionaryRepresentation() -> [String: Any] +} + +struct RequestDTO: Encodable, DictionaryRepresentable { let model: GPTModel let stream: Bool let messages: [MessageDTO] diff --git a/ChatBot/ChatBot/Network/APIClient.swift b/ChatBot/ChatBot/Network/APIClient.swift new file mode 100644 index 00000000..5e42eda6 --- /dev/null +++ b/ChatBot/ChatBot/Network/APIClient.swift @@ -0,0 +1,40 @@ +// +// APIClient.swift +// ChatBot +// +// Created by nayeon on 4/3/24. +// + +import Alamofire + +enum APIClient { + + static func request(_ object: T.Type, + router: URLRequestConvertible, + completion: @escaping (NetworkResult) -> Void) { + AF.request(router) + .validate(statusCode: 200..<500) + .responseDecodable(of: object) { response in + switch response.result { + case .success(let decodedData): + completion(.success(decodedData)) + case .failure(let error): + var errorMessage: String? + if let data = response.data, let message = String(data: data, encoding: .utf8) { + errorMessage = message + } + + if let statusCode = response.response?.statusCode { + switch statusCode { + case 400...499: + completion(.failure(.pathError(message: errorMessage))) + case 500...599: + completion(.failure(.serverError(message: errorMessage ?? "server error"))) + default: + completion(.failure(.networkFail)) + } + } + } + } + } +} diff --git a/ChatBot/ChatBot/Network/APIConstants.swift b/ChatBot/ChatBot/Network/APIConstants.swift new file mode 100644 index 00000000..68ab88f6 --- /dev/null +++ b/ChatBot/ChatBot/Network/APIConstants.swift @@ -0,0 +1,21 @@ +// +// APIConstants.swift +// ChatBot +// +// Created by nayeon on 4/3/24. +// + +import Foundation + +enum APIConstants { + static let baseURL = "https://api.openai.com" +} + +enum HTTPHeaderField: String { + case authentication = "Authorization" + case contentType = "Content-Type" +} + +enum ContentType: String { + case json = "application/json" +} diff --git a/ChatBot/ChatBot/Network/APIRouter.swift b/ChatBot/ChatBot/Network/APIRouter.swift new file mode 100644 index 00000000..9dd8583f --- /dev/null +++ b/ChatBot/ChatBot/Network/APIRouter.swift @@ -0,0 +1,51 @@ +// +// APIRouter.swift +// ChatBot +// +// Created by nayeon on 4/3/24. +// + +import Alamofire + +enum APIRouter: NetworkRouter, URLRequestConvertible { + case chatCompletion(requestDTO: RequestDTO) + + var baseURL: String { + return APIConstants.baseURL + } + + var path: String { + switch self { + case .chatCompletion: + return "/v1/chat/completions" + } + } + + var method: HTTPMethod { + switch self { + case .chatCompletion: + return .post + } + } + + var headers: [String: String] { + return [ + HTTPHeaderField.contentType.rawValue: ContentType.json.rawValue, + HTTPHeaderField.authentication.rawValue: "Bearer \(AppConfig.openAIAPIKey)" + ] + } + + var parameters: [String: Any]? { + switch self { + case .chatCompletion(let requestDTO): + return requestDTO.dictionaryRepresentation() + } + } + + var encoding: ParameterEncoding { + switch self { + case .chatCompletion: + return JSONEncoding.default + } + } +} diff --git a/ChatBot/ChatBot/Network/NetworkResult.swift b/ChatBot/ChatBot/Network/NetworkResult.swift new file mode 100644 index 00000000..adcfc656 --- /dev/null +++ b/ChatBot/ChatBot/Network/NetworkResult.swift @@ -0,0 +1,17 @@ +// +// NetworkResult.swift +// ChatBot +// +// Created by nayeon on 4/3/24. +// + +enum NetworkResult { + case success(T) + case failure(NetworkError) +} + +enum NetworkError: Error { + case pathError(message: String?) + case serverError(message: String?) + case networkFail +} diff --git a/ChatBot/ChatBot/Network/NetworkRouter.swift b/ChatBot/ChatBot/Network/NetworkRouter.swift new file mode 100644 index 00000000..5248b289 --- /dev/null +++ b/ChatBot/ChatBot/Network/NetworkRouter.swift @@ -0,0 +1,30 @@ +// +// NetworkRouter.swift +// ChatBot +// +// Created by nayeon on 4/3/24. +// + +import Alamofire + +protocol NetworkRouter { + var baseURL: String { get } + var path: String { get } + var method: HTTPMethod { get } + var headers: [String: String] { get } + var parameters: [String: Any]? { get } + var encoding: ParameterEncoding { get } +} + +extension NetworkRouter { + func asURLRequest() throws -> URLRequest { + let url = try baseURL.asURL() + var urlRequest = URLRequest(url: url.appendingPathComponent(path)) + urlRequest.httpMethod = method.rawValue + urlRequest.allHTTPHeaderFields = headers + if let parameters = parameters { + urlRequest = try encoding.encode(urlRequest, with: parameters) + } + return urlRequest + } +} diff --git a/ChatBot/ChatBot/Resources/Info.plist b/ChatBot/ChatBot/Resources/Info.plist index 0eb786dc..a1c5c6b6 100644 --- a/ChatBot/ChatBot/Resources/Info.plist +++ b/ChatBot/ChatBot/Resources/Info.plist @@ -2,6 +2,8 @@ + API_KEY + $(API_KEY) UIApplicationSceneManifest UIApplicationSupportsMultipleScenes diff --git a/ChatBot/ChatBot/Service/ChatService.swift b/ChatBot/ChatBot/Service/ChatService.swift new file mode 100644 index 00000000..09a23a10 --- /dev/null +++ b/ChatBot/ChatBot/Service/ChatService.swift @@ -0,0 +1,27 @@ +// +// ChatService.swift +// ChatBot +// +// Created by nayeon on 4/3/24. +// + +protocol ChatServiceProtocol { + func sendChatRequest(message: String, completion: @escaping (NetworkResult) -> Void) +} + +final class ChatService: ChatServiceProtocol { + + func sendChatRequest(message: String, completion: @escaping (NetworkResult) -> Void) { + let requestDTO = RequestDTO(model: .basic, stream: false, messages: [MessageDTO(role: .user, content: message)]) + let router = APIRouter.chatCompletion(requestDTO: requestDTO) + + APIClient.request(ResponseDTO.self, router: router) { result in + switch result { + case .success(let response): + completion(.success(response)) + case .failure(let error): + completion(.failure(error)) + } + } + } +} diff --git a/ChatBot/ChatBot/Util/AppConfig.swift b/ChatBot/ChatBot/Util/AppConfig.swift new file mode 100644 index 00000000..66d9deb9 --- /dev/null +++ b/ChatBot/ChatBot/Util/AppConfig.swift @@ -0,0 +1,18 @@ +// +// AppConfig.swift +// ChatBot +// +// Created by nayeon on 4/4/24. +// + +import Foundation + +enum AppConfig { + static var openAIAPIKey: String { + guard let key = Bundle.main.object(forInfoDictionaryKey: "API_KEY") as? String else { + assertionFailure("API_KEY를 찾을 수 없음") + return "" + } + return key + } +} diff --git a/ChatBot/ChatBot/Util/Extensions/MessageDTO+DictionaryRepresentation.swift b/ChatBot/ChatBot/Util/Extensions/MessageDTO+DictionaryRepresentation.swift new file mode 100644 index 00000000..7bc4ed70 --- /dev/null +++ b/ChatBot/ChatBot/Util/Extensions/MessageDTO+DictionaryRepresentation.swift @@ -0,0 +1,15 @@ +// +// MessageDTO+DictionaryRepresentation.swift +// ChatBot +// +// Created by nayeon on 4/3/24. +// + +extension MessageDTO { + func dictionaryRepresentation() -> [String: Any] { + return [ + "role": role.rawValue, + "content": content + ] + } +} diff --git a/ChatBot/ChatBot/Util/Extensions/RequestDTO+DictionaryRepresentation.swift b/ChatBot/ChatBot/Util/Extensions/RequestDTO+DictionaryRepresentation.swift new file mode 100644 index 00000000..9abb3a53 --- /dev/null +++ b/ChatBot/ChatBot/Util/Extensions/RequestDTO+DictionaryRepresentation.swift @@ -0,0 +1,18 @@ +// +// RequestDTO+DictionaryRepresentation.swift +// ChatBot +// +// Created by nayeon on 4/3/24. +// + +extension RequestDTO { + func dictionaryRepresentation() -> [String: Any] { + var parameters: [String: Any] = [:] + + parameters["model"] = model.rawValue + parameters["stream"] = stream + parameters["messages"] = messages.map { $0.dictionaryRepresentation() } + + return parameters + } +} diff --git a/ChatBot/Podfile b/ChatBot/Podfile index dc8abb8c..56f8f602 100644 --- a/ChatBot/Podfile +++ b/ChatBot/Podfile @@ -7,4 +7,5 @@ target 'ChatBot' do # Pods for ChatBot pod "SwiftLint" + pod 'Alamofire' end diff --git a/ChatBot/Podfile.lock b/ChatBot/Podfile.lock index 907e2985..dc6f1af0 100644 --- a/ChatBot/Podfile.lock +++ b/ChatBot/Podfile.lock @@ -1,16 +1,20 @@ PODS: + - Alamofire (5.6.4) - SwiftLint (0.54.0) DEPENDENCIES: + - Alamofire - SwiftLint SPEC REPOS: trunk: + - Alamofire - SwiftLint SPEC CHECKSUMS: + Alamofire: 4e95d97098eacb88856099c4fc79b526a299e48c SwiftLint: c1de071d9d08c8aba837545f6254315bc900e211 -PODFILE CHECKSUM: 5d1036dd232630979c2ecd98143c4c994fa049db +PODFILE CHECKSUM: f2c861e2b4b4d583b1a645c37ba0896b5d68f903 COCOAPODS: 1.12.0