From 928c7434e13bea6f52e8db51a3829e042979c934 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Sat, 20 Jul 2024 21:35:25 +0900 Subject: [PATCH 01/12] =?UTF-8?q?Feat:=20AddRecipeInteractor=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Interactor/AddRecipeInteractor.swift | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 HomeCafeRecipes/HomeCafeRecipes/Domain/Interactor/AddRecipeInteractor.swift diff --git a/HomeCafeRecipes/HomeCafeRecipes/Domain/Interactor/AddRecipeInteractor.swift b/HomeCafeRecipes/HomeCafeRecipes/Domain/Interactor/AddRecipeInteractor.swift new file mode 100644 index 0000000..8f84cc3 --- /dev/null +++ b/HomeCafeRecipes/HomeCafeRecipes/Domain/Interactor/AddRecipeInteractor.swift @@ -0,0 +1,69 @@ +// +// AddRecipeInteractor.swift +// HomeCafeRecipes +// +// Created by 김건호 on 7/1/24. +// + +import Foundation +import UIKit + +import RxSwift + +protocol AddRecipeInteractorDelegate: AnyObject { + func didLoadRecipeData(viewModel: AddRecipeViewModel) +} + +protocol AddRecipeInteractor { + func saveRecipe(userID: Int, recipeType: RecipeType) -> Single> + func updateRecipeTitle(_ title: String) + func updateRecipeDescription(_ description: String) + func addRecipeImage(_ image: UIImage) + func removeRecipeImage(at index: Int) + func loadRecipeData() +} + +class AddRecipeInteractorImpl: AddRecipeInteractor { + private var recipeImages: [UIImage] = [] + private var recipeTitle: String = "" + private var recipeDescription: String = "" + + weak var delegate: AddRecipeInteractorDelegate? + + private let saveRecipeUseCase: AddRecipeUseCase + + init(saveRecipeUseCase: AddRecipeUseCase) { + self.saveRecipeUseCase = saveRecipeUseCase + } + + func saveRecipe(userID: Int, recipeType: RecipeType) -> Single> { + return saveRecipeUseCase.execute( + userID: userID, + recipeType: recipeType.rawValue, + title: recipeTitle, + description: recipeDescription, + images: recipeImages + ) + } + + func updateRecipeTitle(_ title: String) { + self.recipeTitle = title + } + + func updateRecipeDescription(_ description: String) { + self.recipeDescription = description + } + + func addRecipeImage(_ image: UIImage) { + self.recipeImages.append(image) + } + + func removeRecipeImage(at index: Int) { + self.recipeImages.remove(at: index) + } + + func loadRecipeData() { + let viewModel = AddRecipeViewModel(images: recipeImages, title: recipeTitle, description: recipeDescription) + delegate?.didLoadRecipeData(viewModel: viewModel) + } +} From ac56a829ddc4c0dfaa672ed22efa52abe126a883 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Sat, 20 Jul 2024 21:35:42 +0900 Subject: [PATCH 02/12] =?UTF-8?q?Feat:=20AddRecipeUseCase=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Domain/UseCases/AddRecipeUseCase.swift | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 HomeCafeRecipes/HomeCafeRecipes/Domain/UseCases/AddRecipeUseCase.swift diff --git a/HomeCafeRecipes/HomeCafeRecipes/Domain/UseCases/AddRecipeUseCase.swift b/HomeCafeRecipes/HomeCafeRecipes/Domain/UseCases/AddRecipeUseCase.swift new file mode 100644 index 0000000..23eb44a --- /dev/null +++ b/HomeCafeRecipes/HomeCafeRecipes/Domain/UseCases/AddRecipeUseCase.swift @@ -0,0 +1,59 @@ +// +// SaveRecipeUseCase.swift +// HomeCafeRecipes +// +// Created by 김건호 on 7/1/24. +// + +import UIKit + +import RxSwift + +protocol AddRecipeUseCase { + func execute( + userID: Int, + recipeType: String, + title: String, + description: String, + images: [UIImage] + ) -> Single> +} + +class AddRecipeUseCaseImpl: AddRecipeUseCase { + private let repository: AddRecipeRepository + + init(repository: AddRecipeRepository) { + self.repository = repository + } + + func execute( + userID: Int, + recipeType: String, + title: String, + description: String, + images: [UIImage] + ) -> Single> { + + guard !images.isEmpty else { + return .just(.failure(.noImages)) + } + + guard !title.isBlank else { + return .just(.failure(.titleIsEmpty)) + } + + guard description.count > 10 else { + return .just(.failure(.descriptionTooShort)) + } + + return repository.saveRecipe( + userID: userID, + recipeType: recipeType, + title: title, + description: description, + images: images + ) + .map { .success($0) } + .catch { .just(.failure(.genericError($0))) } + } +} From 13864c0e507fa00dd628decb72ecd0648a2be75b Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Sat, 20 Jul 2024 21:41:22 +0900 Subject: [PATCH 03/12] =?UTF-8?q?Feat:=20NetworkService=EC=9D=98=20postReq?= =?UTF-8?q?uest=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Data/Network/NetworkService.swift | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Data/Network/NetworkService.swift b/HomeCafeRecipes/HomeCafeRecipes/Data/Network/NetworkService.swift index 0e17774..ec7ce2e 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Data/Network/NetworkService.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Data/Network/NetworkService.swift @@ -6,10 +6,13 @@ // import Foundation +import UIKit + import RxSwift protocol NetworkService { func getRequest(url: URL, responseType: T.Type) -> Single + func postRequest(url: URL, parameters: [String: Any], imageDatas: [Data], responseType: T.Type) -> Single } class BaseNetworkService: NetworkService { @@ -39,4 +42,61 @@ class BaseNetworkService: NetworkService { } } } + + func postRequest( + url: URL, parameters: [String: Any], + imageDatas: [Data], + responseType: T.Type + ) + -> Single { + return Single.create { single in + var formDataRequest = MultipartFormDataRequest(url: url) + + for (key, value) in parameters { + formDataRequest.addTextField(named: key, value: String(describing: value)) + } + + for (index, imageData) in imageDatas.enumerated() { + let filename = "image\(index).jpg" + formDataRequest.addDataField( + named: "recipeImgUrls", + data: imageData, + filename: filename, + mimeType: "image/jpeg" + ) + } + + formDataRequest.finalize() + let request = formDataRequest.asURLRequest() + + let task = URLSession.shared.dataTask(with: request) { data, response, error in + if let error = error { + single(.failure(error)) + } else if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode != 200 { + let statusCode = httpResponse.statusCode + let responseString = data.flatMap { String(data: $0, encoding: .utf8) } ?? "No response data" + let error = NSError( + domain: "", + code: statusCode, + userInfo: [NSLocalizedDescriptionKey: "HTTP \(statusCode): \(responseString)"] + ) + single(.failure(error)) + } else if let data = data { + do { + let decoder = JSONDecoder() + decoder.dateDecodingStrategy = .iso8601 + let responseObject = try decoder.decode(T.self, from: data) + single(.success(responseObject)) + } catch let decodingError { + single(.failure(decodingError)) + } + } + } + task.resume() + + return Disposables.create { + task.cancel() + } + } + } } From 74c02066d7eb867532e41776bbfccaeefc75f3ee Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Sat, 20 Jul 2024 21:42:43 +0900 Subject: [PATCH 04/12] =?UTF-8?q?Feat:=20AddRecipeRepository=EC=A0=95?= =?UTF-8?q?=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repositories/AddRecipeRepository.swift | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 HomeCafeRecipes/HomeCafeRecipes/Data/Repositories/AddRecipeRepository.swift diff --git a/HomeCafeRecipes/HomeCafeRecipes/Data/Repositories/AddRecipeRepository.swift b/HomeCafeRecipes/HomeCafeRecipes/Data/Repositories/AddRecipeRepository.swift new file mode 100644 index 0000000..d76357b --- /dev/null +++ b/HomeCafeRecipes/HomeCafeRecipes/Data/Repositories/AddRecipeRepository.swift @@ -0,0 +1,45 @@ +// +// AddRecipeRepository.swift +// HomeCafeRecipes +// +// Created by 김건호 on 7/1/24. +// + +import Foundation +import UIKit + +import RxSwift + +protocol AddRecipeRepository { + func saveRecipe( + userID: Int, + recipeType: String, + title: String, + description: String, + images: [UIImage] + ) -> Single +} + +class AddRecipeRepositoryImpl: AddRecipeRepository { + private let recipePostService: RecipePostService + + init(recipePostService: RecipePostService) { + self.recipePostService = recipePostService + } + + func saveRecipe( + userID: Int, + recipeType: String, + title: String, + description: String, + images: [UIImage] + ) -> Single { + let recipeUploadDTO = RecipeUploadDTO( + userID: userID, + recipeType: recipeType, + recipeName: title, + recipeDescription: description + ) + return recipePostService.postRecipe(recipe: recipeUploadDTO, images: images) + } +} From afd9f0bb88312fcd209d0306959f147468aa6ec6 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Sat, 20 Jul 2024 21:45:38 +0900 Subject: [PATCH 05/12] =?UTF-8?q?Feat:=20RecipeUploadDTO=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Data/Network/DTO/RecipeUploadDTO.swift | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 HomeCafeRecipes/HomeCafeRecipes/Data/Network/DTO/RecipeUploadDTO.swift diff --git a/HomeCafeRecipes/HomeCafeRecipes/Data/Network/DTO/RecipeUploadDTO.swift b/HomeCafeRecipes/HomeCafeRecipes/Data/Network/DTO/RecipeUploadDTO.swift new file mode 100644 index 0000000..3fb0e4a --- /dev/null +++ b/HomeCafeRecipes/HomeCafeRecipes/Data/Network/DTO/RecipeUploadDTO.swift @@ -0,0 +1,15 @@ +// +// RecipeUploadDTO.swift +// HomeCafeRecipes +// +// Created by 김건호 on 7/1/24. +// + +import Foundation + +struct RecipeUploadDTO { + let userID: Int + let recipeType: String + let recipeName: String + let recipeDescription: String +} From d7677a19b2f09cf5b2fc62bf4e52ee7694007521 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Sat, 20 Jul 2024 21:45:51 +0900 Subject: [PATCH 06/12] =?UTF-8?q?Feat:=20RecipeUploadResponseDTO=20?= =?UTF-8?q?=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Network/DTO/RecipeUploadResponseDTO.swift | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 HomeCafeRecipes/HomeCafeRecipes/Data/Network/DTO/RecipeUploadResponseDTO.swift diff --git a/HomeCafeRecipes/HomeCafeRecipes/Data/Network/DTO/RecipeUploadResponseDTO.swift b/HomeCafeRecipes/HomeCafeRecipes/Data/Network/DTO/RecipeUploadResponseDTO.swift new file mode 100644 index 0000000..bbfc8c6 --- /dev/null +++ b/HomeCafeRecipes/HomeCafeRecipes/Data/Network/DTO/RecipeUploadResponseDTO.swift @@ -0,0 +1,50 @@ +// +// RecipeUploadResponseDTO.swift +// HomeCafeRecipes +// +// Created by 김건호 on 7/2/24. +// + +import Foundation + +struct RecipeUploadResponseDTO: Decodable { + + let ID: Int + let type: String + let name: String + let description: String + let likesCount: Int + let createdAt: String + let writer: UserDTO + let imageUrls: [RecipeImageDTO] + let isLikedByCurrentUser: Bool + + enum CodingKeys: String, CodingKey { + case ID = "recipeId" + case type = "recipeType" + case name = "recipeName" + case description = "recipeDescription" + case likesCount = "recipeLikesCnt" + case createdAt = "createdAt" + case writer = "writer" + case imageUrls = "recipeImgUrls" + case isLikedByCurrentUser = "isLiked" + } + +} + +extension RecipeUploadResponseDTO { + func toDomain() -> Recipe { + return Recipe( + id: ID, + type: RecipeType(rawValue: type) ?? .coffee, + name: name, + description: description, + writer: writer.toDomain(), + imageUrls: imageUrls.map { $0.recipeImageUrl }, + isLikedByCurrentUser: isLikedByCurrentUser, + likeCount: likesCount, + createdAt: DateFormatter.iso8601.date(from: createdAt) ?? Date() + ) + } +} From 838777ba394ced438e99b9d72f327be7f12f392d Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Sat, 20 Jul 2024 21:46:36 +0900 Subject: [PATCH 07/12] =?UTF-8?q?Feat:=20MultipartFormDataRequest=20?= =?UTF-8?q?=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Network/MultipartFormDataRequest.swift | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 HomeCafeRecipes/HomeCafeRecipes/Data/Network/MultipartFormDataRequest.swift diff --git a/HomeCafeRecipes/HomeCafeRecipes/Data/Network/MultipartFormDataRequest.swift b/HomeCafeRecipes/HomeCafeRecipes/Data/Network/MultipartFormDataRequest.swift new file mode 100644 index 0000000..93004a9 --- /dev/null +++ b/HomeCafeRecipes/HomeCafeRecipes/Data/Network/MultipartFormDataRequest.swift @@ -0,0 +1,60 @@ +// +// MultipartFormDataRequest.swift +// HomeCafeRecipes +// +// Created by 김건호 on 7/16/24. +// + +import Foundation + +struct MultipartFormDataRequest { + private let boundary: String = UUID().uuidString + private var httpBody = NSMutableData() + let url: URL + + init(url: URL) { + self.url = url + } + + mutating func addTextField(named name: String, value: String) { + httpBody.append(textFormField(named: name, value: value).data(using: .utf8)!) + } + + private func textFormField(named name: String, value: String) -> String { + var fieldString = "--\(boundary)\r\n" + fieldString += "Content-Disposition: form-data; name=\"\(name)\"\r\n" + fieldString += "\r\n" + fieldString += "\(value)\r\n" + + return fieldString + } + + mutating func addDataField(named name: String, data: Data, filename: String, mimeType: String) { + httpBody.append(dataFormField(named: name, data: data, filename: filename, mimeType: mimeType)) + } + + private func dataFormField(named name: String, data: Data, filename: String, mimeType: String) -> Data { + let fieldData = NSMutableData() + + fieldData.append("--\(boundary)\r\n".data(using: .utf8)!) + fieldData.append("Content-Disposition: form-data; name=\"\(name)\"; filename=\"\(filename)\"\r\n".data(using: .utf8)!) + fieldData.append("Content-Type: \(mimeType)\r\n".data(using: .utf8)!) + fieldData.append("\r\n".data(using: .utf8)!) + fieldData.append(data) + fieldData.append("\r\n".data(using: .utf8)!) + + return fieldData as Data + } + + mutating func finalize() { + httpBody.append("--\(boundary)--\r\n".data(using: .utf8)!) + } + + func asURLRequest() -> URLRequest { + var request = URLRequest(url: url) + request.httpMethod = "POST" + request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") + request.httpBody = httpBody as Data + return request + } +} From b1276adacf7d57f4f9e13f6c2f63e0a7aaf12a7a Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Sat, 20 Jul 2024 21:50:13 +0900 Subject: [PATCH 08/12] =?UTF-8?q?Feat:=20RecipePostService=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Data/Network/RecipePostService.swift | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 HomeCafeRecipes/HomeCafeRecipes/Data/Network/RecipePostService.swift diff --git a/HomeCafeRecipes/HomeCafeRecipes/Data/Network/RecipePostService.swift b/HomeCafeRecipes/HomeCafeRecipes/Data/Network/RecipePostService.swift new file mode 100644 index 0000000..596fef7 --- /dev/null +++ b/HomeCafeRecipes/HomeCafeRecipes/Data/Network/RecipePostService.swift @@ -0,0 +1,47 @@ +// +// RecipePostService.swift +// HomeCafeRecipes +// +// Created by 김건호 on 7/1/24. +// + +import Foundation +import UIKit + +import RxSwift + +protocol RecipePostService { + func postRecipe(recipe: RecipeUploadDTO, images: [UIImage]) -> Single +} + +class RecipePostServiceImpl: RecipePostService { + private let networkService: NetworkService + + init(networkService: NetworkService) { + self.networkService = networkService + } + + private func makeURL(endpoint: String) -> URL { + return APIConfig().baseURL.appendingPathComponent(endpoint) + } + + func postRecipe(recipe: RecipeUploadDTO, images: [UIImage]) -> Single { + let url = makeURL(endpoint: "recipes") + let parameters: [String: Any] = [ + "userId": recipe.userID, + "recipeType": recipe.recipeType, + "recipeName": recipe.recipeName, + "recipeDescription": recipe.recipeDescription + ] + + let imageDatas = images.compactMap { $0.jpegData(compressionQuality: 0.5) } + + return networkService.postRequest( + url: url, + parameters: parameters, + imageDatas: imageDatas, + responseType: NetworkResponseDTO.self + ) + .map { $0.data.toDomain() } + } +} From e95db9011b8362718e2844eece36c22151cb6c3b Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Sat, 20 Jul 2024 21:59:39 +0900 Subject: [PATCH 09/12] =?UTF-8?q?Feat:=20AddRecipeError=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HomeCafeRecipes.xcodeproj/project.pbxproj | 524 ++++++++---------- .../Domain/Entities/AddRecipeError.swift | 44 ++ 2 files changed, 287 insertions(+), 281 deletions(-) create mode 100644 HomeCafeRecipes/HomeCafeRecipes/Domain/Entities/AddRecipeError.swift diff --git a/HomeCafeRecipes/HomeCafeRecipes.xcodeproj/project.pbxproj b/HomeCafeRecipes/HomeCafeRecipes.xcodeproj/project.pbxproj index 2eefc42..cd4d60f 100644 --- a/HomeCafeRecipes/HomeCafeRecipes.xcodeproj/project.pbxproj +++ b/HomeCafeRecipes/HomeCafeRecipes.xcodeproj/project.pbxproj @@ -16,68 +16,78 @@ 1D1283B42C16983900C5A870 /* RxSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 1D1283B32C16983900C5A870 /* RxSwift */; }; 1D1283B62C16984E00C5A870 /* RxCocoa in Frameworks */ = {isa = PBXBuildFile; productRef = 1D1283B52C16984E00C5A870 /* RxCocoa */; }; 1D1283CA2C16D9C600C5A870 /* RecipeFetchService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D1283C92C16D9C600C5A870 /* RecipeFetchService.swift */; }; + 1D166D852C4BD58300A50963 /* RecipeListRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166D832C4BD58300A50963 /* RecipeListRouter.swift */; }; + 1D166D862C4BD58300A50963 /* Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166D842C4BD58300A50963 /* Router.swift */; }; + 1D166D892C4BD59500A50963 /* DateFormatter+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166D882C4BD59500A50963 /* DateFormatter+Extensions.swift */; }; + 1D166D902C4BD5A400A50963 /* SelectImageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166D8B2C4BD5A400A50963 /* SelectImageCell.swift */; }; + 1D166D912C4BD5A400A50963 /* AddRecipeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166D8C2C4BD5A400A50963 /* AddRecipeViewController.swift */; }; + 1D166D922C4BD5A400A50963 /* RecipeUploadImgaeCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166D8D2C4BD5A400A50963 /* RecipeUploadImgaeCell.swift */; }; + 1D166D932C4BD5A400A50963 /* AddRecipeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166D8E2C4BD5A400A50963 /* AddRecipeView.swift */; }; + 1D166D942C4BD5A400A50963 /* AddRecipeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166D8F2C4BD5A400A50963 /* AddRecipeViewModel.swift */; }; + 1D166D982C4BD5CD00A50963 /* RecipeListItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166D972C4BD5CD00A50963 /* RecipeListItemViewModel.swift */; }; + 1D166D9A2C4BD5EF00A50963 /* AddRecipeInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166D992C4BD5EF00A50963 /* AddRecipeInteractor.swift */; }; + 1D166D9C2C4BD5F800A50963 /* AddRecipeUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166D9B2C4BD5F800A50963 /* AddRecipeUseCase.swift */; }; + 1D166D9F2C4BD66C00A50963 /* CGSize+addButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166D9D2C4BD66C00A50963 /* CGSize+addButton.swift */; }; + 1D166DA02C4BD66C00A50963 /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166D9E2C4BD66C00A50963 /* UIView+Extensions.swift */; }; + 1D166DA32C4BD69200A50963 /* Comment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166DA12C4BD69200A50963 /* Comment.swift */; }; + 1D166DA42C4BD69200A50963 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166DA22C4BD69200A50963 /* User.swift */; }; + 1D166DA62C4BD69800A50963 /* AddRecipeError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166DA52C4BD69800A50963 /* AddRecipeError.swift */; }; + 1D166DA82C4BD6AF00A50963 /* AddRecipeRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166DA72C4BD6AF00A50963 /* AddRecipeRepository.swift */; }; + 1D166DAA2C4BD6B800A50963 /* MultipartFormDataRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166DA92C4BD6B800A50963 /* MultipartFormDataRequest.swift */; }; + 1D166DAC2C4BD6CD00A50963 /* RecipePostService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166DAB2C4BD6CD00A50963 /* RecipePostService.swift */; }; + 1D166DAE2C4BD6DB00A50963 /* ErrorResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166DAD2C4BD6DB00A50963 /* ErrorResponseDTO.swift */; }; + 1D166DB12C4BD6EA00A50963 /* RecipeUploadDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166DAF2C4BD6EA00A50963 /* RecipeUploadDTO.swift */; }; + 1D166DB22C4BD6EA00A50963 /* RecipeUploadResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166DB02C4BD6EA00A50963 /* RecipeUploadResponseDTO.swift */; }; + 1D166DB42C4BD70600A50963 /* RecipeUploadMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166DB32C4BD70600A50963 /* RecipeUploadMapper.swift */; }; + 1D166DB62C4BD7F600A50963 /* UserDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166DB52C4BD7F600A50963 /* UserDTO.swift */; }; 1D2C16E62BE532B700C04508 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D2C16E52BE532B700C04508 /* AppDelegate.swift */; }; 1D2C16EA2BE532B700C04508 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D2C16E92BE532B700C04508 /* ViewController.swift */; }; 1D2C16FD2BE532B800C04508 /* HomeCafeRecipesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D2C16FC2BE532B800C04508 /* HomeCafeRecipesTests.swift */; }; 1D2C17072BE532B800C04508 /* HomeCafeRecipesUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D2C17062BE532B800C04508 /* HomeCafeRecipesUITests.swift */; }; 1D2C17092BE532B800C04508 /* HomeCafeRecipesUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D2C17082BE532B800C04508 /* HomeCafeRecipesUITestsLaunchTests.swift */; }; + 1D2C6F652C2446D8004BB54E /* MainTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D2C6F642C2446D8004BB54E /* MainTabBarController.swift */; }; + 1D2C6F6C2C27051D004BB54E /* CustomNavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D2C6F6B2C27051D004BB54E /* CustomNavigationBar.swift */; }; + 1D3972682C44185B00495014 /* RecipeListMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D3972672C44185B00495014 /* RecipeListMapper.swift */; }; + 1D39729E2C46C57A00495014 /* FetchRecipeDetailUseCaseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D39729D2C46C57A00495014 /* FetchRecipeDetailUseCaseTests.swift */; }; + 1D439E9C2C2C58DD008530A5 /* FetchRecipeDetailUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D439E9B2C2C58DD008530A5 /* FetchRecipeDetailUseCase.swift */; }; + 1D439E9E2C2C598A008530A5 /* RecipeDetailRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D439E9D2C2C598A008530A5 /* RecipeDetailRepository.swift */; }; + 1D439EA22C2C6997008530A5 /* RecipeDetailInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D439EA12C2C6997008530A5 /* RecipeDetailInteractor.swift */; }; 1D4741D12C1B4F8D009381CE /* RecipeImageDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D4741CC2C1B4F8D009381CE /* RecipeImageDTO.swift */; }; 1D4741D22C1B4F8D009381CE /* RecipeDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D4741CD2C1B4F8D009381CE /* RecipeDTO.swift */; }; 1D4741D32C1B4F8D009381CE /* RecipePageDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D4741CE2C1B4F8D009381CE /* RecipePageDTO.swift */; }; 1D4741D42C1B4F8D009381CE /* NetworkResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D4741CF2C1B4F8D009381CE /* NetworkResponseDTO.swift */; }; - - 1DDE911D2C36717B0078DFD3 /* String+Validation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE911B2C36717B0078DFD3 /* String+Validation.swift */; }; - 1DDE911E2C36717B0078DFD3 /* UIImageViewImageLoading.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE911C2C36717B0078DFD3 /* UIImageViewImageLoading.swift */; }; - 1DDE91212C3671840078DFD3 /* Fonts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91202C3671840078DFD3 /* Fonts.swift */; }; - 1DDE91232C3671920078DFD3 /* CustomNavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91222C3671910078DFD3 /* CustomNavigationBar.swift */; }; - 1DDE91252C3671B20078DFD3 /* RecipeListMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91242C3671B20078DFD3 /* RecipeListMapper.swift */; }; - 1DDE91282C3671DB0078DFD3 /* DateFormatter+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91272C3671DB0078DFD3 /* DateFormatter+Extensions.swift */; }; - 1DDE912B2C3671EC0078DFD3 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91292C3671EC0078DFD3 /* User.swift */; }; - 1DDE912C2C3671EC0078DFD3 /* Comment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE912A2C3671EC0078DFD3 /* Comment.swift */; }; - 1DDE912E2C3671FD0078DFD3 /* FetchRecipeDetailUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE912D2C3671FD0078DFD3 /* FetchRecipeDetailUseCase.swift */; }; - 1DDE91302C36720A0078DFD3 /* RecipeDetailInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE912F2C36720A0078DFD3 /* RecipeDetailInteractor.swift */; }; - 1DDE91332C3672170078DFD3 /* RecipeDetailCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91322C3672170078DFD3 /* RecipeDetailCoordinator.swift */; }; - 1DDE91352C3672230078DFD3 /* RecipeDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91342C3672230078DFD3 /* RecipeDetailViewModel.swift */; }; - 1DDE91382C36722A0078DFD3 /* RecipeDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91362C36722A0078DFD3 /* RecipeDetailViewController.swift */; }; - 1DDE91392C36722A0078DFD3 /* RecipeDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91372C36722A0078DFD3 /* RecipeDetailView.swift */; }; - 1DDE913B2C3672410078DFD3 /* UserDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE913A2C3672410078DFD3 /* UserDTO.swift */; }; - 1DDE913D2C3672490078DFD3 /* RecipeDetailFetchService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE913C2C3672490078DFD3 /* RecipeDetailFetchService.swift */; }; - 1DDE913F2C3672720078DFD3 /* RecipeDetailRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE913E2C3672720078DFD3 /* RecipeDetailRepository.swift */; }; - 1DDE91412C3672850078DFD3 /* RecipeDetailDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE91402C3672850078DFD3 /* RecipeDetailDTO.swift */; }; - - 1D60CC452C3F932D00D08FA3 /* APIConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D60CC442C3F932D00D08FA3 /* APIConfig.swift */; }; - 1D60CC462C3F932D00D08FA3 /* APIConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D60CC442C3F932D00D08FA3 /* APIConfig.swift */; }; - 1D7368B72C3442C8000EF904 /* String+Validation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D7368B52C3442C8000EF904 /* String+Validation.swift */; }; - 1D7368B82C3442C8000EF904 /* UIImageViewImageLoading.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D7368B62C3442C8000EF904 /* UIImageViewImageLoading.swift */; }; - 1D7368BA2C3442DE000EF904 /* RecipeListMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D7368B92C3442DE000EF904 /* RecipeListMapper.swift */; }; - 1D7368C72C344378000EF904 /* UserDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D7368C62C344378000EF904 /* UserDTO.swift */; }; - 1D7368CA2C3443A1000EF904 /* Comment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D7368C82C3443A1000EF904 /* Comment.swift */; }; - 1D7368CB2C3443A1000EF904 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D7368C92C3443A1000EF904 /* User.swift */; }; - 1D7368CE2C344403000EF904 /* DateFormatter+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D7368CD2C344403000EF904 /* DateFormatter+Extensions.swift */; }; - 1D7368D22C34FADD000EF904 /* FetchRecipeDetailUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D7368D12C34FADD000EF904 /* FetchRecipeDetailUseCase.swift */; }; - 1D7368D42C34FAE8000EF904 /* RecipeDetailInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D7368D32C34FAE8000EF904 /* RecipeDetailInteractor.swift */; }; - 1D7368D82C34FB07000EF904 /* RecipeDetailDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D7368D72C34FB07000EF904 /* RecipeDetailDTO.swift */; }; - 1D7368DA2C34FB14000EF904 /* RecipeDetailRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D7368D92C34FB14000EF904 /* RecipeDetailRepository.swift */; }; - 1D7368DC2C34FB32000EF904 /* CustomNavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D7368DB2C34FB32000EF904 /* CustomNavigationBar.swift */; }; - 1D7368E22C34FB38000EF904 /* RecipeDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D7368DF2C34FB38000EF904 /* RecipeDetailViewController.swift */; }; - 1D7368E32C34FB38000EF904 /* RecipeDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D7368E02C34FB38000EF904 /* RecipeDetailView.swift */; }; - 1D7368E42C34FB38000EF904 /* RecipeDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D7368E12C34FB38000EF904 /* RecipeDetailViewModel.swift */; }; - 1D7368E72C34FB66000EF904 /* RecipeDetailCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D7368E62C34FB66000EF904 /* RecipeDetailCoordinator.swift */; }; - 1D7368EA2C34FBF7000EF904 /* MainTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D7368E92C34FBF7000EF904 /* MainTabBarController.swift */; }; - 1D95A0A42C37B0E200F09077 /* Fonts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D95A0A32C37B0E200F09077 /* Fonts.swift */; }; - 1D95A0A82C37C7D400F09077 /* RecipeDetailError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D95A0A72C37C7D400F09077 /* RecipeDetailError.swift */; }; - + 1D4741D72C1B4FF4009381CE /* RecipeListInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D4741D62C1B4FF4009381CE /* RecipeListInteractor.swift */; }; + 1D60CC3D2C3E4F1600D08FA3 /* APIConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D60CC3C2C3E4F1600D08FA3 /* APIConfig.swift */; }; + 1D60CC402C3EB76600D08FA3 /* APIConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D60CC3C2C3E4F1600D08FA3 /* APIConfig.swift */; }; + 1D6958D82C3D5A80008604B3 /* RecipeDeatilInteractorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D6958D72C3D5A80008604B3 /* RecipeDeatilInteractorTests.swift */; }; + 1D6958D92C3D5AF7008604B3 /* RecipeDetailInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D439EA12C2C6997008530A5 /* RecipeDetailInteractor.swift */; }; + 1D6958DA2C3D5BA4008604B3 /* FetchRecipeDetailUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D439E9B2C2C58DD008530A5 /* FetchRecipeDetailUseCase.swift */; }; + 1D6958DB2C3D5C91008604B3 /* Recipe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D1283A12C15E94300C5A870 /* Recipe.swift */; }; + 1D6958DC2C3D5E20008604B3 /* RecipeDetailRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D439E9D2C2C598A008530A5 /* RecipeDetailRepository.swift */; }; + 1D6958DE2C3D5E2C008604B3 /* RecipeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D1283A32C15EA8100C5A870 /* RecipeType.swift */; }; + 1D6958DF2C3D5E35008604B3 /* NetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19EB02C1B42200031804A /* NetworkService.swift */; }; + 1D6958E02C3D5E3D008604B3 /* RecipeDetailError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D95A0A52C37C79500F09077 /* RecipeDetailError.swift */; }; + 1D6958E12C3D5E44008604B3 /* RecipeDetailDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D73686D2C305757000EF904 /* RecipeDetailDTO.swift */; }; + 1D6958E22C3D5E99008604B3 /* RecipeImageDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D4741CC2C1B4F8D009381CE /* RecipeImageDTO.swift */; }; + 1D6958E42C3D5EA6008604B3 /* NetworkResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D4741CF2C1B4F8D009381CE /* NetworkResponseDTO.swift */; }; + 1D73686E2C305757000EF904 /* RecipeDetailDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D73686D2C305757000EF904 /* RecipeDetailDTO.swift */; }; + 1D95A0A62C37C79500F09077 /* RecipeDetailError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D95A0A52C37C79500F09077 /* RecipeDetailError.swift */; }; + 1DDE90CF2C3590C40078DFD3 /* AddRecipeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDE90CE2C3590C40078DFD3 /* AddRecipeTests.swift */; }; + 1DDFFD842C1C324F0083B077 /* RecipeDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDFFD832C1C324F0083B077 /* RecipeDetailViewController.swift */; }; 1DE19E9D2C1B3DC10031804A /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19E9C2C1B3DC10031804A /* SceneDelegate.swift */; }; 1DE19EA72C1B420A0031804A /* FeedListRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19EA52C1B420A0031804A /* FeedListRepository.swift */; }; 1DE19EA82C1B420A0031804A /* SearchFeedListRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19EA62C1B420A0031804A /* SearchFeedListRepository.swift */; }; 1DE19EB12C1B42200031804A /* NetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19EB02C1B42200031804A /* NetworkService.swift */; }; - 1DE19EC22C1B422F0031804A /* RecipeListItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19EBA2C1B422F0031804A /* RecipeListItemViewModel.swift */; }; + 1DE19EBF2C1B422F0031804A /* RecipeDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19EB42C1B422F0031804A /* RecipeDetailViewModel.swift */; }; + 1DE19EC02C1B422F0031804A /* RecipeDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19EB62C1B422F0031804A /* RecipeDetailView.swift */; }; 1DE19EC32C1B422F0031804A /* SearchBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19EBB2C1B422F0031804A /* SearchBar.swift */; }; 1DE19EC42C1B422F0031804A /* RecipeListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19EBC2C1B422F0031804A /* RecipeListViewController.swift */; }; 1DE19EC52C1B422F0031804A /* RecipeListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19EBD2C1B422F0031804A /* RecipeListView.swift */; }; 1DE19EC62C1B422F0031804A /* RecipeListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE19EBE2C1B422F0031804A /* RecipeListCell.swift */; }; 1DE19EC82C1B4C2D0031804A /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 1DE19EC72C1B4C2D0031804A /* Kingfisher */; }; - 1DF829B12C299F1F00C337FC /* RecipeListInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DF829B02C299F1F00C337FC /* RecipeListInteractor.swift */; }; + 1DF829B42C2A7A7D00C337FC /* Fonts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DF829B32C2A7A7D00C337FC /* Fonts.swift */; }; + 1DF829B72C2A7CDC00C337FC /* UIImageViewImageLoading.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DF829B62C2A7CDC00C337FC /* UIImageViewImageLoading.swift */; }; + 1DF829B92C2A818D00C337FC /* String+Validation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DF829B82C2A818D00C337FC /* String+Validation.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -103,6 +113,30 @@ 1D1283A92C15EBCF00C5A870 /* SearchFeedUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchFeedUseCase.swift; sourceTree = ""; }; 1D1283AB2C15EBE600C5A870 /* FetchFeedListUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchFeedListUseCase.swift; sourceTree = ""; }; 1D1283C92C16D9C600C5A870 /* RecipeFetchService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeFetchService.swift; sourceTree = ""; }; + 1D166D832C4BD58300A50963 /* RecipeListRouter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeListRouter.swift; sourceTree = ""; }; + 1D166D842C4BD58300A50963 /* Router.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Router.swift; sourceTree = ""; }; + 1D166D882C4BD59500A50963 /* DateFormatter+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DateFormatter+Extensions.swift"; sourceTree = ""; }; + 1D166D8B2C4BD5A400A50963 /* SelectImageCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectImageCell.swift; sourceTree = ""; }; + 1D166D8C2C4BD5A400A50963 /* AddRecipeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddRecipeViewController.swift; sourceTree = ""; }; + 1D166D8D2C4BD5A400A50963 /* RecipeUploadImgaeCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeUploadImgaeCell.swift; sourceTree = ""; }; + 1D166D8E2C4BD5A400A50963 /* AddRecipeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddRecipeView.swift; sourceTree = ""; }; + 1D166D8F2C4BD5A400A50963 /* AddRecipeViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddRecipeViewModel.swift; sourceTree = ""; }; + 1D166D972C4BD5CD00A50963 /* RecipeListItemViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeListItemViewModel.swift; sourceTree = ""; }; + 1D166D992C4BD5EF00A50963 /* AddRecipeInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddRecipeInteractor.swift; sourceTree = ""; }; + 1D166D9B2C4BD5F800A50963 /* AddRecipeUseCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddRecipeUseCase.swift; sourceTree = ""; }; + 1D166D9D2C4BD66C00A50963 /* CGSize+addButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CGSize+addButton.swift"; sourceTree = ""; }; + 1D166D9E2C4BD66C00A50963 /* UIView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Extensions.swift"; sourceTree = ""; }; + 1D166DA12C4BD69200A50963 /* Comment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Comment.swift; sourceTree = ""; }; + 1D166DA22C4BD69200A50963 /* User.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = ""; }; + 1D166DA52C4BD69800A50963 /* AddRecipeError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddRecipeError.swift; sourceTree = ""; }; + 1D166DA72C4BD6AF00A50963 /* AddRecipeRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddRecipeRepository.swift; sourceTree = ""; }; + 1D166DA92C4BD6B800A50963 /* MultipartFormDataRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultipartFormDataRequest.swift; sourceTree = ""; }; + 1D166DAB2C4BD6CD00A50963 /* RecipePostService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipePostService.swift; sourceTree = ""; }; + 1D166DAD2C4BD6DB00A50963 /* ErrorResponseDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ErrorResponseDTO.swift; sourceTree = ""; }; + 1D166DAF2C4BD6EA00A50963 /* RecipeUploadDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeUploadDTO.swift; sourceTree = ""; }; + 1D166DB02C4BD6EA00A50963 /* RecipeUploadResponseDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeUploadResponseDTO.swift; sourceTree = ""; }; + 1D166DB32C4BD70600A50963 /* RecipeUploadMapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeUploadMapper.swift; sourceTree = ""; }; + 1D166DB52C4BD7F600A50963 /* UserDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDTO.swift; sourceTree = ""; }; 1D2C16E22BE532B700C04508 /* HomeCafeRecipes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HomeCafeRecipes.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1D2C16E52BE532B700C04508 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 1D2C16E92BE532B700C04508 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; @@ -114,61 +148,37 @@ 1D2C17022BE532B800C04508 /* HomeCafeRecipesUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HomeCafeRecipesUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 1D2C17062BE532B800C04508 /* HomeCafeRecipesUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeCafeRecipesUITests.swift; sourceTree = ""; }; 1D2C17082BE532B800C04508 /* HomeCafeRecipesUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeCafeRecipesUITestsLaunchTests.swift; sourceTree = ""; }; + 1D2C6F642C2446D8004BB54E /* MainTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabBarController.swift; sourceTree = ""; }; + 1D2C6F6B2C27051D004BB54E /* CustomNavigationBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomNavigationBar.swift; sourceTree = ""; }; + 1D3972672C44185B00495014 /* RecipeListMapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeListMapper.swift; sourceTree = ""; }; + 1D39729D2C46C57A00495014 /* FetchRecipeDetailUseCaseTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchRecipeDetailUseCaseTests.swift; sourceTree = ""; }; + 1D439E9B2C2C58DD008530A5 /* FetchRecipeDetailUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchRecipeDetailUseCase.swift; sourceTree = ""; }; + 1D439E9D2C2C598A008530A5 /* RecipeDetailRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeDetailRepository.swift; sourceTree = ""; }; + 1D439EA12C2C6997008530A5 /* RecipeDetailInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeDetailInteractor.swift; sourceTree = ""; }; 1D4741CC2C1B4F8D009381CE /* RecipeImageDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeImageDTO.swift; sourceTree = ""; }; 1D4741CD2C1B4F8D009381CE /* RecipeDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDTO.swift; sourceTree = ""; }; 1D4741CE2C1B4F8D009381CE /* RecipePageDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipePageDTO.swift; sourceTree = ""; }; 1D4741CF2C1B4F8D009381CE /* NetworkResponseDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkResponseDTO.swift; sourceTree = ""; }; - - 1DDE911B2C36717B0078DFD3 /* String+Validation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Validation.swift"; sourceTree = ""; }; - 1DDE911C2C36717B0078DFD3 /* UIImageViewImageLoading.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageViewImageLoading.swift; sourceTree = ""; }; - 1DDE91202C3671840078DFD3 /* Fonts.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Fonts.swift; sourceTree = ""; }; - 1DDE91222C3671910078DFD3 /* CustomNavigationBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomNavigationBar.swift; sourceTree = ""; }; - 1DDE91242C3671B20078DFD3 /* RecipeListMapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeListMapper.swift; sourceTree = ""; }; - 1DDE91272C3671DB0078DFD3 /* DateFormatter+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DateFormatter+Extensions.swift"; sourceTree = ""; }; - 1DDE91292C3671EC0078DFD3 /* User.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = ""; }; - 1DDE912A2C3671EC0078DFD3 /* Comment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Comment.swift; sourceTree = ""; }; - 1DDE912D2C3671FD0078DFD3 /* FetchRecipeDetailUseCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchRecipeDetailUseCase.swift; sourceTree = ""; }; - 1DDE912F2C36720A0078DFD3 /* RecipeDetailInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailInteractor.swift; sourceTree = ""; }; - 1DDE91322C3672170078DFD3 /* RecipeDetailCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailCoordinator.swift; sourceTree = ""; }; - 1DDE91342C3672230078DFD3 /* RecipeDetailViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailViewModel.swift; sourceTree = ""; }; - 1DDE91362C36722A0078DFD3 /* RecipeDetailViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailViewController.swift; sourceTree = ""; }; - 1DDE91372C36722A0078DFD3 /* RecipeDetailView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailView.swift; sourceTree = ""; }; - 1DDE913A2C3672410078DFD3 /* UserDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDTO.swift; sourceTree = ""; }; - 1DDE913C2C3672490078DFD3 /* RecipeDetailFetchService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailFetchService.swift; sourceTree = ""; }; - 1DDE913E2C3672720078DFD3 /* RecipeDetailRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailRepository.swift; sourceTree = ""; }; - 1DDE91402C3672850078DFD3 /* RecipeDetailDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailDTO.swift; sourceTree = ""; }; - - 1D60CC442C3F932D00D08FA3 /* APIConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = APIConfig.swift; sourceTree = ""; }; - 1D7368B52C3442C8000EF904 /* String+Validation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Validation.swift"; sourceTree = ""; }; - 1D7368B62C3442C8000EF904 /* UIImageViewImageLoading.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageViewImageLoading.swift; sourceTree = ""; }; - 1D7368B92C3442DE000EF904 /* RecipeListMapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeListMapper.swift; sourceTree = ""; }; - 1D7368C62C344378000EF904 /* UserDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDTO.swift; sourceTree = ""; }; - 1D7368C82C3443A1000EF904 /* Comment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Comment.swift; sourceTree = ""; }; - 1D7368C92C3443A1000EF904 /* User.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = ""; }; - 1D7368CD2C344403000EF904 /* DateFormatter+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DateFormatter+Extensions.swift"; sourceTree = ""; }; - 1D7368D12C34FADD000EF904 /* FetchRecipeDetailUseCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchRecipeDetailUseCase.swift; sourceTree = ""; }; - 1D7368D32C34FAE8000EF904 /* RecipeDetailInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailInteractor.swift; sourceTree = ""; }; - 1D7368D72C34FB07000EF904 /* RecipeDetailDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailDTO.swift; sourceTree = ""; }; - 1D7368D92C34FB14000EF904 /* RecipeDetailRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailRepository.swift; sourceTree = ""; }; - 1D7368DB2C34FB32000EF904 /* CustomNavigationBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomNavigationBar.swift; sourceTree = ""; }; - 1D7368DF2C34FB38000EF904 /* RecipeDetailViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailViewController.swift; sourceTree = ""; }; - 1D7368E02C34FB38000EF904 /* RecipeDetailView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailView.swift; sourceTree = ""; }; - 1D7368E12C34FB38000EF904 /* RecipeDetailViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailViewModel.swift; sourceTree = ""; }; - 1D7368E62C34FB66000EF904 /* RecipeDetailCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailCoordinator.swift; sourceTree = ""; }; - 1D7368E92C34FBF7000EF904 /* MainTabBarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainTabBarController.swift; sourceTree = ""; }; - 1D95A0A32C37B0E200F09077 /* Fonts.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Fonts.swift; sourceTree = ""; }; - 1D95A0A72C37C7D400F09077 /* RecipeDetailError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailError.swift; sourceTree = ""; }; - + 1D4741D62C1B4FF4009381CE /* RecipeListInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeListInteractor.swift; sourceTree = ""; }; + 1D60CC3C2C3E4F1600D08FA3 /* APIConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = APIConfig.swift; sourceTree = ""; }; + 1D6958D72C3D5A80008604B3 /* RecipeDeatilInteractorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeDeatilInteractorTests.swift; sourceTree = ""; }; + 1D73686D2C305757000EF904 /* RecipeDetailDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeDetailDTO.swift; sourceTree = ""; }; + 1D95A0A52C37C79500F09077 /* RecipeDetailError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeDetailError.swift; sourceTree = ""; }; + 1DDE90CE2C3590C40078DFD3 /* AddRecipeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddRecipeTests.swift; sourceTree = ""; }; + 1DDFFD832C1C324F0083B077 /* RecipeDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeDetailViewController.swift; sourceTree = ""; }; 1DE19E9C2C1B3DC10031804A /* SceneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 1DE19EA52C1B420A0031804A /* FeedListRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedListRepository.swift; sourceTree = ""; }; 1DE19EA62C1B420A0031804A /* SearchFeedListRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchFeedListRepository.swift; sourceTree = ""; }; 1DE19EB02C1B42200031804A /* NetworkService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkService.swift; sourceTree = ""; }; - 1DE19EBA2C1B422F0031804A /* RecipeListItemViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeListItemViewModel.swift; sourceTree = ""; }; + 1DE19EB42C1B422F0031804A /* RecipeDetailViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailViewModel.swift; sourceTree = ""; }; + 1DE19EB62C1B422F0031804A /* RecipeDetailView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeDetailView.swift; sourceTree = ""; }; 1DE19EBB2C1B422F0031804A /* SearchBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchBar.swift; sourceTree = ""; }; 1DE19EBC2C1B422F0031804A /* RecipeListViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeListViewController.swift; sourceTree = ""; }; 1DE19EBD2C1B422F0031804A /* RecipeListView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeListView.swift; sourceTree = ""; }; 1DE19EBE2C1B422F0031804A /* RecipeListCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeListCell.swift; sourceTree = ""; }; - 1DF829B02C299F1F00C337FC /* RecipeListInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeListInteractor.swift; sourceTree = ""; }; + 1DF829B32C2A7A7D00C337FC /* Fonts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fonts.swift; sourceTree = ""; }; + 1DF829B62C2A7CDC00C337FC /* UIImageViewImageLoading.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImageViewImageLoading.swift; sourceTree = ""; }; + 1DF829B82C2A818D00C337FC /* String+Validation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Validation.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -204,14 +214,12 @@ 1D12839F2C15E7A700C5A870 /* Entities */ = { isa = PBXGroup; children = ( - - 1DDE912A2C3671EC0078DFD3 /* Comment.swift */, - 1DDE91292C3671EC0078DFD3 /* User.swift */, - 1D95A0A72C37C7D400F09077 /* RecipeDetailError.swift */, + 1D166DA12C4BD69200A50963 /* Comment.swift */, + 1D166DA22C4BD69200A50963 /* User.swift */, 1D1283A12C15E94300C5A870 /* Recipe.swift */, - 1D7368C82C3443A1000EF904 /* Comment.swift */, - 1D7368C92C3443A1000EF904 /* User.swift */, 1D1283A32C15EA8100C5A870 /* RecipeType.swift */, + 1D95A0A52C37C79500F09077 /* RecipeDetailError.swift */, + 1D166DA52C4BD69800A50963 /* AddRecipeError.swift */, ); path = Entities; sourceTree = ""; @@ -219,10 +227,10 @@ 1D1283A02C15E92C00C5A870 /* UseCases */ = { isa = PBXGroup; children = ( + 1D166D9B2C4BD5F800A50963 /* AddRecipeUseCase.swift */, 1D1283A92C15EBCF00C5A870 /* SearchFeedUseCase.swift */, - 1DDE912D2C3671FD0078DFD3 /* FetchRecipeDetailUseCase.swift */, - 1D7368D12C34FADD000EF904 /* FetchRecipeDetailUseCase.swift */, 1D1283AB2C15EBE600C5A870 /* FetchFeedListUseCase.swift */, + 1D439E9B2C2C58DD008530A5 /* FetchRecipeDetailUseCase.swift */, ); path = UseCases; sourceTree = ""; @@ -248,13 +256,43 @@ children = ( 1D4741CB2C1B4F8D009381CE /* DTO */, 1D1283C92C16D9C600C5A870 /* RecipeFetchService.swift */, - 1DDE913C2C3672490078DFD3 /* RecipeDetailFetchService.swift */, + 1D166DAB2C4BD6CD00A50963 /* RecipePostService.swift */, 1DE19EB02C1B42200031804A /* NetworkService.swift */, - 1D60CC442C3F932D00D08FA3 /* APIConfig.swift */, + 1D60CC3C2C3E4F1600D08FA3 /* APIConfig.swift */, + 1D166DA92C4BD6B800A50963 /* MultipartFormDataRequest.swift */, ); path = Network; sourceTree = ""; }; + 1D166D822C4BD58300A50963 /* Router */ = { + isa = PBXGroup; + children = ( + 1D166D832C4BD58300A50963 /* RecipeListRouter.swift */, + 1D166D842C4BD58300A50963 /* Router.swift */, + ); + path = Router; + sourceTree = ""; + }; + 1D166D872C4BD59500A50963 /* Utilities */ = { + isa = PBXGroup; + children = ( + 1D166D882C4BD59500A50963 /* DateFormatter+Extensions.swift */, + ); + path = Utilities; + sourceTree = ""; + }; + 1D166D8A2C4BD5A400A50963 /* UploadRecipe */ = { + isa = PBXGroup; + children = ( + 1D166D8B2C4BD5A400A50963 /* SelectImageCell.swift */, + 1D166D8C2C4BD5A400A50963 /* AddRecipeViewController.swift */, + 1D166D8D2C4BD5A400A50963 /* RecipeUploadImgaeCell.swift */, + 1D166D8E2C4BD5A400A50963 /* AddRecipeView.swift */, + 1D166D8F2C4BD5A400A50963 /* AddRecipeViewModel.swift */, + ); + path = UploadRecipe; + sourceTree = ""; + }; 1D2C16D92BE532B700C04508 = { isa = PBXGroup; children = ( @@ -280,15 +318,10 @@ 1D2C16E42BE532B700C04508 /* HomeCafeRecipes */ = { isa = PBXGroup; children = ( - 1DDE91312C3672170078DFD3 /* Coordinators */, - 1DDE91262C3671DB0078DFD3 /* Utilities */, - 1DDE911F2C3671840078DFD3 /* Resources */, - 1DDE911A2C36717B0078DFD3 /* Extensions */, - - 1D95A0A22C37B0E200F09077 /* Resources */, - 1D7368E52C34FB66000EF904 /* Coordinators */, - 1D7368CC2C344403000EF904 /* Utilities */, - 1D7368B42C3442C8000EF904 /* Extensions */, + 1D166D872C4BD59500A50963 /* Utilities */, + 1D166D822C4BD58300A50963 /* Router */, + 1DF829B52C2A7C8600C337FC /* Extensions */, + 1DF829B22C2A7A0B00C337FC /* Resources */, 1DE19EB22C1B422F0031804A /* Presentation */, 1D1283AD2C16974B00C5A870 /* Data */, 1D740B402C15E6680001B704 /* Domain */, @@ -306,6 +339,9 @@ isa = PBXGroup; children = ( 1D2C16FC2BE532B800C04508 /* HomeCafeRecipesTests.swift */, + 1DDE90CE2C3590C40078DFD3 /* AddRecipeTests.swift */, + 1D6958D72C3D5A80008604B3 /* RecipeDeatilInteractorTests.swift */, + 1D39729D2C46C57A00495014 /* FetchRecipeDetailUseCaseTests.swift */, ); path = HomeCafeRecipesTests; sourceTree = ""; @@ -319,147 +355,66 @@ path = HomeCafeRecipesUITests; sourceTree = ""; }; + 1D2C6F612C2446AF004BB54E /* Tabbar */ = { + isa = PBXGroup; + children = ( + 1D2C6F642C2446D8004BB54E /* MainTabBarController.swift */, + ); + path = Tabbar; + sourceTree = ""; + }; 1D4741CB2C1B4F8D009381CE /* DTO */ = { isa = PBXGroup; children = ( - 1D7368C62C344378000EF904 /* UserDTO.swift */, + 1D166DB52C4BD7F600A50963 /* UserDTO.swift */, 1D4741CC2C1B4F8D009381CE /* RecipeImageDTO.swift */, - 1DDE91402C3672850078DFD3 /* RecipeDetailDTO.swift */, 1D4741CD2C1B4F8D009381CE /* RecipeDTO.swift */, - 1DDE913A2C3672410078DFD3 /* UserDTO.swift */, - 1D7368D72C34FB07000EF904 /* RecipeDetailDTO.swift */, 1D4741CE2C1B4F8D009381CE /* RecipePageDTO.swift */, 1D4741CF2C1B4F8D009381CE /* NetworkResponseDTO.swift */, + 1D73686D2C305757000EF904 /* RecipeDetailDTO.swift */, + 1D166DAF2C4BD6EA00A50963 /* RecipeUploadDTO.swift */, + 1D166DB02C4BD6EA00A50963 /* RecipeUploadResponseDTO.swift */, + 1D166DAD2C4BD6DB00A50963 /* ErrorResponseDTO.swift */, ); path = DTO; sourceTree = ""; }; - 1D7368B42C3442C8000EF904 /* Extensions */ = { - isa = PBXGroup; - children = ( - 1D7368B52C3442C8000EF904 /* String+Validation.swift */, - 1D7368B62C3442C8000EF904 /* UIImageViewImageLoading.swift */, - ); - path = Extensions; - sourceTree = ""; - }; - 1D7368CC2C344403000EF904 /* Utilities */ = { - isa = PBXGroup; - children = ( - 1D7368CD2C344403000EF904 /* DateFormatter+Extensions.swift */, - ); - path = Utilities; - sourceTree = ""; - }; - 1D7368DD2C34FB38000EF904 /* Feed */ = { - isa = PBXGroup; - children = ( - 1D7368DE2C34FB38000EF904 /* View */, - 1D7368E12C34FB38000EF904 /* RecipeDetailViewModel.swift */, - ); - path = Feed; - sourceTree = ""; - }; - 1D7368DE2C34FB38000EF904 /* View */ = { - isa = PBXGroup; - children = ( - 1D7368DF2C34FB38000EF904 /* RecipeDetailViewController.swift */, - 1D7368E02C34FB38000EF904 /* RecipeDetailView.swift */, - ); - path = View; - sourceTree = ""; - }; - 1D7368E52C34FB66000EF904 /* Coordinators */ = { - isa = PBXGroup; - children = ( - 1D7368E62C34FB66000EF904 /* RecipeDetailCoordinator.swift */, - ); - path = Coordinators; - sourceTree = ""; - }; - 1D7368E82C34FBF7000EF904 /* Tabbar */ = { - isa = PBXGroup; - children = ( - 1D7368E92C34FBF7000EF904 /* MainTabBarController.swift */, - ); - path = Tabbar; - sourceTree = ""; - }; 1D740B402C15E6680001B704 /* Domain */ = { isa = PBXGroup; children = ( - 1DF829AF2C299F1F00C337FC /* Interactor */, + 1DE19EA12C1B41FE0031804A /* Interactor */, 1D1283A02C15E92C00C5A870 /* UseCases */, 1D12839F2C15E7A700C5A870 /* Entities */, ); path = Domain; sourceTree = ""; }; - - 1DDE911A2C36717B0078DFD3 /* Extensions */ = { - isa = PBXGroup; - children = ( - 1DDE911B2C36717B0078DFD3 /* String+Validation.swift */, - 1DDE911C2C36717B0078DFD3 /* UIImageViewImageLoading.swift */, - ); - path = Extensions; - sourceTree = ""; - }; - 1DDE911F2C3671840078DFD3 /* Resources */ = { - isa = PBXGroup; - children = ( - 1DDE91202C3671840078DFD3 /* Fonts.swift */, - - 1D95A0A22C37B0E200F09077 /* Resources */ = { - isa = PBXGroup; - children = ( - 1D95A0A32C37B0E200F09077 /* Fonts.swift */, - - ); - path = Resources; - sourceTree = ""; - }; - - 1DDE91262C3671DB0078DFD3 /* Utilities */ = { - isa = PBXGroup; - children = ( - 1DDE91272C3671DB0078DFD3 /* DateFormatter+Extensions.swift */, - ); - path = Utilities; - sourceTree = ""; - }; - 1DDE91312C3672170078DFD3 /* Coordinators */ = { + 1DDFFD822C1C09AB0083B077 /* Mapper */ = { isa = PBXGroup; children = ( - 1DDE91322C3672170078DFD3 /* RecipeDetailCoordinator.swift */, + 1D3972672C44185B00495014 /* RecipeListMapper.swift */, + 1D166DB32C4BD70600A50963 /* RecipeUploadMapper.swift */, ); - path = Coordinators; + path = Mapper; sourceTree = ""; }; - 1DDFFD822C1C09AB0083B077 /* Mapper */ = { - isa = PBXGroup; - children = ( - 1DDE91242C3671B20078DFD3 /* RecipeListMapper.swift */, - - 1DDFFD822C1C09AB0083B077 /* Mapper */ = { + 1DE19EA12C1B41FE0031804A /* Interactor */ = { isa = PBXGroup; children = ( - 1D7368B92C3442DE000EF904 /* RecipeListMapper.swift */, - + 1D4741D62C1B4FF4009381CE /* RecipeListInteractor.swift */, + 1D439EA12C2C6997008530A5 /* RecipeDetailInteractor.swift */, + 1D166D992C4BD5EF00A50963 /* AddRecipeInteractor.swift */, ); - path = Mapper; + path = Interactor; sourceTree = ""; }; 1DE19EA42C1B420A0031804A /* Repositories */ = { isa = PBXGroup; children = ( 1DE19EA52C1B420A0031804A /* FeedListRepository.swift */, - - 1DDE913E2C3672720078DFD3 /* RecipeDetailRepository.swift */, - - 1D7368D92C34FB14000EF904 /* RecipeDetailRepository.swift */, - 1DE19EA62C1B420A0031804A /* SearchFeedListRepository.swift */, + 1D439E9D2C2C598A008530A5 /* RecipeDetailRepository.swift */, + 1D166DA72C4BD6AF00A50963 /* AddRecipeRepository.swift */, ); path = Repositories; sourceTree = ""; @@ -467,22 +422,20 @@ 1DE19EB22C1B422F0031804A /* Presentation */ = { isa = PBXGroup; children = ( - 1DDE91222C3671910078DFD3 /* CustomNavigationBar.swift */, - 1D7368E82C34FBF7000EF904 /* Tabbar */, - 1D7368DD2C34FB38000EF904 /* Feed */, - 1D7368DB2C34FB32000EF904 /* CustomNavigationBar.swift */, - + 1D166D8A2C4BD5A400A50963 /* UploadRecipe */, + 1D2C6F612C2446AF004BB54E /* Tabbar */, 1DDFFD822C1C09AB0083B077 /* Mapper */, + 1DE19EB32C1B422F0031804A /* Feed */, 1DE19EB72C1B422F0031804A /* FeedList */, + 1D2C6F6B2C27051D004BB54E /* CustomNavigationBar.swift */, ); path = Presentation; sourceTree = ""; }; - 1DE19EB32C1B422F0031804A /* Feed */ = { isa = PBXGroup; children = ( - 1DDE91342C3672230078DFD3 /* RecipeDetailViewModel.swift */, + 1DE19EB42C1B422F0031804A /* RecipeDetailViewModel.swift */, 1DE19EB52C1B422F0031804A /* View */, ); path = Feed; @@ -491,16 +444,16 @@ 1DE19EB52C1B422F0031804A /* View */ = { isa = PBXGroup; children = ( - 1DDE91372C36722A0078DFD3 /* RecipeDetailView.swift */, - 1DDE91362C36722A0078DFD3 /* RecipeDetailViewController.swift */, + 1DE19EB62C1B422F0031804A /* RecipeDetailView.swift */, + 1DDFFD832C1C324F0083B077 /* RecipeDetailViewController.swift */, ); path = View; sourceTree = ""; }; - 1DE19EB72C1B422F0031804A /* FeedList */ = { isa = PBXGroup; children = ( + 1D166D972C4BD5CD00A50963 /* RecipeListItemViewModel.swift */, 1DE19EB92C1B422F0031804A /* View */, ); path = FeedList; @@ -509,7 +462,6 @@ 1DE19EB92C1B422F0031804A /* View */ = { isa = PBXGroup; children = ( - 1DE19EBA2C1B422F0031804A /* RecipeListItemViewModel.swift */, 1DE19EBB2C1B422F0031804A /* SearchBar.swift */, 1DE19EBC2C1B422F0031804A /* RecipeListViewController.swift */, 1DE19EBD2C1B422F0031804A /* RecipeListView.swift */, @@ -518,14 +470,23 @@ path = View; sourceTree = ""; }; - 1DF829AF2C299F1F00C337FC /* Interactor */ = { + 1DF829B22C2A7A0B00C337FC /* Resources */ = { isa = PBXGroup; children = ( - 1DDE912F2C36720A0078DFD3 /* RecipeDetailInteractor.swift */, - 1D7368D32C34FAE8000EF904 /* RecipeDetailInteractor.swift */, - 1DF829B02C299F1F00C337FC /* RecipeListInteractor.swift */, + 1DF829B32C2A7A7D00C337FC /* Fonts.swift */, ); - path = Interactor; + path = Resources; + sourceTree = ""; + }; + 1DF829B52C2A7C8600C337FC /* Extensions */ = { + isa = PBXGroup; + children = ( + 1DF829B62C2A7CDC00C337FC /* UIImageViewImageLoading.swift */, + 1DF829B82C2A818D00C337FC /* String+Validation.swift */, + 1D166D9D2C4BD66C00A50963 /* CGSize+addButton.swift */, + 1D166D9E2C4BD66C00A50963 /* UIView+Extensions.swift */, + ); + path = Extensions; sourceTree = ""; }; /* End PBXGroup section */ @@ -669,77 +630,65 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 1DF829B12C299F1F00C337FC /* RecipeListInteractor.swift in Sources */, + 1D439E9E2C2C598A008530A5 /* RecipeDetailRepository.swift in Sources */, + 1D166DB22C4BD6EA00A50963 /* RecipeUploadResponseDTO.swift in Sources */, + 1D2C6F6C2C27051D004BB54E /* CustomNavigationBar.swift in Sources */, + 1D3972682C44185B00495014 /* RecipeListMapper.swift in Sources */, + 1D166D902C4BD5A400A50963 /* SelectImageCell.swift in Sources */, 1D2C16EA2BE532B700C04508 /* ViewController.swift in Sources */, - 1D7368EA2C34FBF7000EF904 /* MainTabBarController.swift in Sources */, - 1D60CC452C3F932D00D08FA3 /* APIConfig.swift in Sources */, - 1D7368D42C34FAE8000EF904 /* RecipeDetailInteractor.swift in Sources */, 1DE19EC52C1B422F0031804A /* RecipeListView.swift in Sources */, - - 1DDE911E2C36717B0078DFD3 /* UIImageViewImageLoading.swift in Sources */, - 1DDE912B2C3671EC0078DFD3 /* User.swift in Sources */, - 1DDE91352C3672230078DFD3 /* RecipeDetailViewModel.swift in Sources */, - 1DDE913B2C3672410078DFD3 /* UserDTO.swift in Sources */, + 1D166D852C4BD58300A50963 /* RecipeListRouter.swift in Sources */, 1D4741D32C1B4F8D009381CE /* RecipePageDTO.swift in Sources */, - 1DDE91392C36722A0078DFD3 /* RecipeDetailView.swift in Sources */, - - 1D7368CB2C3443A1000EF904 /* User.swift in Sources */, - 1D4741D32C1B4F8D009381CE /* RecipePageDTO.swift in Sources */, - 1D7368CE2C344403000EF904 /* DateFormatter+Extensions.swift in Sources */, - 1D7368E32C34FB38000EF904 /* RecipeDetailView.swift in Sources */, - + 1D2C6F652C2446D8004BB54E /* MainTabBarController.swift in Sources */, + 1DDFFD842C1C324F0083B077 /* RecipeDetailViewController.swift in Sources */, 1D2C16E62BE532B700C04508 /* AppDelegate.swift in Sources */, - 1DDE91282C3671DB0078DFD3 /* DateFormatter+Extensions.swift in Sources */, - 1DDE91332C3672170078DFD3 /* RecipeDetailCoordinator.swift in Sources */, - 1DDE91382C36722A0078DFD3 /* RecipeDetailViewController.swift in Sources */, 1DE19EB12C1B42200031804A /* NetworkService.swift in Sources */, - - 1DDE913F2C3672720078DFD3 /* RecipeDetailRepository.swift in Sources */, + 1D166D932C4BD5A400A50963 /* AddRecipeView.swift in Sources */, + 1D166D892C4BD59500A50963 /* DateFormatter+Extensions.swift in Sources */, + 1D166D9C2C4BD5F800A50963 /* AddRecipeUseCase.swift in Sources */, + 1D95A0A62C37C79500F09077 /* RecipeDetailError.swift in Sources */, 1D1283AC2C15EBE600C5A870 /* FetchFeedListUseCase.swift in Sources */, - 1DDE91252C3671B20078DFD3 /* RecipeListMapper.swift in Sources */, - - 1D1283AC2C15EBE600C5A870 /* FetchFeedListUseCase.swift in Sources */, - 1D7368E22C34FB38000EF904 /* RecipeDetailViewController.swift in Sources */, - + 1D166D912C4BD5A400A50963 /* AddRecipeViewController.swift in Sources */, + 1D166DB42C4BD70600A50963 /* RecipeUploadMapper.swift in Sources */, + 1D166D862C4BD58300A50963 /* Router.swift in Sources */, + 1D166D982C4BD5CD00A50963 /* RecipeListItemViewModel.swift in Sources */, + 1D166DAC2C4BD6CD00A50963 /* RecipePostService.swift in Sources */, + 1DF829B72C2A7CDC00C337FC /* UIImageViewImageLoading.swift in Sources */, + 1D60CC3D2C3E4F1600D08FA3 /* APIConfig.swift in Sources */, 1D1283A42C15EA8100C5A870 /* RecipeType.swift in Sources */, - 1D7368D82C34FB07000EF904 /* RecipeDetailDTO.swift in Sources */, - 1D7368DA2C34FB14000EF904 /* RecipeDetailRepository.swift in Sources */, + 1D166D9F2C4BD66C00A50963 /* CGSize+addButton.swift in Sources */, + 1DF829B42C2A7A7D00C337FC /* Fonts.swift in Sources */, 1D4741D22C1B4F8D009381CE /* RecipeDTO.swift in Sources */, + 1DE19EC02C1B422F0031804A /* RecipeDetailView.swift in Sources */, + 1D166D922C4BD5A400A50963 /* RecipeUploadImgaeCell.swift in Sources */, 1D1283AA2C15EBCF00C5A870 /* SearchFeedUseCase.swift in Sources */, + 1D166DA82C4BD6AF00A50963 /* AddRecipeRepository.swift in Sources */, 1DE19EA82C1B420A0031804A /* SearchFeedListRepository.swift in Sources */, - - 1D95A0A42C37B0E200F09077 /* Fonts.swift in Sources */, - - 1DE19EC22C1B422F0031804A /* RecipeListItemViewModel.swift in Sources */, - 1D7368C72C344378000EF904 /* UserDTO.swift in Sources */, 1DE19EC32C1B422F0031804A /* SearchBar.swift in Sources */, + 1D439EA22C2C6997008530A5 /* RecipeDetailInteractor.swift in Sources */, + 1D166D9A2C4BD5EF00A50963 /* AddRecipeInteractor.swift in Sources */, + 1D73686E2C305757000EF904 /* RecipeDetailDTO.swift in Sources */, + 1D166DA32C4BD69200A50963 /* Comment.swift in Sources */, + 1D166D942C4BD5A400A50963 /* AddRecipeViewModel.swift in Sources */, + 1D4741D72C1B4FF4009381CE /* RecipeListInteractor.swift in Sources */, 1DE19E9D2C1B3DC10031804A /* SceneDelegate.swift in Sources */, - 1DDE91232C3671920078DFD3 /* CustomNavigationBar.swift in Sources */, 1D4741D12C1B4F8D009381CE /* RecipeImageDTO.swift in Sources */, - 1DDE91412C3672850078DFD3 /* RecipeDetailDTO.swift in Sources */, 1DE19EA72C1B420A0031804A /* FeedListRepository.swift in Sources */, + 1D166DA42C4BD69200A50963 /* User.swift in Sources */, 1DE19EC62C1B422F0031804A /* RecipeListCell.swift in Sources */, - - 1DDE91212C3671840078DFD3 /* Fonts.swift in Sources */, - 1DDE913D2C3672490078DFD3 /* RecipeDetailFetchService.swift in Sources */, - 1DDE91302C36720A0078DFD3 /* RecipeDetailInteractor.swift in Sources */, - 1DE19EC42C1B422F0031804A /* RecipeListViewController.swift in Sources */, - 1DDE912C2C3671EC0078DFD3 /* Comment.swift in Sources */, - 1DDE911D2C36717B0078DFD3 /* String+Validation.swift in Sources */, - 1D7368E72C34FB66000EF904 /* RecipeDetailCoordinator.swift in Sources */, - 1D7368D22C34FADD000EF904 /* FetchRecipeDetailUseCase.swift in Sources */, + 1D166DAA2C4BD6B800A50963 /* MultipartFormDataRequest.swift in Sources */, + 1D166DB12C4BD6EA00A50963 /* RecipeUploadDTO.swift in Sources */, + 1D166DB62C4BD7F600A50963 /* UserDTO.swift in Sources */, + 1DF829B92C2A818D00C337FC /* String+Validation.swift in Sources */, 1DE19EC42C1B422F0031804A /* RecipeListViewController.swift in Sources */, - 1D95A0A82C37C7D400F09077 /* RecipeDetailError.swift in Sources */, + 1DE19EBF2C1B422F0031804A /* RecipeDetailViewModel.swift in Sources */, + 1D166DAE2C4BD6DB00A50963 /* ErrorResponseDTO.swift in Sources */, + 1D166DA02C4BD66C00A50963 /* UIView+Extensions.swift in Sources */, 1D1283A22C15E94300C5A870 /* Recipe.swift in Sources */, - 1D7368BA2C3442DE000EF904 /* RecipeListMapper.swift in Sources */, - 1D7368CA2C3443A1000EF904 /* Comment.swift in Sources */, 1D1283CA2C16D9C600C5A870 /* RecipeFetchService.swift in Sources */, - 1DDE912E2C3671FD0078DFD3 /* FetchRecipeDetailUseCase.swift in Sources */, - 1D7368E42C34FB38000EF904 /* RecipeDetailViewModel.swift in Sources */, - 1D7368B82C3442C8000EF904 /* UIImageViewImageLoading.swift in Sources */, 1D4741D42C1B4F8D009381CE /* NetworkResponseDTO.swift in Sources */, - 1D7368B72C3442C8000EF904 /* String+Validation.swift in Sources */, - 1D7368DC2C34FB32000EF904 /* CustomNavigationBar.swift in Sources */, + 1D166DA62C4BD69800A50963 /* AddRecipeError.swift in Sources */, + 1D439E9C2C2C58DD008530A5 /* FetchRecipeDetailUseCase.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -747,8 +696,21 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 1D60CC462C3F932D00D08FA3 /* APIConfig.swift in Sources */, + 1D6958DF2C3D5E35008604B3 /* NetworkService.swift in Sources */, + 1D6958DC2C3D5E20008604B3 /* RecipeDetailRepository.swift in Sources */, + 1D6958E12C3D5E44008604B3 /* RecipeDetailDTO.swift in Sources */, + 1D6958D82C3D5A80008604B3 /* RecipeDeatilInteractorTests.swift in Sources */, + 1D60CC402C3EB76600D08FA3 /* APIConfig.swift in Sources */, + 1D6958DE2C3D5E2C008604B3 /* RecipeType.swift in Sources */, + 1D6958D92C3D5AF7008604B3 /* RecipeDetailInteractor.swift in Sources */, 1D2C16FD2BE532B800C04508 /* HomeCafeRecipesTests.swift in Sources */, + 1D6958E42C3D5EA6008604B3 /* NetworkResponseDTO.swift in Sources */, + 1D6958DB2C3D5C91008604B3 /* Recipe.swift in Sources */, + 1D6958E02C3D5E3D008604B3 /* RecipeDetailError.swift in Sources */, + 1DDE90CF2C3590C40078DFD3 /* AddRecipeTests.swift in Sources */, + 1D6958DA2C3D5BA4008604B3 /* FetchRecipeDetailUseCase.swift in Sources */, + 1D39729E2C46C57A00495014 /* FetchRecipeDetailUseCaseTests.swift in Sources */, + 1D6958E22C3D5E99008604B3 /* RecipeImageDTO.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/HomeCafeRecipes/HomeCafeRecipes/Domain/Entities/AddRecipeError.swift b/HomeCafeRecipes/HomeCafeRecipes/Domain/Entities/AddRecipeError.swift new file mode 100644 index 0000000..ddbf904 --- /dev/null +++ b/HomeCafeRecipes/HomeCafeRecipes/Domain/Entities/AddRecipeError.swift @@ -0,0 +1,44 @@ +// +// AddRecipeError.swift +// HomeCafeRecipes +// +// Created by 김건호 on 7/17/24. +// + +import Foundation + +enum AddRecipeError: Error { + case noImages + case titleIsEmpty + case descriptionTooShort + case genericError(Error) +} + +extension AddRecipeError: LocalizedError { + + var title: String { + switch self { + case .noImages: + return "이미지 없음" + case .titleIsEmpty: + return "제목 없음" + case .descriptionTooShort: + return "설명 부족" + case .genericError: + return "업로드 실패" + } + } + + var errorDescription: String? { + switch self { + case .noImages: + return "최소 한 장의 이미지를 추가해 주세요." + case .titleIsEmpty: + return "제목을 입력해 주세요." + case .descriptionTooShort: + return "설명을 10자 이상 입력해 주세요." + case .genericError(let error): + return error.localizedDescription + } + } +} From 58b4cc88df939462863813135c5008d690ff0624 Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Tue, 23 Jul 2024 14:15:14 +0900 Subject: [PATCH 10/12] =?UTF-8?q?Fix:=20didLoadRecipe=EB=A1=9C=20=EB=84=A4?= =?UTF-8?q?=EC=9D=B4=EB=B0=8D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Domain/Interactor/AddRecipeInteractor.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Domain/Interactor/AddRecipeInteractor.swift b/HomeCafeRecipes/HomeCafeRecipes/Domain/Interactor/AddRecipeInteractor.swift index 8f84cc3..b5b0417 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Domain/Interactor/AddRecipeInteractor.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Domain/Interactor/AddRecipeInteractor.swift @@ -11,7 +11,7 @@ import UIKit import RxSwift protocol AddRecipeInteractorDelegate: AnyObject { - func didLoadRecipeData(viewModel: AddRecipeViewModel) + func didLoadRecipe(viewModel: AddRecipeViewModel) } protocol AddRecipeInteractor { @@ -64,6 +64,6 @@ class AddRecipeInteractorImpl: AddRecipeInteractor { func loadRecipeData() { let viewModel = AddRecipeViewModel(images: recipeImages, title: recipeTitle, description: recipeDescription) - delegate?.didLoadRecipeData(viewModel: viewModel) + delegate?.didLoadRecipe(viewModel: viewModel) } } From 54cdfcaf289f4e1b5b9434fba2775930b466629d Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Tue, 23 Jul 2024 14:15:43 +0900 Subject: [PATCH 11/12] =?UTF-8?q?Fix:=20final=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HomeCafeRecipes/Domain/UseCases/AddRecipeUseCase.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Domain/UseCases/AddRecipeUseCase.swift b/HomeCafeRecipes/HomeCafeRecipes/Domain/UseCases/AddRecipeUseCase.swift index 23eb44a..4645a16 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Domain/UseCases/AddRecipeUseCase.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Domain/UseCases/AddRecipeUseCase.swift @@ -19,7 +19,7 @@ protocol AddRecipeUseCase { ) -> Single> } -class AddRecipeUseCaseImpl: AddRecipeUseCase { +final class AddRecipeUseCaseImpl: AddRecipeUseCase { private let repository: AddRecipeRepository init(repository: AddRecipeRepository) { From ed32a8369ab0dd4d175407e921f5c74b7fab7bba Mon Sep 17 00:00:00 2001 From: GeonH0 Date: Tue, 23 Jul 2024 14:18:07 +0900 Subject: [PATCH 12/12] =?UTF-8?q?Fix:=20=EC=A4=84=EB=B0=94=EA=BF=88=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HomeCafeRecipes/Data/Network/NetworkService.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/HomeCafeRecipes/HomeCafeRecipes/Data/Network/NetworkService.swift b/HomeCafeRecipes/HomeCafeRecipes/Data/Network/NetworkService.swift index ec7ce2e..1baf3dc 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Data/Network/NetworkService.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Data/Network/NetworkService.swift @@ -47,8 +47,7 @@ class BaseNetworkService: NetworkService { url: URL, parameters: [String: Any], imageDatas: [Data], responseType: T.Type - ) - -> Single { + ) -> Single { return Single.create { single in var formDataRequest = MultipartFormDataRequest(url: url)