Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

댓글들을 로드하는 기능을 생성하였습니다. #33

Merged
merged 9 commits into from
Oct 8, 2024
62 changes: 62 additions & 0 deletions HomeCafeRecipes/HomeCafeRecipes.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@
objects = {

/* Begin PBXBuildFile section */
1D0173AC2CB162CA00FF04BA /* commentViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D0173AB2CB162CA00FF04BA /* commentViewModel.swift */; };
1D0173AE2CB171DF00FF04BA /* Comment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D0173AD2CB171DF00FF04BA /* Comment.swift */; };
1D0173B02CB1847C00FF04BA /* CommentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D0173AF2CB1847C00FF04BA /* CommentView.swift */; };
1D0173B22CB1856300FF04BA /* CommentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D0173B12CB1856300FF04BA /* CommentViewController.swift */; };
1D0173B42CB185C000FF04BA /* CommentCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D0173B32CB185C000FF04BA /* CommentCell.swift */; };
1D0635E12CB28A8700DCC9EA /* CommentService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D0635E02CB28A8700DCC9EA /* CommentService.swift */; };
1D0635E42CB28B8700DCC9EA /* CommentInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D0635E32CB28B8700DCC9EA /* CommentInteractor.swift */; };
1D0635E62CB2A63200DCC9EA /* FetchCommentUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D0635E52CB2A63200DCC9EA /* FetchCommentUsecase.swift */; };
1D0635E82CB2AA0600DCC9EA /* CommentListRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D0635E72CB2AA0600DCC9EA /* CommentListRepository.swift */; };
1D0635EA2CB2B0CD00DCC9EA /* CommentDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D0635E92CB2B0CD00DCC9EA /* CommentDTO.swift */; };
1D0BE5822CB5652500F54A26 /* CommnetMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D0BE5812CB5652500F54A26 /* CommnetMapper.swift */; };
1D0BE5832CB575B800F54A26 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1D2C16EE2BE532B800C04508 /* Assets.xcassets */; };
1D1283A22C15E94300C5A870 /* Recipe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D1283A12C15E94300C5A870 /* Recipe.swift */; };
1D1283A42C15EA8100C5A870 /* RecipeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D1283A32C15EA8100C5A870 /* RecipeType.swift */; };
1D1283AA2C15EBCF00C5A870 /* SearchFeedUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D1283A92C15EBCF00C5A870 /* SearchFeedUseCase.swift */; };
Expand Down Expand Up @@ -156,6 +168,17 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
1D0173AB2CB162CA00FF04BA /* commentViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = commentViewModel.swift; sourceTree = "<group>"; };
1D0173AD2CB171DF00FF04BA /* Comment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Comment.swift; sourceTree = "<group>"; };
1D0173AF2CB1847C00FF04BA /* CommentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentView.swift; sourceTree = "<group>"; };
1D0173B12CB1856300FF04BA /* CommentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentViewController.swift; sourceTree = "<group>"; };
1D0173B32CB185C000FF04BA /* CommentCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentCell.swift; sourceTree = "<group>"; };
1D0635E02CB28A8700DCC9EA /* CommentService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentService.swift; sourceTree = "<group>"; };
1D0635E32CB28B8700DCC9EA /* CommentInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentInteractor.swift; sourceTree = "<group>"; };
1D0635E52CB2A63200DCC9EA /* FetchCommentUsecase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchCommentUsecase.swift; sourceTree = "<group>"; };
1D0635E72CB2AA0600DCC9EA /* CommentListRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentListRepository.swift; sourceTree = "<group>"; };
1D0635E92CB2B0CD00DCC9EA /* CommentDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentDTO.swift; sourceTree = "<group>"; };
1D0BE5812CB5652500F54A26 /* CommnetMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommnetMapper.swift; sourceTree = "<group>"; };
1D1283A12C15E94300C5A870 /* Recipe.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Recipe.swift; sourceTree = "<group>"; };
1D1283A32C15EA8100C5A870 /* RecipeType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecipeType.swift; sourceTree = "<group>"; };
1D1283A92C15EBCF00C5A870 /* SearchFeedUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchFeedUseCase.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -282,6 +305,25 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
1D0173AA2CB15E2A00FF04BA /* comment */ = {
isa = PBXGroup;
children = (
1D0635E22CB28ADE00DCC9EA /* View */,
1D0173AB2CB162CA00FF04BA /* commentViewModel.swift */,
1D0173AF2CB1847C00FF04BA /* CommentView.swift */,
1D0173B12CB1856300FF04BA /* CommentViewController.swift */,
1D0173B32CB185C000FF04BA /* CommentCell.swift */,
);
path = comment;
sourceTree = "<group>";
};
1D0635E22CB28ADE00DCC9EA /* View */ = {
isa = PBXGroup;
children = (
);
path = View;
sourceTree = "<group>";
};
1D12839F2C15E7A700C5A870 /* Entities */ = {
isa = PBXGroup;
children = (
Expand All @@ -293,6 +335,7 @@
1DD4F7092C80C947003E9D9D /* LoginError.swift */,
1D2398B32C8DC23500626F0C /* SignUpError.swift */,
1DDF485A2C93DFC9000A082E /* CheckEmailError.swift */,
1D0173AD2CB171DF00FF04BA /* Comment.swift */,
);
path = Entities;
sourceTree = "<group>";
Expand All @@ -307,6 +350,7 @@
1D7641442C81BE90002AC68F /* LoginUseCase.swift */,
1D2398B12C8DC07800626F0C /* SignUpUseCase.swift */,
1DFC961F2C908739006C3309 /* CheckEmailUsecase.swift */,
1D0635E52CB2A63200DCC9EA /* FetchCommentUsecase.swift */,
);
path = UseCases;
sourceTree = "<group>";
Expand Down Expand Up @@ -338,6 +382,7 @@
1D39726B2C458CE100495014 /* MultipartFormDataRequest.swift */,
1D7641482C831295002AC68F /* LoginService.swift */,
1DBD90B82C91BDAC00184F67 /* SignUpService.swift */,
1D0635E02CB28A8700DCC9EA /* CommentService.swift */,
);
path = Network;
sourceTree = "<group>";
Expand Down Expand Up @@ -451,6 +496,7 @@
1D7368852C33D7BE000EF904 /* RecipeUploadResponseDTO.swift */,
1DBD90BA2C91DE1600184F67 /* EmptyResponse.swift */,
1DDF485C2C9405CF000A082E /* CheckEmailRespones.swift */,
1D0635E92CB2B0CD00DCC9EA /* CommentDTO.swift */,
);
path = DTO;
sourceTree = "<group>";
Expand Down Expand Up @@ -487,6 +533,7 @@
isa = PBXGroup;
children = (
1D3972672C44185B00495014 /* RecipeListMapper.swift */,
1D0BE5812CB5652500F54A26 /* CommnetMapper.swift */,
);
path = Mapper;
sourceTree = "<group>";
Expand All @@ -499,6 +546,7 @@
1D73686F2C32BFBB000EF904 /* AddRecipeInteractor.swift */,
1D96FDA92C7F55E600EFC657 /* LoginInteractor.swift */,
1DF6E1422C8C561E005E8875 /* SignUpInteractor.swift */,
1D0635E32CB28B8700DCC9EA /* CommentInteractor.swift */,
);
path = Interactor;
sourceTree = "<group>";
Expand All @@ -513,13 +561,15 @@
1D7641462C831192002AC68F /* LoginRepository.swift */,
1DFC961B2C90809D006C3309 /* SignUpRepository.swift */,
1DFC961D2C908723006C3309 /* CheckEmailRepository.swift */,
1D0635E72CB2AA0600DCC9EA /* CommentListRepository.swift */,
);
path = Repositories;
sourceTree = "<group>";
};
1DE19EB22C1B422F0031804A /* Presentation */ = {
isa = PBXGroup;
children = (
1D0173AA2CB15E2A00FF04BA /* comment */,
1DF0D1A72C7DF99F00E2C94C /* Login */,
1D2C6F662C24697F004BB54E /* UploadRecipe */,
1D2C6F612C2446AF004BB54E /* Tabbar */,
Expand Down Expand Up @@ -724,6 +774,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1D0BE5832CB575B800F54A26 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -751,6 +802,7 @@
1DBB550A2C8421920009E033 /* SignUpViewController.swift in Sources */,
1D439E9E2C2C598A008530A5 /* RecipeDetailRepository.swift in Sources */,
1D2C6F6C2C27051D004BB54E /* CustomNavigationBar.swift in Sources */,
1D0173B42CB185C000FF04BA /* CommentCell.swift in Sources */,
1DD4F70A2C80C947003E9D9D /* LoginError.swift in Sources */,
1D3972682C44185B00495014 /* RecipeListMapper.swift in Sources */,
1D2C16EA2BE532B700C04508 /* ViewController.swift in Sources */,
Expand All @@ -768,6 +820,7 @@
1DE19EB12C1B42200031804A /* NetworkService.swift in Sources */,
1DC7CC322C283C0200796889 /* RecipeUploadImgaeCell.swift in Sources */,
1D7368782C32E7FE000EF904 /* RecipePostService.swift in Sources */,
1D0635EA2CB2B0CD00DCC9EA /* CommentDTO.swift in Sources */,
1D2398B42C8DC23500626F0C /* SignUpError.swift in Sources */,
1DBC63662C47D23000DA00C2 /* AddRecipeError.swift in Sources */,
1D95A0A62C37C79500F09077 /* RecipeDetailError.swift in Sources */,
Expand All @@ -784,8 +837,12 @@
1DF829B72C2A7CDC00C337FC /* UIImageViewImageLoading.swift in Sources */,
1D5AEE532C592A9900BBD5F0 /* RecipeListItemViewModel.swift in Sources */,
1D60CC3D2C3E4F1600D08FA3 /* APIConfig.swift in Sources */,
1D0173B02CB1847C00FF04BA /* CommentView.swift in Sources */,
1D0635E42CB28B8700DCC9EA /* CommentInteractor.swift in Sources */,
1D6F99492C9291B700430FD8 /* UIViewController+Alert.swift in Sources */,
1D1283A42C15EA8100C5A870 /* RecipeType.swift in Sources */,
1D0173AC2CB162CA00FF04BA /* commentViewModel.swift in Sources */,
1D0635E62CB2A63200DCC9EA /* FetchCommentUsecase.swift in Sources */,
1D7641472C831192002AC68F /* LoginRepository.swift in Sources */,
1DF829B42C2A7A7D00C337FC /* Fonts.swift in Sources */,
1DF0D1AD2C7DF9BB00E2C94C /* LoginView.swift in Sources */,
Expand All @@ -796,19 +853,23 @@
1DBB55062C8418490009E033 /* LoginRouter.swift in Sources */,
1DFC961E2C908723006C3309 /* CheckEmailRepository.swift in Sources */,
1D1283AA2C15EBCF00C5A870 /* SearchFeedUseCase.swift in Sources */,
1D0BE5822CB5652500F54A26 /* CommnetMapper.swift in Sources */,
1DE19EA82C1B420A0031804A /* SearchFeedListRepository.swift in Sources */,
1DE19EC32C1B422F0031804A /* SearchBar.swift in Sources */,
1D439EA22C2C6997008530A5 /* RecipeDetailInteractor.swift in Sources */,
1D73686E2C305757000EF904 /* RecipeDetailDTO.swift in Sources */,
1D0635E12CB28A8700DCC9EA /* CommentService.swift in Sources */,
1D4741D72C1B4FF4009381CE /* RecipeListInteractor.swift in Sources */,
1D2398B22C8DC07800626F0C /* SignUpUseCase.swift in Sources */,
1DC7CC342C294F9200796889 /* SelectImageCell.swift in Sources */,
1DE19E9D2C1B3DC10031804A /* SceneDelegate.swift in Sources */,
1D0173B22CB1856300FF04BA /* CommentViewController.swift in Sources */,
1DDF485B2C93DFC9000A082E /* CheckEmailError.swift in Sources */,
1D4741D12C1B4F8D009381CE /* RecipeImageDTO.swift in Sources */,
1DF6E1432C8C561E005E8875 /* SignUpInteractor.swift in Sources */,
1DF0D1AB2C7DF9B500E2C94C /* LoginViewController.swift in Sources */,
1D7368742C32CF09000EF904 /* AddRecipeRepository.swift in Sources */,
1D0635E82CB2AA0600DCC9EA /* CommentListRepository.swift in Sources */,
1DE19EA72C1B420A0031804A /* FeedListRepository.swift in Sources */,
1DF0D19B2C7B92D600E2C94C /* UserDTO.swift in Sources */,
1DE19EC62C1B422F0031804A /* RecipeListCell.swift in Sources */,
Expand All @@ -822,6 +883,7 @@
1DE19EC42C1B422F0031804A /* RecipeListViewController.swift in Sources */,
1DE19EBF2C1B422F0031804A /* RecipeDetailViewModel.swift in Sources */,
1D1283A22C15E94300C5A870 /* Recipe.swift in Sources */,
1D0173AE2CB171DF00FF04BA /* Comment.swift in Sources */,
1D1283CA2C16D9C600C5A870 /* RecipeFetchService.swift in Sources */,
1D6958D42C3D059E008604B3 /* RecipeListRouter.swift in Sources */,
1D4741D42C1B4F8D009381CE /* NetworkResponseDTO.swift in Sources */,
Expand Down
37 changes: 37 additions & 0 deletions HomeCafeRecipes/HomeCafeRecipes/Data/Network/CommentService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// CommentService.swift
// HomeCafeRecipes
//
// Created by 김건호 on 10/6/24.
//

import UIKit

import RxSwift

protocol CommentService {
func fetchComment(recipeID: Int) -> Single<[Comment]>
}

final class CommentServiceImpl: CommentService {
private let networkService: NetworkService

init(networkService: NetworkService) {
self.networkService = networkService
}

private func makeURL(ednpoint: String) -> URL {
return APIConfig().baseURL.appendingPathComponent(ednpoint)
}

func fetchComment(recipeID: Int) -> Single<[Comment]> {
let url = makeURL(ednpoint: "comments/\(recipeID)")

return networkService.getRequest(
url: url,
responseType: NetworkResponseDTO<[CommentDTO]>.self
).map { response in
response.data.map { $0.toDomain() }
}
}
}
41 changes: 41 additions & 0 deletions HomeCafeRecipes/HomeCafeRecipes/Data/Network/DTO/CommentDTO.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// CommentDTO.swift
// HomeCafeRecipes
//
// Created by 김건호 on 10/6/24.
//

import Foundation

struct CommentDTO: Decodable {

let commentID: Int
let comment: String
let commentLikeCount: Int
let isLiked: Bool
let createdAt: String
let writer: UserDTO

enum CodingKeys: String, CodingKey {
case commentID = "commentId"
case comment = "content"
case commentLikeCount = "commentLikesCnt"
case isLiked = "isLiked"
case createdAt = "createdAt"
case writer = "writer"
}
}

extension CommentDTO {
func toDomain() -> Comment{
return Comment (
commentID: commentID,
comment: comment,
commentLikeCount: commentLikeCount,
isLiked: isLiked,
createAt: DateFormatter.iso8601.date(from: createdAt) ?? Date(),
writer: writer.toDomain()
)

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// CommentListRepository.swift
// HomeCafeRecipes
//
// Created by 김건호 on 10/6/24.
//

import Foundation

import RxSwift

protocol CommentListRepository {
func fetchComments(recipeID: Int) -> Single<[Comment]>
}

final class CommentListRepositoryImpl: CommentListRepository {
private let commnetServie: CommentService

init(commnetServie: CommentService) {
self.commnetServie = commnetServie
}

func fetchComments(recipeID: Int) -> Single<[Comment]> {
return commnetServie.fetchComment(recipeID: recipeID)
}
}
17 changes: 17 additions & 0 deletions HomeCafeRecipes/HomeCafeRecipes/Domain/Entities/Comment.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// Comment.swift
// HomeCafeRecipes
//
// Created by 김건호 on 10/5/24.
//

import Foundation

struct Comment {
let commentID: Int
let comment: String
let commentLikeCount: Int
let isLiked: Bool
let createAt: Date
let writer: User
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// CommentInteractor.swift
// HomeCafeRecipes
//
// Created by 김건호 on 10/6/24.
//

import Foundation

import RxSwift

protocol CommentInteractorDelegate: AnyObject {
func fetchedComments(result: Result<[Comment], Error>)
}

protocol CommentInteractor {
func loadComment(recipeID: Int)
}

final class CommentInteractorImpl: CommentInteractor {
private let disposeBag = DisposeBag()
private let usecase: FetchCommentUsecase
private var allComments: [Comment] = []
weak var delegate: CommentInteractorDelegate?

init(usecase: FetchCommentUsecase) {
self.usecase = usecase
}

func loadComment(recipeID: Int) {
usecase.execute(recipeID: recipeID)
.subscribe(onSuccess: { [weak self] comments in
self?.handleResult(.success(comments))
}, onError: { [weak self] error in
self?.handleResult(.failure(error))
})
.disposed(by: disposeBag)
}

private func handleResult(_ result: Result<[Comment], Error>) {
switch result {
case .success(let comments):
if comments.isEmpty {
return
}
allComments = comments
delegate?.fetchedComments(result: .success(allComments))
case .failure(let error):
delegate?.fetchedComments(result: .failure(error))
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// FetchCommentUsecase.swift
// HomeCafeRecipes
//
// Created by 김건호 on 10/6/24.
//

import RxSwift

protocol FetchCommentUsecase{
func execute(recipeID: Int) -> Single<[Comment]>
}


final class FetchCommentUsecaseImpl: FetchCommentUsecase{
private let repository: CommentListRepository

init(repository: CommentListRepository) {
self.repository = repository
}

func execute(recipeID: Int) -> Single<[Comment]> {
return repository.fetchComments(recipeID: recipeID)
}
}
Loading
Loading