diff --git a/HomeCafeRecipes/HomeCafeRecipes.xcodeproj/project.pbxproj b/HomeCafeRecipes/HomeCafeRecipes.xcodeproj/project.pbxproj index 2eefc42..509dc8c 100644 --- a/HomeCafeRecipes/HomeCafeRecipes.xcodeproj/project.pbxproj +++ b/HomeCafeRecipes/HomeCafeRecipes.xcodeproj/project.pbxproj @@ -16,68 +16,65 @@ 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 */; }; + 1D166D132C4AD9A700A50963 /* AddRecipeRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166D102C4AD9A700A50963 /* AddRecipeRouter.swift */; }; + 1D166D142C4AD9A700A50963 /* AddRecipeRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166D102C4AD9A700A50963 /* AddRecipeRouter.swift */; }; + 1D166D152C4AD9A700A50963 /* RecipeListRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166D112C4AD9A700A50963 /* RecipeListRouter.swift */; }; + 1D166D162C4AD9A700A50963 /* RecipeListRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166D112C4AD9A700A50963 /* RecipeListRouter.swift */; }; + 1D166D172C4AD9A700A50963 /* Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166D122C4AD9A700A50963 /* Router.swift */; }; + 1D166D182C4AD9A700A50963 /* Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D166D122C4AD9A700A50963 /* Router.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 */; }; + 1D3972572C44168E00495014 /* DateFormatter+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D3972562C44168E00495014 /* DateFormatter+Extensions.swift */; }; + 1D39725A2C4416A300495014 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D3972582C4416A300495014 /* User.swift */; }; + 1D39725B2C4416A300495014 /* Comment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D3972592C4416A300495014 /* Comment.swift */; }; + 1D39725F2C4416CE00495014 /* RecipeListMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D39725D2C4416CE00495014 /* RecipeListMapper.swift */; }; + 1D3972622C4416E400495014 /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D3972612C4416E400495014 /* UIView+Extensions.swift */; }; + 1D3972642C4416F500495014 /* UserDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D3972632C4416F400495014 /* UserDTO.swift */; }; + 1D3972662C44171100495014 /* RecipeListItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D3972652C44171100495014 /* RecipeListItemViewModel.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 +100,9 @@ 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 = ""; }; + 1D166D102C4AD9A700A50963 /* AddRecipeRouter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddRecipeRouter.swift; sourceTree = ""; }; + 1D166D112C4AD9A700A50963 /* RecipeListRouter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeListRouter.swift; sourceTree = ""; }; + 1D166D122C4AD9A700A50963 /* Router.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Router.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 +114,42 @@ 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 = ""; }; + 1D3972562C44168E00495014 /* DateFormatter+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DateFormatter+Extensions.swift"; sourceTree = ""; }; + 1D3972582C4416A300495014 /* User.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = ""; }; + 1D3972592C4416A300495014 /* Comment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Comment.swift; sourceTree = ""; }; + 1D39725D2C4416CE00495014 /* RecipeListMapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeListMapper.swift; sourceTree = ""; }; + 1D3972612C4416E400495014 /* UIView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Extensions.swift"; sourceTree = ""; }; + 1D3972632C4416F400495014 /* UserDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDTO.swift; sourceTree = ""; }; + 1D3972652C44171100495014 /* RecipeListItemViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecipeListItemViewModel.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 +185,11 @@ 1D12839F2C15E7A700C5A870 /* Entities */ = { isa = PBXGroup; children = ( - - 1DDE912A2C3671EC0078DFD3 /* Comment.swift */, - 1DDE91292C3671EC0078DFD3 /* User.swift */, - 1D95A0A72C37C7D400F09077 /* RecipeDetailError.swift */, 1D1283A12C15E94300C5A870 /* Recipe.swift */, - 1D7368C82C3443A1000EF904 /* Comment.swift */, - 1D7368C92C3443A1000EF904 /* User.swift */, + 1D3972592C4416A300495014 /* Comment.swift */, + 1D3972582C4416A300495014 /* User.swift */, 1D1283A32C15EA8100C5A870 /* RecipeType.swift */, + 1D95A0A52C37C79500F09077 /* RecipeDetailError.swift */, ); path = Entities; sourceTree = ""; @@ -220,9 +198,8 @@ isa = PBXGroup; children = ( 1D1283A92C15EBCF00C5A870 /* SearchFeedUseCase.swift */, - 1DDE912D2C3671FD0078DFD3 /* FetchRecipeDetailUseCase.swift */, - 1D7368D12C34FADD000EF904 /* FetchRecipeDetailUseCase.swift */, 1D1283AB2C15EBE600C5A870 /* FetchFeedListUseCase.swift */, + 1D439E9B2C2C58DD008530A5 /* FetchRecipeDetailUseCase.swift */, ); path = UseCases; sourceTree = ""; @@ -248,13 +225,22 @@ children = ( 1D4741CB2C1B4F8D009381CE /* DTO */, 1D1283C92C16D9C600C5A870 /* RecipeFetchService.swift */, - 1DDE913C2C3672490078DFD3 /* RecipeDetailFetchService.swift */, 1DE19EB02C1B42200031804A /* NetworkService.swift */, - 1D60CC442C3F932D00D08FA3 /* APIConfig.swift */, + 1D60CC3C2C3E4F1600D08FA3 /* APIConfig.swift */, ); path = Network; sourceTree = ""; }; + 1D166D0F2C4AD9A700A50963 /* Router */ = { + isa = PBXGroup; + children = ( + 1D166D102C4AD9A700A50963 /* AddRecipeRouter.swift */, + 1D166D112C4AD9A700A50963 /* RecipeListRouter.swift */, + 1D166D122C4AD9A700A50963 /* Router.swift */, + ); + path = Router; + sourceTree = ""; + }; 1D2C16D92BE532B700C04508 = { isa = PBXGroup; children = ( @@ -280,15 +266,10 @@ 1D2C16E42BE532B700C04508 /* HomeCafeRecipes */ = { isa = PBXGroup; children = ( - 1DDE91312C3672170078DFD3 /* Coordinators */, - 1DDE91262C3671DB0078DFD3 /* Utilities */, - 1DDE911F2C3671840078DFD3 /* Resources */, - 1DDE911A2C36717B0078DFD3 /* Extensions */, - - 1D95A0A22C37B0E200F09077 /* Resources */, - 1D7368E52C34FB66000EF904 /* Coordinators */, - 1D7368CC2C344403000EF904 /* Utilities */, - 1D7368B42C3442C8000EF904 /* Extensions */, + 1D166D0F2C4AD9A700A50963 /* Router */, + 1D3972552C44168E00495014 /* Utilities */, + 1DF829B52C2A7C8600C337FC /* Extensions */, + 1DF829B22C2A7A0B00C337FC /* Resources */, 1DE19EB22C1B422F0031804A /* Presentation */, 1D1283AD2C16974B00C5A870 /* Data */, 1D740B402C15E6680001B704 /* Domain */, @@ -306,6 +287,8 @@ isa = PBXGroup; children = ( 1D2C16FC2BE532B800C04508 /* HomeCafeRecipesTests.swift */, + 1DDE90CE2C3590C40078DFD3 /* AddRecipeTests.swift */, + 1D6958D72C3D5A80008604B3 /* RecipeDeatilInteractorTests.swift */, ); path = HomeCafeRecipesTests; sourceTree = ""; @@ -319,147 +302,69 @@ path = HomeCafeRecipesUITests; sourceTree = ""; }; - 1D4741CB2C1B4F8D009381CE /* DTO */ = { + 1D2C6F612C2446AF004BB54E /* Tabbar */ = { isa = PBXGroup; children = ( - 1D7368C62C344378000EF904 /* UserDTO.swift */, - 1D4741CC2C1B4F8D009381CE /* RecipeImageDTO.swift */, - 1DDE91402C3672850078DFD3 /* RecipeDetailDTO.swift */, - 1D4741CD2C1B4F8D009381CE /* RecipeDTO.swift */, - 1DDE913A2C3672410078DFD3 /* UserDTO.swift */, - 1D7368D72C34FB07000EF904 /* RecipeDetailDTO.swift */, - 1D4741CE2C1B4F8D009381CE /* RecipePageDTO.swift */, - 1D4741CF2C1B4F8D009381CE /* NetworkResponseDTO.swift */, + 1D2C6F642C2446D8004BB54E /* MainTabBarController.swift */, ); - path = DTO; - sourceTree = ""; - }; - 1D7368B42C3442C8000EF904 /* Extensions */ = { - isa = PBXGroup; - children = ( - 1D7368B52C3442C8000EF904 /* String+Validation.swift */, - 1D7368B62C3442C8000EF904 /* UIImageViewImageLoading.swift */, - ); - path = Extensions; + path = Tabbar; sourceTree = ""; }; - 1D7368CC2C344403000EF904 /* Utilities */ = { + 1D3972552C44168E00495014 /* Utilities */ = { isa = PBXGroup; children = ( - 1D7368CD2C344403000EF904 /* DateFormatter+Extensions.swift */, + 1D3972562C44168E00495014 /* DateFormatter+Extensions.swift */, ); path = Utilities; sourceTree = ""; }; - 1D7368DD2C34FB38000EF904 /* Feed */ = { + 1D39725C2C4416CE00495014 /* Mapper */ = { isa = PBXGroup; children = ( - 1D7368DE2C34FB38000EF904 /* View */, - 1D7368E12C34FB38000EF904 /* RecipeDetailViewModel.swift */, + 1D39725D2C4416CE00495014 /* RecipeListMapper.swift */, ); - path = Feed; + name = Mapper; + path = ../../../../../HomeCafeRecipesLocal/HomeCafeRecipes/HomeCafeRecipes/Presentation/Mapper; 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 */ = { + 1D4741CB2C1B4F8D009381CE /* DTO */ = { isa = PBXGroup; children = ( - 1D7368E92C34FBF7000EF904 /* MainTabBarController.swift */, + 1D4741CC2C1B4F8D009381CE /* RecipeImageDTO.swift */, + 1D3972632C4416F400495014 /* UserDTO.swift */, + 1D4741CD2C1B4F8D009381CE /* RecipeDTO.swift */, + 1D4741CE2C1B4F8D009381CE /* RecipePageDTO.swift */, + 1D4741CF2C1B4F8D009381CE /* NetworkResponseDTO.swift */, + 1D73686D2C305757000EF904 /* RecipeDetailDTO.swift */, ); - path = Tabbar; + path = DTO; sourceTree = ""; }; 1D740B402C15E6680001B704 /* Domain */ = { isa = PBXGroup; children = ( - 1DF829AF2C299F1F00C337FC /* Interactor */, + 1DE19EA12C1B41FE0031804A /* Interactor */, 1D1283A02C15E92C00C5A870 /* UseCases */, 1D12839F2C15E7A700C5A870 /* Entities */, ); path = Domain; sourceTree = ""; }; - - 1DDE911A2C36717B0078DFD3 /* Extensions */ = { + 1DE19EA12C1B41FE0031804A /* Interactor */ = { isa = PBXGroup; children = ( - 1DDE911B2C36717B0078DFD3 /* String+Validation.swift */, - 1DDE911C2C36717B0078DFD3 /* UIImageViewImageLoading.swift */, + 1D4741D62C1B4FF4009381CE /* RecipeListInteractor.swift */, + 1D439EA12C2C6997008530A5 /* RecipeDetailInteractor.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 */ = { - isa = PBXGroup; - children = ( - 1DDE91322C3672170078DFD3 /* RecipeDetailCoordinator.swift */, - ); - path = Coordinators; - sourceTree = ""; - }; - 1DDFFD822C1C09AB0083B077 /* Mapper */ = { - isa = PBXGroup; - children = ( - 1DDE91242C3671B20078DFD3 /* RecipeListMapper.swift */, - - 1DDFFD822C1C09AB0083B077 /* Mapper */ = { - isa = PBXGroup; - children = ( - 1D7368B92C3442DE000EF904 /* RecipeListMapper.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 */, ); path = Repositories; sourceTree = ""; @@ -467,22 +372,19 @@ 1DE19EB22C1B422F0031804A /* Presentation */ = { isa = PBXGroup; children = ( - 1DDE91222C3671910078DFD3 /* CustomNavigationBar.swift */, - 1D7368E82C34FBF7000EF904 /* Tabbar */, - 1D7368DD2C34FB38000EF904 /* Feed */, - 1D7368DB2C34FB32000EF904 /* CustomNavigationBar.swift */, - - 1DDFFD822C1C09AB0083B077 /* Mapper */, + 1D39725C2C4416CE00495014 /* Mapper */, + 1D2C6F612C2446AF004BB54E /* Tabbar */, + 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 +393,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 = ( + 1D3972652C44171100495014 /* RecipeListItemViewModel.swift */, 1DE19EB92C1B422F0031804A /* View */, ); path = FeedList; @@ -509,7 +411,6 @@ 1DE19EB92C1B422F0031804A /* View */ = { isa = PBXGroup; children = ( - 1DE19EBA2C1B422F0031804A /* RecipeListItemViewModel.swift */, 1DE19EBB2C1B422F0031804A /* SearchBar.swift */, 1DE19EBC2C1B422F0031804A /* RecipeListViewController.swift */, 1DE19EBD2C1B422F0031804A /* RecipeListView.swift */, @@ -518,14 +419,22 @@ 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 */, + 1D3972612C4416E400495014 /* UIView+Extensions.swift */, + ); + path = Extensions; sourceTree = ""; }; /* End PBXGroup section */ @@ -669,77 +578,50 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 1DF829B12C299F1F00C337FC /* RecipeListInteractor.swift in Sources */, + 1D39725B2C4416A300495014 /* Comment.swift in Sources */, + 1D439E9E2C2C598A008530A5 /* RecipeDetailRepository.swift in Sources */, + 1D2C6F6C2C27051D004BB54E /* CustomNavigationBar.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 */, - 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 */, + 1D3972622C4416E400495014 /* UIView+Extensions.swift in Sources */, 1D2C16E62BE532B700C04508 /* AppDelegate.swift in Sources */, - 1DDE91282C3671DB0078DFD3 /* DateFormatter+Extensions.swift in Sources */, - 1DDE91332C3672170078DFD3 /* RecipeDetailCoordinator.swift in Sources */, - 1DDE91382C36722A0078DFD3 /* RecipeDetailViewController.swift in Sources */, + 1D3972662C44171100495014 /* RecipeListItemViewModel.swift in Sources */, 1DE19EB12C1B42200031804A /* NetworkService.swift in Sources */, - - 1DDE913F2C3672720078DFD3 /* RecipeDetailRepository.swift in Sources */, + 1D166D132C4AD9A700A50963 /* AddRecipeRouter.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 */, - + 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 */, + 1DF829B42C2A7A7D00C337FC /* Fonts.swift in Sources */, + 1D39725A2C4416A300495014 /* User.swift in Sources */, 1D4741D22C1B4F8D009381CE /* RecipeDTO.swift in Sources */, + 1DE19EC02C1B422F0031804A /* RecipeDetailView.swift in Sources */, 1D1283AA2C15EBCF00C5A870 /* SearchFeedUseCase.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 */, + 1D73686E2C305757000EF904 /* RecipeDetailDTO.swift in Sources */, + 1D39725F2C4416CE00495014 /* RecipeListMapper.swift in Sources */, + 1D4741D72C1B4FF4009381CE /* RecipeListInteractor.swift in Sources */, + 1D166D172C4AD9A700A50963 /* Router.swift in Sources */, 1DE19E9D2C1B3DC10031804A /* SceneDelegate.swift in Sources */, - 1DDE91232C3671920078DFD3 /* CustomNavigationBar.swift in Sources */, + 1D3972642C4416F500495014 /* UserDTO.swift in Sources */, 1D4741D12C1B4F8D009381CE /* RecipeImageDTO.swift in Sources */, - 1DDE91412C3672850078DFD3 /* RecipeDetailDTO.swift in Sources */, 1DE19EA72C1B420A0031804A /* FeedListRepository.swift in Sources */, + 1D166D152C4AD9A700A50963 /* RecipeListRouter.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 */, + 1DF829B92C2A818D00C337FC /* String+Validation.swift in Sources */, 1DE19EC42C1B422F0031804A /* RecipeListViewController.swift in Sources */, - 1D95A0A82C37C7D400F09077 /* RecipeDetailError.swift in Sources */, + 1DE19EBF2C1B422F0031804A /* RecipeDetailViewModel.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 */, + 1D439E9C2C2C58DD008530A5 /* FetchRecipeDetailUseCase.swift in Sources */, + 1D3972572C44168E00495014 /* DateFormatter+Extensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -747,8 +629,23 @@ 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 */, + 1D166D162C4AD9A700A50963 /* RecipeListRouter.swift in Sources */, + 1D6958D92C3D5AF7008604B3 /* RecipeDetailInteractor.swift in Sources */, 1D2C16FD2BE532B800C04508 /* HomeCafeRecipesTests.swift in Sources */, + 1D6958E42C3D5EA6008604B3 /* NetworkResponseDTO.swift in Sources */, + 1D166D182C4AD9A700A50963 /* Router.swift in Sources */, + 1D6958DB2C3D5C91008604B3 /* Recipe.swift in Sources */, + 1D6958E02C3D5E3D008604B3 /* RecipeDetailError.swift in Sources */, + 1DDE90CF2C3590C40078DFD3 /* AddRecipeTests.swift in Sources */, + 1D6958DA2C3D5BA4008604B3 /* FetchRecipeDetailUseCase.swift in Sources */, + 1D6958E22C3D5E99008604B3 /* RecipeImageDTO.swift in Sources */, + 1D166D142C4AD9A700A50963 /* AddRecipeRouter.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/HomeCafeRecipes/HomeCafeRecipes/Domain/Interactor/RecipeDetailInteractor.swift b/HomeCafeRecipes/HomeCafeRecipes/Domain/Interactor/RecipeDetailInteractor.swift index 187863f..ee47406 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Domain/Interactor/RecipeDetailInteractor.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Domain/Interactor/RecipeDetailInteractor.swift @@ -6,32 +6,24 @@ // import Foundation + import RxSwift protocol RecipeDetailInteractorDelegate: AnyObject { func fetchedRecipe(result: Result) } -protocol InputRecipeDetailInteractor { - func viewDidLoad() -} - -protocol OutputRecipeDetailInteractor { - var recipe: Observable> { get } +protocol RecipeDetailInteractor { + func viewDidLoad() } -class RecipeDetailInteractor: InputRecipeDetailInteractor, OutputRecipeDetailInteractor { - +class RecipeDetailInteractorImpl: RecipeDetailInteractor { + private let fetchRecipeDetailUseCase: FetchRecipeDetailUseCase private let recipeID: Int private let disposeBag = DisposeBag() - private let recipeDetailSubject = PublishSubject>() weak var delegate: RecipeDetailInteractorDelegate? - - var recipe: Observable> { - return recipeDetailSubject.asObservable() - } - + init( fetchRecipeDetailUseCase: FetchRecipeDetailUseCase, recipeID: Int @@ -39,38 +31,18 @@ class RecipeDetailInteractor: InputRecipeDetailInteractor, OutputRecipeDetailInt self.fetchRecipeDetailUseCase = fetchRecipeDetailUseCase self.recipeID = recipeID } - - func setDelegate(_ delegate: RecipeDetailInteractorDelegate) { - self.delegate = delegate - bindOutputs() - } - - private func bindOutputs() { - recipe - .subscribe(onNext: { [weak self] result in - self?.delegate?.fetchedRecipe(result: result) - }) - .disposed(by: disposeBag) - } - + func viewDidLoad() { fetchRecipeDetail() } - + private func fetchRecipeDetail() { fetchRecipeDetailUseCase.execute(recipeID: recipeID) - .subscribe { [weak self] result in - self?.handleResult(result) - } + .subscribe(onSuccess: { [weak self] result in + self?.delegate?.fetchedRecipe(result: result) + }, onFailure: { [weak self] error in + self?.delegate?.fetchedRecipe(result: .failure(error)) + }) .disposed(by: disposeBag) } - - private func handleResult(_ result: Result) { - switch result { - case .success(let recipe): - self.recipeDetailSubject.onNext(.success(recipe)) - case .failure(let error): - self.recipeDetailSubject.onNext(.failure(error)) - } - } } diff --git a/HomeCafeRecipes/HomeCafeRecipes/Domain/Interactor/RecipeListInteractor.swift b/HomeCafeRecipes/HomeCafeRecipes/Domain/Interactor/RecipeListInteractor.swift index b02de71..8ee8f01 100755 --- a/HomeCafeRecipes/HomeCafeRecipes/Domain/Interactor/RecipeListInteractor.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Domain/Interactor/RecipeListInteractor.swift @@ -6,6 +6,7 @@ // import Foundation + import RxSwift protocol RecipeListInteractorDelegate: AnyObject { @@ -13,7 +14,7 @@ protocol RecipeListInteractorDelegate: AnyObject { func showRecipeDetail(ID: Int) } -protocol InputRecipeListInteractor { +protocol RecipeListInteractor { func viewDidLoad() func fetchNextPage() func didSelectItem(ID: Int) @@ -21,16 +22,12 @@ protocol InputRecipeListInteractor { func resetSearch() } -protocol OutputRecipeListInteractor { - var recipes: Observable> { get } -} - -class RecipeListInteractor: InputRecipeListInteractor, OutputRecipeListInteractor { +class RecipeListInteractorImpl: RecipeListInteractor { private let disposeBag = DisposeBag() private let fetchFeedListUseCase: FetchFeedListUseCase private let searchFeedListUseCase: SearchFeedListUseCase - private weak var delegate: RecipeListInteractorDelegate? + weak var delegate: RecipeListInteractorDelegate? private var currentPage: Int = 1 private var isFetching = false @@ -40,34 +37,18 @@ class RecipeListInteractor: InputRecipeListInteractor, OutputRecipeListInteracto private let recipesSubject = BehaviorSubject>(value: .success([])) - var recipes: Observable> { - return recipesSubject.asObservable() - } - init(fetchFeedListUseCase: FetchFeedListUseCase, searchFeedListUseCase: SearchFeedListUseCase) { self.fetchFeedListUseCase = fetchFeedListUseCase self.searchFeedListUseCase = searchFeedListUseCase } - - func setDelegate(_ delegate: RecipeListInteractorDelegate) { - self.delegate = delegate - bindOutputs() - } - - private func bindOutputs() { - recipes - .subscribe(onNext: { [weak self] result in - self?.delegate?.fetchedRecipes(result: result) - }) - .disposed(by: disposeBag) - } - + func viewDidLoad() { fetchRecipes() } func fetchNextPage() { - fetchNextRecipes(nextPage: currentPage) + guard !isFetching else { return } + fetchNextRecipes() } func didSelectItem(ID: Int) { @@ -78,6 +59,7 @@ class RecipeListInteractor: InputRecipeListInteractor, OutputRecipeListInteracto isSearching = false currentSearchQuery = nil currentPage = 1 + allRecipes.removeAll() recipesSubject.onNext(.success([])) fetchRecipes() } @@ -89,9 +71,11 @@ class RecipeListInteractor: InputRecipeListInteractor, OutputRecipeListInteracto isSearching = true currentPage = 1 searchFeedListUseCase.execute(title: title, pageNumber: currentPage) - .subscribe { [weak self] result in + .subscribe(onSuccess: { [weak self] result in self?.handleResult(result) - } + }, onFailure: { [weak self] error in + self?.handleResult(.failure(error)) + }) .disposed(by: disposeBag) } @@ -99,19 +83,23 @@ class RecipeListInteractor: InputRecipeListInteractor, OutputRecipeListInteracto guard !isFetching else { return } isFetching = true fetchFeedListUseCase.execute(pageNumber: currentPage) - .subscribe { [weak self] result in + .subscribe(onSuccess: { [weak self] result in self?.handleResult(result) - } + }, onFailure: { [weak self] error in + self?.handleResult(.failure(error)) + }) .disposed(by: disposeBag) } - private func fetchNextRecipes(nextPage: Int) { + private func fetchNextRecipes() { guard !isFetching else { return } isFetching = true - fetchFeedListUseCase.execute(pageNumber: nextPage) - .subscribe { [weak self] result in + fetchFeedListUseCase.execute(pageNumber: currentPage) + .subscribe(onSuccess: { [weak self] result in self?.handleResult(result) - } + }, onFailure: { [weak self] error in + self?.handleResult(.failure(error)) + }) .disposed(by: disposeBag) } @@ -127,11 +115,10 @@ class RecipeListInteractor: InputRecipeListInteractor, OutputRecipeListInteracto } else { allRecipes.append(contentsOf: recipes) } - self.recipesSubject.onNext(.success(allRecipes)) - self.currentPage += 1 + delegate?.fetchedRecipes(result: .success(allRecipes)) + currentPage += 1 case .failure(let error): - recipesSubject.onNext(.failure(error)) + delegate?.fetchedRecipes(result: .failure(error)) } } - } diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift index c6ec16d..b6d7256 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/Feed/View/RecipeDetailViewController.swift @@ -20,8 +20,7 @@ final class RecipeDetailViewController: UIViewController { init(interactor: RecipeDetailInteractor) { self.interactor = interactor - super.init(nibName: nil, bundle: nil) - self.interactor.setDelegate(self) + super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { @@ -37,7 +36,7 @@ final class RecipeDetailViewController: UIViewController { interactor.viewDidLoad() contentView.customNavigationBar.backButton.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside) } - + private func displayError(_ error: Error) { let alert = UIAlertController(title: "해당 레시피를 로드하는데 실패했습니다.", message: error.localizedDescription, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default)) @@ -60,7 +59,10 @@ extension RecipeDetailViewController: RecipeDetailInteractorDelegate { self.contentView.configure(with: recipeItemViewModel) } case .failure(let error): - self.displayError(error) + DispatchQueue.main.async { + self.displayError(error) + } } } } + diff --git a/HomeCafeRecipes/HomeCafeRecipes/Presentation/FeedList/View/RecipeListViewController.swift b/HomeCafeRecipes/HomeCafeRecipes/Presentation/FeedList/View/RecipeListViewController.swift index 710f217..ac37e81 100644 --- a/HomeCafeRecipes/HomeCafeRecipes/Presentation/FeedList/View/RecipeListViewController.swift +++ b/HomeCafeRecipes/HomeCafeRecipes/Presentation/FeedList/View/RecipeListViewController.swift @@ -13,12 +13,14 @@ final class RecipeListViewController: UIViewController { private var recipes: [RecipeListItemViewModel] = [] private let searchBar = SearchBar() private let recipeListView = RecipeListView() - - init(interactor: RecipeListInteractor) { + private let recipeListMapper = RecipeListMapper() + private let router: RecipeListRouterProtocol + + init(interactor: RecipeListInteractor, router: RecipeListRouterProtocol) { self.interactor = interactor - super.init(nibName: nil, bundle: nil) - self.interactor.setDelegate(self) - + self.router = router + super.init(nibName: nil, bundle: nil) + recipeListView.delegate = self } required init?(coder: NSCoder) { @@ -27,7 +29,6 @@ final class RecipeListViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - recipeListView.delegate = self setupUI() interactor.viewDidLoad() } @@ -36,16 +37,16 @@ final class RecipeListViewController: UIViewController { view.backgroundColor = .white view.addSubview(searchBar) view.addSubview(recipeListView) - + searchBar.translatesAutoresizingMaskIntoConstraints = false recipeListView.translatesAutoresizingMaskIntoConstraints = false - + NSLayoutConstraint.activate([ searchBar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), searchBar.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10), searchBar.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10), searchBar.heightAnchor.constraint(equalToConstant: 50), - + recipeListView.topAnchor.constraint(equalTo: searchBar.bottomAnchor), recipeListView.leadingAnchor.constraint(equalTo: view.leadingAnchor), recipeListView.trailingAnchor.constraint(equalTo: view.trailingAnchor), @@ -54,10 +55,10 @@ final class RecipeListViewController: UIViewController { searchBar.setDelegate(self) } - } // MARK: - UISearchBarDelegate + extension RecipeListViewController: UISearchBarDelegate { func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { if searchText.isBlank { @@ -75,6 +76,7 @@ extension RecipeListViewController: UISearchBarDelegate { } // MARK: - RecipeListInteractorDelegate + extension RecipeListViewController: RecipeListInteractorDelegate { func fetchedRecipes(result: Result<[Recipe], Error>) { switch result { @@ -90,7 +92,7 @@ extension RecipeListViewController: RecipeListInteractorDelegate { } func showRecipeDetail(ID: Int) { - coordinator.showRecipeDetail(from: self, recipeID: ID) + router.navigateToRecipeDetail(from: self, recipeID: ID) } } @@ -100,7 +102,7 @@ extension RecipeListViewController: RecipeListViewDelegate { interactor.didSelectItem(ID: ID) } - func ScrollToBottom() { + func scrollToBottom() { interactor.fetchNextPage() } }