diff --git a/.gitignore b/.gitignore index 65d29924..4dd74878 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .DS_Store .DS_Store +BoxOffice.xcodeproj/project.xcworkspace/xcuserdata/kimwoohyeon.xcuserdatad/UserInterfaceState.xcuserstate diff --git a/BoxOffice.xcodeproj/project.pbxproj b/BoxOffice.xcodeproj/project.pbxproj index d4142d7f..82a3be95 100644 --- a/BoxOffice.xcodeproj/project.pbxproj +++ b/BoxOffice.xcodeproj/project.pbxproj @@ -7,18 +7,23 @@ objects = { /* Begin PBXBuildFile section */ - 3C3E80152B148FBC002AF4A2 /* MovieDataDecoerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C3E80142B148FBC002AF4A2 /* MovieDataDecoerTests.swift */; }; 3C4D67212B15848900B8926A /* BoxOffice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C4D67202B15848900B8926A /* BoxOffice.swift */; }; 3C6A18D22B18790400E1DBC2 /* Movie.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C6A18D12B18790400E1DBC2 /* Movie.swift */; }; 3C6A18D42B18832E00E1DBC2 /* MovieURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C6A18D32B18832E00E1DBC2 /* MovieURL.swift */; }; + 3C8280862B29AE7C0083DD64 /* BoxOfficeData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C8280852B29AE7C0083DD64 /* BoxOfficeData.swift */; }; + 3CAFE2012B2AE9FC006DF36E /* MovieDetailData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CAFE2002B2AE9FC006DF36E /* MovieDetailData.swift */; }; 3CB861712B21E824003113C1 /* DateGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CB861702B21E824003113C1 /* DateGenerator.swift */; }; + 3CFF21642B28551C006B7A36 /* URLError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CFF21632B28551C006B7A36 /* URLError.swift */; }; + 3CFF21662B285567006B7A36 /* Endpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CFF21652B285567006B7A36 /* Endpoint.swift */; }; + 3CFF21682B28558A006B7A36 /* HTTPHeaderField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CFF21672B28558A006B7A36 /* HTTPHeaderField.swift */; }; + 3CFF216A2B2855A7006B7A36 /* HTTPMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CFF21692B2855A7006B7A36 /* HTTPMethod.swift */; }; 63DF20EF2970E1A0005DF7D1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63DF20EE2970E1A0005DF7D1 /* AppDelegate.swift */; }; 63DF20F12970E1A0005DF7D1 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63DF20F02970E1A0005DF7D1 /* SceneDelegate.swift */; }; 63DF20F32970E1A0005DF7D1 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63DF20F22970E1A0005DF7D1 /* ViewController.swift */; }; 63DF20F62970E1A0005DF7D1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 63DF20F42970E1A0005DF7D1 /* Main.storyboard */; }; 63DF20F82970E1A1005DF7D1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 63DF20F72970E1A1005DF7D1 /* Assets.xcassets */; }; 63DF20FB2970E1A1005DF7D1 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 63DF20F92970E1A1005DF7D1 /* LaunchScreen.storyboard */; }; - 9239D0472B148D400008DE9F /* excuteError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9239D0462B148D400008DE9F /* excuteError.swift */; }; + 9239D0472B148D400008DE9F /* NetworkManagerError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9239D0462B148D400008DE9F /* NetworkManagerError.swift */; }; 926CEE4E2B1C5787002B3FFE /* Key.swift in Sources */ = {isa = PBXBuildFile; fileRef = 926CEE4D2B1C5787002B3FFE /* Key.swift */; }; 92882BDF2B171A7F007AEA40 /* NetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92882BDE2B171A7F007AEA40 /* NetworkManager.swift */; }; 92AC83F82B21C30400D10264 /* API.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92AC83F72B21C30400D10264 /* API.swift */; }; @@ -36,11 +41,16 @@ /* Begin PBXFileReference section */ 3C3E80122B148FBC002AF4A2 /* MovieDataDecoerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MovieDataDecoerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 3C3E80142B148FBC002AF4A2 /* MovieDataDecoerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MovieDataDecoerTests.swift; sourceTree = ""; }; 3C4D67202B15848900B8926A /* BoxOffice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoxOffice.swift; sourceTree = ""; }; 3C6A18D12B18790400E1DBC2 /* Movie.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Movie.swift; sourceTree = ""; }; 3C6A18D32B18832E00E1DBC2 /* MovieURL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MovieURL.swift; sourceTree = ""; }; + 3C8280852B29AE7C0083DD64 /* BoxOfficeData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoxOfficeData.swift; sourceTree = ""; }; + 3CAFE2002B2AE9FC006DF36E /* MovieDetailData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MovieDetailData.swift; sourceTree = ""; }; 3CB861702B21E824003113C1 /* DateGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateGenerator.swift; sourceTree = ""; }; + 3CFF21632B28551C006B7A36 /* URLError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLError.swift; sourceTree = ""; }; + 3CFF21652B285567006B7A36 /* Endpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Endpoint.swift; sourceTree = ""; }; + 3CFF21672B28558A006B7A36 /* HTTPHeaderField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPHeaderField.swift; sourceTree = ""; }; + 3CFF21692B2855A7006B7A36 /* HTTPMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPMethod.swift; sourceTree = ""; }; 63DF20EB2970E1A0005DF7D1 /* BoxOffice.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BoxOffice.app; sourceTree = BUILT_PRODUCTS_DIR; }; 63DF20EE2970E1A0005DF7D1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 63DF20F02970E1A0005DF7D1 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -49,7 +59,7 @@ 63DF20F72970E1A1005DF7D1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 63DF20FA2970E1A1005DF7D1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 63DF20FC2970E1A1005DF7D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 9239D0462B148D400008DE9F /* excuteError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = excuteError.swift; sourceTree = ""; }; + 9239D0462B148D400008DE9F /* NetworkManagerError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkManagerError.swift; sourceTree = ""; }; 926CEE4D2B1C5787002B3FFE /* Key.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Key.swift; sourceTree = ""; }; 92882BDE2B171A7F007AEA40 /* NetworkManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkManager.swift; sourceTree = ""; }; 92AC83F72B21C30400D10264 /* API.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = API.swift; sourceTree = ""; }; @@ -82,22 +92,25 @@ path = Model; sourceTree = ""; }; - 3C3E80132B148FBC002AF4A2 /* MovieDataDecoerTests */ = { + 3C8280842B29AD2A0083DD64 /* HTTP */ = { isa = PBXGroup; children = ( - 3C3E80142B148FBC002AF4A2 /* MovieDataDecoerTests.swift */, + 3CFF21672B28558A006B7A36 /* HTTPHeaderField.swift */, + 3CFF21692B2855A7006B7A36 /* HTTPMethod.swift */, ); - path = MovieDataDecoerTests; + path = HTTP; sourceTree = ""; }; 3CD5DDAD2B171CF30013E5C0 /* Network */ = { isa = PBXGroup; children = ( + 928029CD2B2AEFBA007D604E /* NameSpace */, + 928029CC2B2AEF94007D604E /* Data */, + 3C8280842B29AD2A0083DD64 /* HTTP */, + 3CB861702B21E824003113C1 /* DateGenerator.swift */, 92882BDE2B171A7F007AEA40 /* NetworkManager.swift */, - 3C6A18D32B18832E00E1DBC2 /* MovieURL.swift */, - 926CEE4D2B1C5787002B3FFE /* Key.swift */, + 3CFF21652B285567006B7A36 /* Endpoint.swift */, 92AC83F72B21C30400D10264 /* API.swift */, - 3CB861702B21E824003113C1 /* DateGenerator.swift */, ); path = Network; sourceTree = ""; @@ -105,7 +118,8 @@ 3CD5DDAE2B1722810013E5C0 /* Error */ = { isa = PBXGroup; children = ( - 9239D0462B148D400008DE9F /* excuteError.swift */, + 9239D0462B148D400008DE9F /* NetworkManagerError.swift */, + 3CFF21632B28551C006B7A36 /* URLError.swift */, ); path = Error; sourceTree = ""; @@ -133,7 +147,6 @@ isa = PBXGroup; children = ( 63DF20ED2970E1A0005DF7D1 /* BoxOffice */, - 3C3E80132B148FBC002AF4A2 /* MovieDataDecoerTests */, 63DF20EC2970E1A0005DF7D1 /* Products */, ); sourceTree = ""; @@ -161,6 +174,24 @@ path = BoxOffice; sourceTree = ""; }; + 928029CC2B2AEF94007D604E /* Data */ = { + isa = PBXGroup; + children = ( + 3C8280852B29AE7C0083DD64 /* BoxOfficeData.swift */, + 3CAFE2002B2AE9FC006DF36E /* MovieDetailData.swift */, + ); + path = Data; + sourceTree = ""; + }; + 928029CD2B2AEFBA007D604E /* NameSpace */ = { + isa = PBXGroup; + children = ( + 3C6A18D32B18832E00E1DBC2 /* MovieURL.swift */, + 926CEE4D2B1C5787002B3FFE /* Key.swift */, + ); + path = NameSpace; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -262,7 +293,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 3C3E80152B148FBC002AF4A2 /* MovieDataDecoerTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -271,10 +301,16 @@ buildActionMask = 2147483647; files = ( 3CB861712B21E824003113C1 /* DateGenerator.swift in Sources */, + 3C8280862B29AE7C0083DD64 /* BoxOfficeData.swift in Sources */, 92AC83F82B21C30400D10264 /* API.swift in Sources */, - 9239D0472B148D400008DE9F /* excuteError.swift in Sources */, + 3CFF21642B28551C006B7A36 /* URLError.swift in Sources */, + 3CFF21662B285567006B7A36 /* Endpoint.swift in Sources */, + 9239D0472B148D400008DE9F /* NetworkManagerError.swift in Sources */, 926CEE4E2B1C5787002B3FFE /* Key.swift in Sources */, + 3CAFE2012B2AE9FC006DF36E /* MovieDetailData.swift in Sources */, 3C6A18D42B18832E00E1DBC2 /* MovieURL.swift in Sources */, + 3CFF21682B28558A006B7A36 /* HTTPHeaderField.swift in Sources */, + 3CFF216A2B2855A7006B7A36 /* HTTPMethod.swift in Sources */, 63DF20F32970E1A0005DF7D1 /* ViewController.swift in Sources */, 63DF20EF2970E1A0005DF7D1 /* AppDelegate.swift in Sources */, 92882BDF2B171A7F007AEA40 /* NetworkManager.swift in Sources */, diff --git a/BoxOffice.xcodeproj/project.xcworkspace/xcuserdata/hyunmac.xcuserdatad/UserInterfaceState.xcuserstate b/BoxOffice.xcodeproj/project.xcworkspace/xcuserdata/hyunmac.xcuserdatad/UserInterfaceState.xcuserstate index b0e3aa6a..e6d5aa66 100644 Binary files a/BoxOffice.xcodeproj/project.xcworkspace/xcuserdata/hyunmac.xcuserdatad/UserInterfaceState.xcuserstate and b/BoxOffice.xcodeproj/project.xcworkspace/xcuserdata/hyunmac.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/BoxOffice.xcodeproj/project.xcworkspace/xcuserdata/kimwoohyeon.xcuserdatad/UserInterfaceState.xcuserstate b/BoxOffice.xcodeproj/project.xcworkspace/xcuserdata/kimwoohyeon.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index f79cd39d..00000000 Binary files a/BoxOffice.xcodeproj/project.xcworkspace/xcuserdata/kimwoohyeon.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ diff --git a/BoxOffice/Controllers/ViewController.swift b/BoxOffice/Controllers/ViewController.swift index 12586a7b..5bada031 100644 --- a/BoxOffice/Controllers/ViewController.swift +++ b/BoxOffice/Controllers/ViewController.swift @@ -8,59 +8,24 @@ import UIKit class ViewController: UIViewController { - - private var networkManager = NetworkManager() + private let data = BoxOfficeData() + private let detail = MovieDetailData(value: "20190324") override func viewDidLoad() { super.viewDidLoad() - networkTest() + boxOfiiceData() + movieDetailData() } - func networkTest() { - let dailyBoxOfficeAPI = API(schema: MovieURL.schema, host: MovieURL.movieHost, path: MovieURL.boxofficePath) - - let dailyBoxOfficeAPIAdditionalQueryItems: [URLQueryItem] = [ - URLQueryItem(name: "targetDt", value: DateGenerator.fetchTodayDate()) - ] - - let apiKey = Key.movieDataApiKey - - var movieCode = "" - - let group = DispatchGroup() - - group.enter() - networkManager.executeRequest(api: dailyBoxOfficeAPI, apiKey: apiKey, queryItems: dailyBoxOfficeAPIAdditionalQueryItems, type: BoxOffice.self, complitionHandler: { result in - defer {group.leave()} - - switch result { - case .success(let safeData): - let data = safeData.boxOfficeResult.dailyBoxOfficeList - data.forEach {dump($0)} - movieCode = data[0].movieCode - case .failure(let error): - print("\(error)에러발생") - } - }) - - - group.notify(queue: .main) { - let movieDetailAPI = API(schema: MovieURL.schema, host: MovieURL.movieHost, path: MovieURL.movieDetailPath) - - let movieDetailAPIAdditionalQueryItems: [URLQueryItem] = [ - URLQueryItem(name: "movieCd", value: movieCode) - ] - - self.networkManager.executeRequest(api: movieDetailAPI, apiKey: apiKey, queryItems: movieDetailAPIAdditionalQueryItems, type: Movie.self) { result in - switch result { - case .success(let safeData): - let data = safeData.infomationResult.movieInfomation - print(data) - - case .failure(let error): - print("\(error)에러발생") - } - } + private func boxOfiiceData() { + data.getBoxOfficeData { result in + result.forEach { dump($0) } + } + } + + private func movieDetailData() { + detail.getMovieDetailData { movie in + dump(movie) } } } diff --git a/BoxOffice/Error/excuteError.swift b/BoxOffice/Error/NetworkManagerError.swift similarity index 73% rename from BoxOffice/Error/excuteError.swift rename to BoxOffice/Error/NetworkManagerError.swift index 860790a3..0b876772 100644 --- a/BoxOffice/Error/excuteError.swift +++ b/BoxOffice/Error/NetworkManagerError.swift @@ -1,5 +1,5 @@ // -// DecodingError.swift +// NetworkManagerError.swift // BoxOffice // // Created by Toy, Morgan on 11/27/23. @@ -7,19 +7,16 @@ import Foundation -enum ExecuteRequestError: Error { - case invalidURL +enum NetworkManagerError: Error { case urlSessionError case responseError case invalidData case decodeError } -extension ExecuteRequestError: LocalizedError { +extension NetworkManagerError: LocalizedError { var errorDescription: String? { switch self { - case .invalidURL: - return "유효하지 않은 URL" case .urlSessionError: return "URLSession에 대한" case .responseError: diff --git a/BoxOffice/Error/URLError.swift b/BoxOffice/Error/URLError.swift new file mode 100644 index 00000000..545ee56a --- /dev/null +++ b/BoxOffice/Error/URLError.swift @@ -0,0 +1,21 @@ +// +// URLError.swift +// BoxOffice +// +// Created by Toy, Morgan on 12/12/23. +// + +import Foundation + +enum URLError: Error { + case invalidURL +} + +extension URLError: LocalizedError { + var errorDescription: String? { + switch self { + case .invalidURL: + return "유효하지 않은 URL" + } + } +} diff --git a/BoxOffice/Network/API.swift b/BoxOffice/Network/API.swift index 1b0d052a..a3de293b 100644 --- a/BoxOffice/Network/API.swift +++ b/BoxOffice/Network/API.swift @@ -2,15 +2,15 @@ // API.swift // BoxOffice // -// Created by hyunMac on 12/7/23. +// Created by Toy, Morgan on 12/7/23. // import Foundation struct API { - let schema: String - let host: String - let path: String + private let schema: String + private let host: String + private let path: String init(schema: String, host: String, path: String) { self.schema = schema diff --git a/BoxOffice/Network/Data/BoxOfficeData.swift b/BoxOffice/Network/Data/BoxOfficeData.swift new file mode 100644 index 00000000..7ef3edcd --- /dev/null +++ b/BoxOffice/Network/Data/BoxOfficeData.swift @@ -0,0 +1,30 @@ +// +// DataManager.swift +// BoxOffice +// +// Created by Toy, Morgan on 12/13/23. +// + +import Foundation + +struct BoxOfficeData { + private let networkManager = NetworkManager() + private let boxofficeAPI = API(schema: MovieURL.schema, host: MovieURL.movieHost, path: MovieURL.boxofficePath) + private let boxOfficeAPIAdditionalQueryItems = [ URLQueryItem(name: "targetDt", value: DateGenerator.fetchTodayDate()) ] + + private var getEndpoint: Endpoint { + Endpoint(api: boxofficeAPI, queryItems: boxOfficeAPIAdditionalQueryItems, httpMethod: .get, httpHeaderField: .contentType) + } + + func getBoxOfficeData(complitionHandler: @escaping ([DailyBoxOfficeItem]) -> Void) { + networkManager.executeRequest(endponit: getEndpoint, type: BoxOffice.self) { result in + switch result { + case .success(let safeData): + let data = safeData.boxOfficeResult.dailyBoxOfficeList + complitionHandler(data) + case .failure(let error): + print("\(error)에러발생") + } + } + } +} diff --git a/BoxOffice/Network/Data/MovieDetailData.swift b/BoxOffice/Network/Data/MovieDetailData.swift new file mode 100644 index 00000000..99e4c6ec --- /dev/null +++ b/BoxOffice/Network/Data/MovieDetailData.swift @@ -0,0 +1,43 @@ +// +// MovieDetailData.swift +// BoxOffice +// +// Created by Toy, Morgan on 12/14/23. +// + +import Foundation + +//endpoint +// +//api: API, +//queryItems:[URLQueryItem], +//var request = URLRequest(url: url) +//request.httpMethod = "GET" +//request.addValue("application/json", forHTTPHeaderField: "Content-Type") +//json + +struct MovieDetailData { + private let networkManager = NetworkManager() + private let movieDetailAPI = API(schema: MovieURL.schema, host: MovieURL.movieHost, path: MovieURL.movieDetailPath) + private var movieDetailAPIAdditionalQueryItems: [URLQueryItem] + + private var getEndpoint: Endpoint { + Endpoint(api: movieDetailAPI, queryItems: movieDetailAPIAdditionalQueryItems, httpMethod: .get, httpHeaderField: .contentType) + } + + init(value: String) { + movieDetailAPIAdditionalQueryItems = [ URLQueryItem(name: "movieCd", value: value) ] + } + + func getMovieDetailData(complitionHandler: @escaping (MovieInfomation) -> Void) { + networkManager.executeRequest(endponit: getEndpoint, type: Movie.self) { result in + switch result { + case .success(let safeData): + let data = safeData.infomationResult.movieInfomation + complitionHandler(data) + case .failure(let error): + print("\(error)에러발생") + } + } + } +} diff --git a/BoxOffice/Network/DateGenerator.swift b/BoxOffice/Network/DateGenerator.swift index 37abcef1..1fe2e301 100644 --- a/BoxOffice/Network/DateGenerator.swift +++ b/BoxOffice/Network/DateGenerator.swift @@ -2,7 +2,7 @@ // DateGenerator.swift // BoxOffice // -// Created by on 12/7/23. +// Created by Toy, Morgan on 12/7/23. // import Foundation diff --git a/BoxOffice/Network/Endpoint.swift b/BoxOffice/Network/Endpoint.swift new file mode 100644 index 00000000..9d90f33f --- /dev/null +++ b/BoxOffice/Network/Endpoint.swift @@ -0,0 +1,44 @@ +// +// Endpoint.swift +// BoxOffice +// +// Created by Toy, Morgan on 12/12/23. +// +import Foundation + +struct Endpoint { + private let api: API + private let queryItems:[URLQueryItem] + private let httpMethod: HTTPMethod + private let httpHeaderField: HTTPHeaderField + private let mime: MIME + + init(api: API, queryItems: [URLQueryItem], httpMethod: HTTPMethod, httpHeaderField: HTTPHeaderField, mime: MIME = MIME.json) { + self.api = api + self.queryItems = queryItems + self.httpMethod = httpMethod + self.httpHeaderField = httpHeaderField + self.mime = mime + } + + func asURLGetRequest() throws -> URLRequest { + guard let url = api.getURL(apikey: Key.movieDataApiKey, queryItems: queryItems) else { throw URLError.invalidURL } + + var request = URLRequest(url: url) + request.httpMethod = httpMethod.rawValue + request.addValue(mime.rawValue, forHTTPHeaderField: httpHeaderField.rawValue) + + return request + } + + func asURLPostRequest(data: Data) throws -> URLRequest { + guard let url = api.getURL(apikey: Key.movieDataApiKey, queryItems: queryItems) else { throw URLError.invalidURL } + + var request = URLRequest(url: url) + request.httpMethod = httpMethod.rawValue + request.addValue(mime.rawValue, forHTTPHeaderField: httpHeaderField.rawValue) + request.httpBody = data + + return request + } +} diff --git a/BoxOffice/Network/HTTP/HTTPHeaderField.swift b/BoxOffice/Network/HTTP/HTTPHeaderField.swift new file mode 100644 index 00000000..58e1dda0 --- /dev/null +++ b/BoxOffice/Network/HTTP/HTTPHeaderField.swift @@ -0,0 +1,19 @@ +// +// HTTPHeaderField.swift +// BoxOffice +// +// Created by Toy, Morgan on 12/12/23. +// +enum HTTPHeaderField: String { + case contentType = "Content-Type" + case contentEncoding = "Content-Encoding" + case contentLanguage = "Content-Language" +} + +enum MIME: String { + case html = "text/html" + case json = "application/json" + case iamgeGif = "image/gif" + case imageJpeg = "image/jpeg" + case gzip = "application/gzip" +} diff --git a/BoxOffice/Network/HTTP/HTTPMethod.swift b/BoxOffice/Network/HTTP/HTTPMethod.swift new file mode 100644 index 00000000..015fc49b --- /dev/null +++ b/BoxOffice/Network/HTTP/HTTPMethod.swift @@ -0,0 +1,12 @@ +// +// HTTPMethod.swift +// BoxOffice +// +// Created by Toy, Morgan on 12/12/23. +// +enum HTTPMethod: String { + case get = "GET" + case post = "POST" + case put = "PUT" + case delete = "DELETE" +} diff --git a/BoxOffice/Network/Key.swift b/BoxOffice/Network/NameSpace/Key.swift similarity index 100% rename from BoxOffice/Network/Key.swift rename to BoxOffice/Network/NameSpace/Key.swift diff --git a/BoxOffice/Network/MovieURL.swift b/BoxOffice/Network/NameSpace/MovieURL.swift similarity index 100% rename from BoxOffice/Network/MovieURL.swift rename to BoxOffice/Network/NameSpace/MovieURL.swift diff --git a/BoxOffice/Network/NetworkManager.swift b/BoxOffice/Network/NetworkManager.swift index 33433afb..ee7abc0f 100644 --- a/BoxOffice/Network/NetworkManager.swift +++ b/BoxOffice/Network/NetworkManager.swift @@ -8,40 +8,63 @@ import Foundation struct NetworkManager { - func executeRequest(api: API, apiKey: String, queryItems:[URLQueryItem], type: T.Type, complitionHandler: @escaping (Result) -> Void) { - - guard let url = api.getURL(apikey: apiKey, queryItems: queryItems) else { - complitionHandler(.failure(ExecuteRequestError.invalidURL)) - return - } - - var request = URLRequest(url: url) - request.httpMethod = "GET" - request.addValue("application/json", forHTTPHeaderField: "Content-Type") + func executeRequest(endponit: Endpoint, type: T.Type, complitionHandler: @escaping (Result) -> Void) { + guard let request = try? endponit.asURLGetRequest() else { return } let task = URLSession.shared.dataTask(with: request) { (data, response, error) in guard error == nil else { - complitionHandler(.failure(ExecuteRequestError.urlSessionError)) + complitionHandler(.failure(NetworkManagerError.urlSessionError)) return } guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else { - complitionHandler(.failure(ExecuteRequestError.responseError)) + complitionHandler(.failure(NetworkManagerError.responseError)) return } guard let data = data else { - complitionHandler(.failure(ExecuteRequestError.invalidData)) + complitionHandler(.failure(NetworkManagerError.invalidData)) return } do { let decoder = JSONDecoder() - let safeData = try decoder.decode(T.self, from: data) + let safeData = try decoder.decode(type.self, from: data) complitionHandler(.success(safeData)) } catch { - complitionHandler(.failure(ExecuteRequestError.decodeError)) + complitionHandler(.failure(NetworkManagerError.decodeError)) + } + } + task.resume() + } + + func sendRequest(endponit: Endpoint, value: T, complitionHandler: @escaping (Result) -> Void) { + let encoder = JSONEncoder() + + guard let jsonData = try? encoder.encode(value), let request = try? endponit.asURLPostRequest(data: jsonData) else { return } + + let task = URLSession.shared.dataTask(with: request) { (data, response, error) in + guard error == nil else { + complitionHandler(.failure(NetworkManagerError.urlSessionError)) + return } + + guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else { + complitionHandler(.failure(NetworkManagerError.responseError)) + return + } + + guard let data = data else { + complitionHandler(.failure(NetworkManagerError.invalidData)) + return + } + + guard let successData = data as? T else { + complitionHandler(.failure(NetworkManagerError.invalidData)) + return + } + + complitionHandler(.success(successData)) } task.resume() } diff --git a/MovieDataDecoerTests/MovieDataDecoerTests.swift b/MovieDataDecoerTests/MovieDataDecoerTests.swift deleted file mode 100644 index 0ccce9a3..00000000 --- a/MovieDataDecoerTests/MovieDataDecoerTests.swift +++ /dev/null @@ -1,45 +0,0 @@ -// -// MovieDataDecoerTests.swift -// MovieDataDecoerTests -// -// Created by Morgan, Toy on 11/27/23. -// - -//import XCTest -//@testable import BoxOffice -// -//final class MovieDataDecoerTests: XCTestCase { -// private var sut: BoxOffice! -// -// override func setUpWithError() throws { -// try super.setUpWithError() -// sut = try DataDecoder.decodeAssetData(assetName: "box_office_sample", decoder: JSONDecoder()) -// } -// -// override func tearDownWithError() throws { -// try super.tearDownWithError() -// sut = nil -// } -// -// func test_box_office_sample_디코딩후_boxofficeType은_일별_박스오피스를_반환한다() { -// // given -// let result = sut.boxOfficeResult.boxOfficeType -// print(result) -// // when -// let boxofficeType = "일별 박스오피스" -// -// // then -// XCTAssertEqual(result, boxofficeType) -// } -// -// func test_box_office_sample_디코딩후_dailyBoxOfficeList의_0번째요소의_movieName가_경관의_피_를반환한다() { -// // given -// let result = sut.boxOfficeResult.dailyBoxOfficeList[0].movieName -// -// // when -// let movieName = "경관의 피" -// -// // then -// XCTAssertEqual(result, movieName) -// } -//}