diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..7baf41eb Binary files /dev/null and b/.DS_Store differ diff --git a/ChatBot/.gitignore b/ChatBot/.gitignore new file mode 100644 index 00000000..e5dd6d4f --- /dev/null +++ b/ChatBot/.gitignore @@ -0,0 +1,118 @@ +# Created by https://www.toptal.com/developers/gitignore/api/xcode,swift,cocoapods +# Edit at https://www.toptal.com/developers/gitignore?templates=xcode,swift,cocoapods + +### CocoaPods ### +## CocoaPods GitIgnore Template + +# CocoaPods - Only use to conserve bandwidth / Save time on Pushing +# - Also handy if you have a large number of dependant pods +# - AS PER https://guides.cocoapods.org/using/using-cocoapods.html NEVER IGNORE THE LOCK FILE +Pods/ + +### Swift ### +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## User settings +xcuserdata/ + +## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) +*.xcscmblueprint +*.xccheckout + +## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) +build/ +DerivedData/ +*.moved-aside +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 + +## Obj-C/Swift specific +*.hmap + +## App packaging +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +# Package.pins +# Package.resolved +# *.xcodeproj +# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata +# hence it is not needed unless you have added a package configuration file to your project +# .swiftpm + +.build/ + +# CocoaPods +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# Pods/ +# Add this line if you want to avoid checking in source code from the Xcode workspace +# *.xcworkspace + +# Carthage +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build/ + +# Accio dependency management +Dependencies/ +.accio/ + +# fastlane +# It is recommended to not store the screenshots in the git repo. +# Instead, use fastlane to re-generate the screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots/**/*.png +fastlane/test_output + +# Code Injection +# After new code Injection tools there's a generated folder /iOSInjectionProject +# https://github.com/johnno1962/injectionforxcode + +iOSInjectionProject/ + +### Xcode ### +# Xcode +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + + +### DS_Store ### +.DS_Store + + +## Gcc Patch +/*.gcno + +### Xcode Patch ### +*.xcodeproj/* +!*.xcodeproj/project.pbxproj +!*.xcodeproj/xcshareddata/ +!*.xcworkspace/contents.xcworkspacedata +**/xcshareddata/WorkspaceSettings.xcsettings + +## APIKEY +Api_Key.plist + +# End of https://www.toptal.com/developers/gitignore/api/xcode,swift,cocoapods diff --git a/ChatBot/ChatBot.xcodeproj/project.pbxproj b/ChatBot/ChatBot.xcodeproj/project.pbxproj index b0f43154..6d30523a 100644 --- a/ChatBot/ChatBot.xcodeproj/project.pbxproj +++ b/ChatBot/ChatBot.xcodeproj/project.pbxproj @@ -7,23 +7,39 @@ objects = { /* Begin PBXBuildFile section */ - B4B3E2BD2B42D1BB00818B3C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B3E2BC2B42D1BB00818B3C /* AppDelegate.swift */; }; - B4B3E2BF2B42D1BB00818B3C /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B3E2BE2B42D1BB00818B3C /* SceneDelegate.swift */; }; - B4B3E2C12B42D1BB00818B3C /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B3E2C02B42D1BB00818B3C /* ViewController.swift */; }; - B4B3E2C42B42D1BB00818B3C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B4B3E2C22B42D1BB00818B3C /* Main.storyboard */; }; - B4B3E2C62B42D1BC00818B3C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B4B3E2C52B42D1BC00818B3C /* Assets.xcassets */; }; - B4B3E2C92B42D1BC00818B3C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B4B3E2C72B42D1BC00818B3C /* LaunchScreen.storyboard */; }; + 1512D68D2BC3B42F00FDB7F6 /* Bundel+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1512D68C2BC3B42F00FDB7F6 /* Bundel+Extension.swift */; }; + 1512D6902BC3B4E800FDB7F6 /* NetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1512D68F2BC3B4E800FDB7F6 /* NetworkManager.swift */; }; + 1512D6922BC3B58900FDB7F6 /* NetworkError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1512D6912BC3B58900FDB7F6 /* NetworkError.swift */; }; + 1512D6942BC3B66B00FDB7F6 /* Choice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1512D6932BC3B66B00FDB7F6 /* Choice.swift */; }; + 1512D6962BC3B68F00FDB7F6 /* Usage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1512D6952BC3B68F00FDB7F6 /* Usage.swift */; }; + 15D33E822BBFE96D00F88B25 /* Api_Key.plist in Resources */ = {isa = PBXBuildFile; fileRef = 15D33E812BBFE96D00F88B25 /* Api_Key.plist */; }; + 1D312FB42BBACF8000169AD3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D312FB12BBACF8000169AD3 /* AppDelegate.swift */; }; + 1D312FB52BBACF8000169AD3 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D312FB22BBACF8000169AD3 /* SceneDelegate.swift */; }; + 1D312FBC2BBACFA100169AD3 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D312FBA2BBACFA100169AD3 /* ViewController.swift */; }; + 1D312FC22BBACFAF00169AD3 /* ChatRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D312FBD2BBACFAF00169AD3 /* ChatRequest.swift */; }; + 1D312FC32BBACFAF00169AD3 /* ChatResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D312FBE2BBACFAF00169AD3 /* ChatResponse.swift */; }; + 1D312FC42BBACFAF00169AD3 /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D312FBF2BBACFAF00169AD3 /* Message.swift */; }; + 1D312FCB2BBACFC200169AD3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1D312FC62BBACFC200169AD3 /* Assets.xcassets */; }; + 1D312FCD2BBACFC200169AD3 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1D312FC92BBACFC200169AD3 /* LaunchScreen.storyboard */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 1512D68C2BC3B42F00FDB7F6 /* Bundel+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bundel+Extension.swift"; sourceTree = ""; }; + 1512D68F2BC3B4E800FDB7F6 /* NetworkManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkManager.swift; sourceTree = ""; }; + 1512D6912BC3B58900FDB7F6 /* NetworkError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkError.swift; sourceTree = ""; }; + 1512D6932BC3B66B00FDB7F6 /* Choice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Choice.swift; sourceTree = ""; }; + 1512D6952BC3B68F00FDB7F6 /* Usage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Usage.swift; sourceTree = ""; }; + 15D33E812BBFE96D00F88B25 /* Api_Key.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Api_Key.plist; sourceTree = ""; }; + 1D312FB12BBACF8000169AD3 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 1D312FB22BBACF8000169AD3 /* SceneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 1D312FBA2BBACFA100169AD3 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 1D312FBD2BBACFAF00169AD3 /* ChatRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatRequest.swift; sourceTree = ""; }; + 1D312FBE2BBACFAF00169AD3 /* ChatResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatResponse.swift; sourceTree = ""; }; + 1D312FBF2BBACFAF00169AD3 /* Message.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Message.swift; sourceTree = ""; }; + 1D312FC62BBACFC200169AD3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1D312FC72BBACFC200169AD3 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1D312FC82BBACFC200169AD3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; B4B3E2B92B42D1BB00818B3C /* ChatBot.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ChatBot.app; sourceTree = BUILT_PRODUCTS_DIR; }; - B4B3E2BC2B42D1BB00818B3C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - B4B3E2BE2B42D1BB00818B3C /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - B4B3E2C02B42D1BB00818B3C /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - B4B3E2C32B42D1BB00818B3C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - B4B3E2C52B42D1BC00818B3C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - B4B3E2C82B42D1BC00818B3C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - B4B3E2CA2B42D1BC00818B3C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -37,6 +53,63 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 1512D68B2BC3B41A00FDB7F6 /* Extension */ = { + isa = PBXGroup; + children = ( + 1512D68C2BC3B42F00FDB7F6 /* Bundel+Extension.swift */, + ); + path = Extension; + sourceTree = ""; + }; + 1512D68E2BC3B4D400FDB7F6 /* Network */ = { + isa = PBXGroup; + children = ( + 1512D68F2BC3B4E800FDB7F6 /* NetworkManager.swift */, + 1512D6912BC3B58900FDB7F6 /* NetworkError.swift */, + ); + path = Network; + sourceTree = ""; + }; + 1D312FB32BBACF8000169AD3 /* App */ = { + isa = PBXGroup; + children = ( + 1D312FB12BBACF8000169AD3 /* AppDelegate.swift */, + 1D312FB22BBACF8000169AD3 /* SceneDelegate.swift */, + ); + path = App; + sourceTree = ""; + }; + 1D312FBB2BBACFA100169AD3 /* Controller */ = { + isa = PBXGroup; + children = ( + 1D312FBA2BBACFA100169AD3 /* ViewController.swift */, + ); + path = Controller; + sourceTree = ""; + }; + 1D312FC12BBACFAF00169AD3 /* Model */ = { + isa = PBXGroup; + children = ( + 1D312FBD2BBACFAF00169AD3 /* ChatRequest.swift */, + 1D312FBE2BBACFAF00169AD3 /* ChatResponse.swift */, + 1512D6932BC3B66B00FDB7F6 /* Choice.swift */, + 1512D6952BC3B68F00FDB7F6 /* Usage.swift */, + 1D312FBF2BBACFAF00169AD3 /* Message.swift */, + ); + path = Model; + sourceTree = ""; + }; + 1D312FCA2BBACFC200169AD3 /* Resources */ = { + isa = PBXGroup; + children = ( + 15D33E812BBFE96D00F88B25 /* Api_Key.plist */, + 1D312FC62BBACFC200169AD3 /* Assets.xcassets */, + 1D312FC72BBACFC200169AD3 /* Info.plist */, + 1D312FC92BBACFC200169AD3 /* LaunchScreen.storyboard */, + ); + path = Resources; + sourceTree = ""; + }; B4B3E2B02B42D1BB00818B3C = { isa = PBXGroup; children = ( @@ -56,13 +129,12 @@ B4B3E2BB2B42D1BB00818B3C /* ChatBot */ = { isa = PBXGroup; children = ( - B4B3E2BC2B42D1BB00818B3C /* AppDelegate.swift */, - B4B3E2BE2B42D1BB00818B3C /* SceneDelegate.swift */, - B4B3E2C02B42D1BB00818B3C /* ViewController.swift */, - B4B3E2C22B42D1BB00818B3C /* Main.storyboard */, - B4B3E2C52B42D1BC00818B3C /* Assets.xcassets */, - B4B3E2C72B42D1BC00818B3C /* LaunchScreen.storyboard */, - B4B3E2CA2B42D1BC00818B3C /* Info.plist */, + 1512D68E2BC3B4D400FDB7F6 /* Network */, + 1512D68B2BC3B41A00FDB7F6 /* Extension */, + 1D312FB32BBACF8000169AD3 /* App */, + 1D312FC12BBACFAF00169AD3 /* Model */, + 1D312FCA2BBACFC200169AD3 /* Resources */, + 1D312FBB2BBACFA100169AD3 /* Controller */, ); path = ChatBot; sourceTree = ""; @@ -125,9 +197,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - B4B3E2C92B42D1BC00818B3C /* LaunchScreen.storyboard in Resources */, - B4B3E2C62B42D1BC00818B3C /* Assets.xcassets in Resources */, - B4B3E2C42B42D1BB00818B3C /* Main.storyboard in Resources */, + 15D33E822BBFE96D00F88B25 /* Api_Key.plist in Resources */, + 1D312FCB2BBACFC200169AD3 /* Assets.xcassets in Resources */, + 1D312FCD2BBACFC200169AD3 /* LaunchScreen.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -138,27 +210,27 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - B4B3E2C12B42D1BB00818B3C /* ViewController.swift in Sources */, - B4B3E2BD2B42D1BB00818B3C /* AppDelegate.swift in Sources */, - B4B3E2BF2B42D1BB00818B3C /* SceneDelegate.swift in Sources */, + 1D312FC32BBACFAF00169AD3 /* ChatResponse.swift in Sources */, + 1D312FB42BBACF8000169AD3 /* AppDelegate.swift in Sources */, + 1D312FC22BBACFAF00169AD3 /* ChatRequest.swift in Sources */, + 1D312FC42BBACFAF00169AD3 /* Message.swift in Sources */, + 1512D6962BC3B68F00FDB7F6 /* Usage.swift in Sources */, + 1512D6902BC3B4E800FDB7F6 /* NetworkManager.swift in Sources */, + 1D312FBC2BBACFA100169AD3 /* ViewController.swift in Sources */, + 1512D6942BC3B66B00FDB7F6 /* Choice.swift in Sources */, + 1512D6922BC3B58900FDB7F6 /* NetworkError.swift in Sources */, + 1512D68D2BC3B42F00FDB7F6 /* Bundel+Extension.swift in Sources */, + 1D312FB52BBACF8000169AD3 /* SceneDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ - B4B3E2C22B42D1BB00818B3C /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - B4B3E2C32B42D1BB00818B3C /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - B4B3E2C72B42D1BC00818B3C /* LaunchScreen.storyboard */ = { + 1D312FC92BBACFC200169AD3 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( - B4B3E2C82B42D1BC00818B3C /* Base */, + 1D312FC82BBACFC200169AD3 /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; @@ -294,10 +366,9 @@ CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = W9647FYSN7; GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = ChatBot/Info.plist; + INFOPLIST_FILE = ChatBot/Resources/Info.plist; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; - INFOPLIST_KEY_UIMainStoryboardFile = Main; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; IPHONEOS_DEPLOYMENT_TARGET = 15.0; @@ -323,10 +394,9 @@ CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = W9647FYSN7; GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = ChatBot/Info.plist; + INFOPLIST_FILE = ChatBot/Resources/Info.plist; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; - INFOPLIST_KEY_UIMainStoryboardFile = Main; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; IPHONEOS_DEPLOYMENT_TARGET = 15.0; diff --git a/ChatBot/ChatBot/AppDelegate.swift b/ChatBot/ChatBot/App/AppDelegate.swift similarity index 100% rename from ChatBot/ChatBot/AppDelegate.swift rename to ChatBot/ChatBot/App/AppDelegate.swift diff --git a/ChatBot/ChatBot/SceneDelegate.swift b/ChatBot/ChatBot/App/SceneDelegate.swift similarity index 65% rename from ChatBot/ChatBot/SceneDelegate.swift rename to ChatBot/ChatBot/App/SceneDelegate.swift index 290e44c2..6b4e84a4 100644 --- a/ChatBot/ChatBot/SceneDelegate.swift +++ b/ChatBot/ChatBot/App/SceneDelegate.swift @@ -9,11 +9,17 @@ import UIKit class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? - + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { - guard let _ = (scene as? UIWindowScene) else { return } + guard let windowScene = (scene as? UIWindowScene) else { return } + + // TODO: - rootViewController 설정 + let window = UIWindow(windowScene: windowScene) + window.rootViewController = ViewController() + window.makeKeyAndVisible() + self.window = window } - + func sceneDidDisconnect(_ scene: UIScene) { } func sceneDidBecomeActive(_ scene: UIScene) { } func sceneWillResignActive(_ scene: UIScene) { } diff --git a/ChatBot/ChatBot/Base.lproj/Main.storyboard b/ChatBot/ChatBot/Base.lproj/Main.storyboard deleted file mode 100644 index 25a76385..00000000 --- a/ChatBot/ChatBot/Base.lproj/Main.storyboard +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ChatBot/ChatBot/Controller/ViewController.swift b/ChatBot/ChatBot/Controller/ViewController.swift new file mode 100644 index 00000000..8a651ce0 --- /dev/null +++ b/ChatBot/ChatBot/Controller/ViewController.swift @@ -0,0 +1,36 @@ +// +// ViewController.swift +// ChatBot +// +// Created by Tacocat on 1/1/24. +// + +import UIKit + +class ViewController: UIViewController { + + var networkManger = NetworkManger() + + override func viewDidLoad() { + super.viewDidLoad() + view.backgroundColor = .white + fetchChatMessage() + } + + func fetchChatMessage() { + networkManger.urlDataTaks { result in + switch result { + case .success(let data): + let decodedResult: Result = self.networkManger.DecodedData(data: data) + switch decodedResult { + case .success(let decodedData): + print("Decoded data:", decodedData) + case .failure(let error): + print("Decoding failed with error:", error.localizedDescription) + } + case .failure(let error): + print("Error:", error.localizedDescription) + } + } + } +} diff --git a/ChatBot/ChatBot/Extension/Bundel+Extension.swift b/ChatBot/ChatBot/Extension/Bundel+Extension.swift new file mode 100644 index 00000000..6e875124 --- /dev/null +++ b/ChatBot/ChatBot/Extension/Bundel+Extension.swift @@ -0,0 +1,19 @@ + +import Foundation + +extension Bundle { + + // 생성한 .plist 파일 경로 불러오기 + var OPENAI_API_KEY: String { + guard let file = self.path(forResource: "Api_Key", ofType: "plist") else { return "" } + + // .plist를 딕셔너리로 받아오기 + guard let resource = NSDictionary(contentsOfFile: file) else { return "" } + + // 딕셔너리에서 값 찾기 + guard let key = resource["myApiKey"] as? String else { + fatalError("API_KEY error") + } + return key + } +} diff --git a/ChatBot/ChatBot/Model/ChatRequest.swift b/ChatBot/ChatBot/Model/ChatRequest.swift new file mode 100644 index 00000000..548b80be --- /dev/null +++ b/ChatBot/ChatBot/Model/ChatRequest.swift @@ -0,0 +1,20 @@ +// +// ChatRequest.swift +// ChatBot +// +// Created by yujaehong on 3/28/24. +// + +import Foundation + +struct ChatRequest: Codable { + var model: String = "gpt-3.5-turbo-1106" + var isFalse: Bool = false + let messages: [Message] + + enum CodingKeys: String ,CodingKey { + case model + case isFalse = "stream" + case messages + } +} diff --git a/ChatBot/ChatBot/Model/ChatResponse.swift b/ChatBot/ChatBot/Model/ChatResponse.swift new file mode 100644 index 00000000..972899e9 --- /dev/null +++ b/ChatBot/ChatBot/Model/ChatResponse.swift @@ -0,0 +1,29 @@ +// +// ChatResponse.swift +// ChatBot +// +// Created by yujaehong on 3/28/24. +// + +import Foundation + +struct ChatResponse: Codable { + let id: String + let object: String + let created: Int + let model: String + let systemFingerprint: String + let choices: [Choice] + let usage: Usage + + enum CodingKeys: String, CodingKey { + case id + case object + case created + case model + case choices + case usage + case systemFingerprint = "system_fingerprint" + } +} + diff --git a/ChatBot/ChatBot/Model/Choice.swift b/ChatBot/ChatBot/Model/Choice.swift new file mode 100644 index 00000000..1fa01827 --- /dev/null +++ b/ChatBot/ChatBot/Model/Choice.swift @@ -0,0 +1,16 @@ + +import Foundation + +struct Choice: Codable { + let index: Int + let message: Message + let logprobs: String? + let finishReason: String + + enum CodingKeys: String, CodingKey { + case index + case message + case logprobs + case finishReason = "finish_reason" + } +} diff --git a/ChatBot/ChatBot/Model/Message.swift b/ChatBot/ChatBot/Model/Message.swift new file mode 100644 index 00000000..617a0542 --- /dev/null +++ b/ChatBot/ChatBot/Model/Message.swift @@ -0,0 +1,13 @@ +// +// Message.swift +// ChatBot +// +// Created by yujaehong on 3/28/24. +// + +import Foundation + +struct Message: Codable { + let role: String + let content: String +} diff --git a/ChatBot/ChatBot/Model/Usage.swift b/ChatBot/ChatBot/Model/Usage.swift new file mode 100644 index 00000000..3e6bde45 --- /dev/null +++ b/ChatBot/ChatBot/Model/Usage.swift @@ -0,0 +1,14 @@ + +import Foundation + +struct Usage: Codable { + let promptTokens: Int + let completionTokens: Int + let totalTokens: Int + + enum CodingKeys: String, CodingKey { + case promptTokens = "prompt_tokens" + case completionTokens = "completion_tokens" + case totalTokens = "total_tokens" + } +} diff --git a/ChatBot/ChatBot/Network/NetworkError.swift b/ChatBot/ChatBot/Network/NetworkError.swift new file mode 100644 index 00000000..d6f6353c --- /dev/null +++ b/ChatBot/ChatBot/Network/NetworkError.swift @@ -0,0 +1,25 @@ + +import Foundation + +enum NetworkError: Error { + case urlError + case dataError + case decoderError + case requestError + case invalidResponse + + var errorMessage: String { + switch self { + case .urlError: + return "URL 에러 입니다." + case .dataError: + return "데이터 에러 입니다." + case .decoderError: + return "JSON 에러 입니다" + case .requestError: + return "request 에러 입니다." + case .invalidResponse: + return "invalidResponse 에러 입니다." + } + } +} diff --git a/ChatBot/ChatBot/Network/NetworkManager.swift b/ChatBot/ChatBot/Network/NetworkManager.swift new file mode 100644 index 00000000..92681527 --- /dev/null +++ b/ChatBot/ChatBot/Network/NetworkManager.swift @@ -0,0 +1,74 @@ + +import Foundation + +struct NetworkManger { + + let apiKey = Bundle.main.OPENAI_API_KEY + + func UrlComponents() -> URL?{ + var urlComponents = URLComponents() + urlComponents.scheme = "https" + urlComponents.host = "api.openai.com" + urlComponents.path = "/v1/chat/completions" + + return urlComponents.url + } + + func UrlRequset() -> URLRequest? { + guard let url = UrlComponents() else { + return nil + } + + var request = URLRequest(url: url) + request.httpMethod = "POST" + let header = ["Authorization": "Bearer \(apiKey)"] + request.allHTTPHeaderFields = header + request.setValue("application/json", forHTTPHeaderField: "Content-Type") + + let bodyData = ChatRequest(messages: [.init(role: "system", content: "어렵다"),Message(role: "user", content: "swift언어 설명해줘 ")]) + + guard let body = try? JSONEncoder().encode(bodyData) else { + return nil + } + request.httpBody = body + + return request + + } + + func DecodedData(data: Data?) -> (Result) { + guard + let data = data + else { + return .failure(.dataError) + } + do { + let decodedData = try JSONDecoder().decode(T.self, from: data) + return .success(decodedData) + } catch { + print("Decoding failed with error:", error) + return .failure(.decoderError) + } + } + + func urlDataTaks(completion: @escaping (Result) -> Void) { + guard let request = UrlRequset() else { + completion(.failure(NetworkError.urlError)) + return + } + URLSession.shared.dataTask(with: request) { (data, response, error) in + if error != nil { + completion(.failure(NetworkError.dataError)) + } + guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else { + completion(.failure(NetworkError.invalidResponse)) + return + } + guard let data = data else { + completion(.failure(NetworkError.dataError)) + return + } + completion(.success(data)) + }.resume() + } +} diff --git a/ChatBot/ChatBot/Assets.xcassets/AccentColor.colorset/Contents.json b/ChatBot/ChatBot/Resources/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from ChatBot/ChatBot/Assets.xcassets/AccentColor.colorset/Contents.json rename to ChatBot/ChatBot/Resources/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/ChatBot/ChatBot/Assets.xcassets/AppIcon.appiconset/Contents.json b/ChatBot/ChatBot/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from ChatBot/ChatBot/Assets.xcassets/AppIcon.appiconset/Contents.json rename to ChatBot/ChatBot/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/ChatBot/ChatBot/Assets.xcassets/Contents.json b/ChatBot/ChatBot/Resources/Assets.xcassets/Contents.json similarity index 100% rename from ChatBot/ChatBot/Assets.xcassets/Contents.json rename to ChatBot/ChatBot/Resources/Assets.xcassets/Contents.json diff --git a/ChatBot/ChatBot/Base.lproj/LaunchScreen.storyboard b/ChatBot/ChatBot/Resources/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from ChatBot/ChatBot/Base.lproj/LaunchScreen.storyboard rename to ChatBot/ChatBot/Resources/Base.lproj/LaunchScreen.storyboard diff --git a/ChatBot/ChatBot/Info.plist b/ChatBot/ChatBot/Resources/Info.plist similarity index 90% rename from ChatBot/ChatBot/Info.plist rename to ChatBot/ChatBot/Resources/Info.plist index dd3c9afd..0eb786dc 100644 --- a/ChatBot/ChatBot/Info.plist +++ b/ChatBot/ChatBot/Resources/Info.plist @@ -15,8 +15,6 @@ Default Configuration UISceneDelegateClassName $(PRODUCT_MODULE_NAME).SceneDelegate - UISceneStoryboardFile - Main diff --git a/ChatBot/ChatBot/ViewController.swift b/ChatBot/ChatBot/ViewController.swift deleted file mode 100644 index 2ed5f125..00000000 --- a/ChatBot/ChatBot/ViewController.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// ViewController.swift -// ChatBot -// -// Created by Tacocat on 1/1/24. -// - -import UIKit - -class ViewController: UIViewController { - override func viewDidLoad() { - super.viewDidLoad() - } -}