-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #18 from f-lab-edu/feature/UploadDomainData
레시피 업로드 Domain, Data 영역을 정의해 보았습니다.
- Loading branch information
Showing
10 changed files
with
1,505 additions
and
1,056 deletions.
There are no files selected for viewing
2,113 changes: 1,057 additions & 1,056 deletions
2,113
HomeCafeRecipes/HomeCafeRecipes.xcodeproj/project.pbxproj
Large diffs are not rendered by default.
Oops, something went wrong.
15 changes: 15 additions & 0 deletions
15
HomeCafeRecipes/HomeCafeRecipes/Data/Network/DTO/RecipeUploadDTO.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
50 changes: 50 additions & 0 deletions
50
HomeCafeRecipes/HomeCafeRecipes/Data/Network/DTO/RecipeUploadResponseDTO.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() | ||
) | ||
} | ||
} |
60 changes: 60 additions & 0 deletions
60
HomeCafeRecipes/HomeCafeRecipes/Data/Network/MultipartFormDataRequest.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
HomeCafeRecipes/HomeCafeRecipes/Data/Network/RecipePostService.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<Recipe> | ||
} | ||
|
||
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<Recipe> { | ||
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<RecipeUploadResponseDTO>.self | ||
) | ||
.map { $0.data.toDomain() } | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
HomeCafeRecipes/HomeCafeRecipes/Data/Repositories/AddRecipeRepository.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<Recipe> | ||
} | ||
|
||
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<Recipe> { | ||
let recipeUploadDTO = RecipeUploadDTO( | ||
userID: userID, | ||
recipeType: recipeType, | ||
recipeName: title, | ||
recipeDescription: description | ||
) | ||
return recipePostService.postRecipe(recipe: recipeUploadDTO, images: images) | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
HomeCafeRecipes/HomeCafeRecipes/Domain/Entities/AddRecipeError.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} | ||
} | ||
} |
Oops, something went wrong.