diff --git a/FLINT/Data/Sources/DTO/Collection/CollectionDetailDTO.swift b/FLINT/Data/Sources/DTO/Collection/CollectionDetailDTO.swift index ae2d9515..818a477d 100644 --- a/FLINT/Data/Sources/DTO/Collection/CollectionDetailDTO.swift +++ b/FLINT/Data/Sources/DTO/Collection/CollectionDetailDTO.swift @@ -65,7 +65,7 @@ extension CollectionDetailDTO.AuthorDTO { id: unwrap(id), nickname: nickname ?? "", profileImageUrl: URL(string: profileImageUrl ?? ""), - role: unwrap(UserRole(rawValue: userRole ?? "")) + role: UserRole(rawValue: userRole ?? "") ?? .unknown ) } } diff --git a/FLINT/Data/Sources/DTO/Content/OTTPlatformsDTO.swift b/FLINT/Data/Sources/DTO/Content/OTTPlatformsDTO.swift index 69786aa9..a05d983d 100644 --- a/FLINT/Data/Sources/DTO/Content/OTTPlatformsDTO.swift +++ b/FLINT/Data/Sources/DTO/Content/OTTPlatformsDTO.swift @@ -36,8 +36,8 @@ extension OTTPlatformsDTO.OTTPlatformDTO { return try OTTPlatformEntity( ottId: unwrap(ottId), name: name ?? "", - logoUrl: logoUrl ?? "", - contentUrl: contentUrl ?? "" + logoUrl: URL(string: logoUrl ?? ""), + contentUrl: URL(string: contentUrl ?? "") ) } } diff --git a/FLINT/Data/Sources/DTO/User/CollectionBookmarkUsersDTO.swift b/FLINT/Data/Sources/DTO/User/CollectionBookmarkUsersDTO.swift index 4fb7b368..e4011207 100644 --- a/FLINT/Data/Sources/DTO/User/CollectionBookmarkUsersDTO.swift +++ b/FLINT/Data/Sources/DTO/User/CollectionBookmarkUsersDTO.swift @@ -35,13 +35,13 @@ extension CollectionBookmarkUsersDTO { } extension CollectionBookmarkUsersDTO.UserDTO { - public var entity: CollectionBookmarkUserEntity { + public var entity: UserProfileEntity { get throws { - return try CollectionBookmarkUserEntity( - userId: unwrap(userId), + return try UserProfileEntity( + id: unwrap(userId), nickname: nickName ?? "", profileImageUrl: URL(string: profileImageUrl ?? ""), - userRole: userRole ?? "" + role: UserRole(rawValue: userRole ?? "") ?? .unknown ) } } diff --git a/FLINT/Data/Sources/DTO/User/KeywordDTO.swift b/FLINT/Data/Sources/DTO/User/KeywordDTO.swift index c2a5d9cb..129798b0 100644 --- a/FLINT/Data/Sources/DTO/User/KeywordDTO.swift +++ b/FLINT/Data/Sources/DTO/User/KeywordDTO.swift @@ -35,11 +35,11 @@ extension KeywordsDTO.KeywordDTO { public var entity: KeywordEntity { get throws { return try KeywordEntity( - color: color ?? "", + color: unwrap(KeywordColor(rawValue: color ?? "")), rank: unwrap(rank), name: name ?? "", percentage: percentage ?? 0, - imageUrl: imageUrl ?? "" + imageUrl: URL(string: imageUrl ?? "") ) } } diff --git a/FLINT/Data/Sources/DTO/User/UserProfileDTO.swift b/FLINT/Data/Sources/DTO/User/UserProfileDTO.swift index 61c0f2df..7ab6b046 100644 --- a/FLINT/Data/Sources/DTO/User/UserProfileDTO.swift +++ b/FLINT/Data/Sources/DTO/User/UserProfileDTO.swift @@ -22,8 +22,8 @@ extension UserProfileDTO { return try UserProfileEntity( id: unwrap(id), nickname: nickname ?? "", - profileImageUrl: profileImageUrl ?? "", - isFliner: isFliner ?? false + profileImageUrl: URL(string: profileImageUrl ?? ""), + role: (isFliner ?? false) ? .fliner : .unknown ) } } diff --git a/FLINT/Data/Sources/Networking/Service/CollectionService.swift b/FLINT/Data/Sources/Networking/Service/CollectionService.swift index 8093d927..2fddf0a6 100644 --- a/FLINT/Data/Sources/Networking/Service/CollectionService.swift +++ b/FLINT/Data/Sources/Networking/Service/CollectionService.swift @@ -36,7 +36,7 @@ public final class DefaultCollectionService: CollectionService { public func createCollection(collectionInfo: CreateCollectionEntity) -> AnyPublisher { return collectionAPIProvider.requestPublisher(.createCollection(collectionInfo: collectionInfo)) - .mapBaseResponseData(CreateCollectionResponseDTO.self) + .mapBaseResponseData(CreateCollectionDTO.self) .eraseToAnyPublisher() } diff --git a/FLINT/Domain/Sources/Entity/Bookmark/CollectionBookmarkUsersEntity.swift b/FLINT/Domain/Sources/Entity/Bookmark/CollectionBookmarkUsersEntity.swift index 0f8791be..1ceb7366 100644 --- a/FLINT/Domain/Sources/Entity/Bookmark/CollectionBookmarkUsersEntity.swift +++ b/FLINT/Domain/Sources/Entity/Bookmark/CollectionBookmarkUsersEntity.swift @@ -7,7 +7,7 @@ import Foundation -public struct CollectionBookmarkUsersEntity { +public struct CollectionBookmarkUsersEntity: Equatable { public let bookmarkCount: Int public let users: [UserProfileEntity] diff --git a/FLINT/Domain/Sources/Entity/Collection/CollectionDetailEntity.swift b/FLINT/Domain/Sources/Entity/Collection/CollectionDetailEntity.swift index e61fe7e4..563b3856 100644 --- a/FLINT/Domain/Sources/Entity/Collection/CollectionDetailEntity.swift +++ b/FLINT/Domain/Sources/Entity/Collection/CollectionDetailEntity.swift @@ -7,7 +7,7 @@ import Foundation -public struct CollectionDetailEntity { +public struct CollectionDetailEntity: Equatable { public let id: String public let title: String public let description: String diff --git a/FLINT/Domain/Sources/Entity/Collection/ExploreInfoEntity.swift b/FLINT/Domain/Sources/Entity/Collection/ExploreInfoEntity.swift index 34b251be..9bde9209 100644 --- a/FLINT/Domain/Sources/Entity/Collection/ExploreInfoEntity.swift +++ b/FLINT/Domain/Sources/Entity/Collection/ExploreInfoEntity.swift @@ -7,7 +7,7 @@ import Foundation -public struct ExploreInfoEntity { +public struct ExploreInfoEntity: Equatable, Hashable, Sendable { public let id: String public let imageUrl: URL? public let title: String diff --git a/FLINT/Domain/Sources/Entity/Content/ContentEntity.swift b/FLINT/Domain/Sources/Entity/Content/ContentEntity.swift index e12b438b..45bcb18b 100644 --- a/FLINT/Domain/Sources/Entity/Content/ContentEntity.swift +++ b/FLINT/Domain/Sources/Entity/Content/ContentEntity.swift @@ -7,7 +7,7 @@ import Foundation -public struct ContentEntity { +public struct ContentEntity: Equatable { public let id: String public let title: String public let author: String diff --git a/FLINT/Domain/Sources/Entity/User/KeywordColor.swift b/FLINT/Domain/Sources/Entity/User/KeywordColor.swift new file mode 100644 index 00000000..3007625e --- /dev/null +++ b/FLINT/Domain/Sources/Entity/User/KeywordColor.swift @@ -0,0 +1,16 @@ +// +// KeywordColor.swift +// Domain +// +// Created by 김호성 on 2026.02.09. +// + +import Foundation + +public enum KeywordColor: String, Decodable { + case pink = "PINK" + case green = "GREEN" + case orange = "ORANGE" + case yellow = "YELLOW" + case blue = "BLUE" +} diff --git a/FLINT/Domain/Sources/Entity/User/KeywordEntity.swift b/FLINT/Domain/Sources/Entity/User/KeywordEntity.swift index ef407871..adf636de 100644 --- a/FLINT/Domain/Sources/Entity/User/KeywordEntity.swift +++ b/FLINT/Domain/Sources/Entity/User/KeywordEntity.swift @@ -8,13 +8,13 @@ import Foundation public struct KeywordEntity { - public let color: String + public let color: KeywordColor public let rank: Int public let name: String public let percentage: Int public let imageUrl: URL? - public init(color: String, rank: Int, name: String, percentage: Int, imageUrl: URL?) { + public init(color: KeywordColor, rank: Int, name: String, percentage: Int, imageUrl: URL?) { self.color = color self.rank = rank self.name = name diff --git a/FLINT/Domain/Sources/Entity/User/UserProfileEntity.swift b/FLINT/Domain/Sources/Entity/User/UserProfileEntity.swift index 402815d6..2a9c838c 100644 --- a/FLINT/Domain/Sources/Entity/User/UserProfileEntity.swift +++ b/FLINT/Domain/Sources/Entity/User/UserProfileEntity.swift @@ -7,7 +7,7 @@ import Foundation -public struct UserProfileEntity { +public struct UserProfileEntity: Equatable { public let id: String public let nickname: String public let profileImageUrl: URL? diff --git a/FLINT/Domain/Sources/Entity/User/UserRole.swift b/FLINT/Domain/Sources/Entity/User/UserRole.swift index d427766f..9e5081ad 100644 --- a/FLINT/Domain/Sources/Entity/User/UserRole.swift +++ b/FLINT/Domain/Sources/Entity/User/UserRole.swift @@ -7,7 +7,7 @@ import Foundation -public enum UserRole: String { +public enum UserRole: String, Equatable { /// 관리자 - 시스템 전체 관리 권한 case admin = "ADMIN" @@ -16,4 +16,6 @@ public enum UserRole: String { /// 게스트 사용자 - 조회만 가능 case fling = "FLING" + + case unknown } diff --git a/FLINT/Domain/Sources/UseCase/Collection/CreateCollectionUseCase.swift b/FLINT/Domain/Sources/UseCase/Collection/CreateCollectionUseCase.swift index d35c525c..568bd5c0 100644 --- a/FLINT/Domain/Sources/UseCase/Collection/CreateCollectionUseCase.swift +++ b/FLINT/Domain/Sources/UseCase/Collection/CreateCollectionUseCase.swift @@ -12,7 +12,7 @@ import Entity import Repository public protocol CreateCollectionUseCase { - func createCollection(collectionInfo: CreateCollectionEntity) -> AnyPublisher + func createCollection(collectionInfo: CreateCollectionEntity) -> AnyPublisher } public class DefaultCreateCollectionUseCase: CreateCollectionUseCase { @@ -23,7 +23,7 @@ public class DefaultCreateCollectionUseCase: CreateCollectionUseCase { self.collectionRepository = collectionRepository } - public func createCollection(collectionInfo: CreateCollectionEntity) -> AnyPublisher { + public func createCollection(collectionInfo: CreateCollectionEntity) -> AnyPublisher { return collectionRepository.createCollection(collectionInfo: collectionInfo) } } diff --git a/FLINT/Domain/Sources/UseCase/Profile/FetchBookmarkedCollectionsUseCase.swift b/FLINT/Domain/Sources/UseCase/Collection/FetchBookmarkedCollectionsUseCase.swift similarity index 100% rename from FLINT/Domain/Sources/UseCase/Profile/FetchBookmarkedCollectionsUseCase.swift rename to FLINT/Domain/Sources/UseCase/Collection/FetchBookmarkedCollectionsUseCase.swift diff --git a/FLINT/Domain/Sources/UseCase/Profile/FetchCreatedCollectionsUseCase.swift b/FLINT/Domain/Sources/UseCase/Collection/FetchCreatedCollectionsUseCase.swift similarity index 100% rename from FLINT/Domain/Sources/UseCase/Profile/FetchCreatedCollectionsUseCase.swift rename to FLINT/Domain/Sources/UseCase/Collection/FetchCreatedCollectionsUseCase.swift diff --git a/FLINT/Domain/Sources/UseCase/Collection/FetchCollectionsUseCase.swift b/FLINT/Domain/Sources/UseCase/Collection/FetchExploreCollectionsUseCase.swift similarity index 51% rename from FLINT/Domain/Sources/UseCase/Collection/FetchCollectionsUseCase.swift rename to FLINT/Domain/Sources/UseCase/Collection/FetchExploreCollectionsUseCase.swift index 48f0efe6..f6b76178 100644 --- a/FLINT/Domain/Sources/UseCase/Collection/FetchCollectionsUseCase.swift +++ b/FLINT/Domain/Sources/UseCase/Collection/FetchExploreCollectionsUseCase.swift @@ -1,5 +1,5 @@ // -// FetchCollectionsUseCase.swift +// FetchExploreCollectionsUseCase.swift // Domain // // Created by 김호성 on 2026.01.22. @@ -11,11 +11,11 @@ import Foundation import Entity import Repository -public protocol FetchCollectionsUseCase { - func fetchExplore(cursor: Int64?) -> AnyPublisher +public protocol FetchExploreCollectionsUseCase { + func fetchExploreCollections(cursor: Int64?) -> AnyPublisher } -public final class DefaultFetchCollectionsUseCase: FetchCollectionsUseCase { +public final class DefaultFetchExploreCollectionsUseCase: FetchExploreCollectionsUseCase { private let collectionRepository: CollectionRepository @@ -23,7 +23,7 @@ public final class DefaultFetchCollectionsUseCase: FetchCollectionsUseCase { self.collectionRepository = collectionRepository } - public func fetchExplore(cursor: Int64?) -> AnyPublisher { + public func fetchExploreCollections(cursor: Int64?) -> AnyPublisher { collectionRepository.fetchCollections(cursor: cursor, size: 3) } } diff --git a/FLINT/Domain/Sources/UseCase/Profile/FetchBookmarkedContentsUseCase.swift b/FLINT/Domain/Sources/UseCase/Content/FetchBookmarkedContentsUseCase.swift similarity index 100% rename from FLINT/Domain/Sources/UseCase/Profile/FetchBookmarkedContentsUseCase.swift rename to FLINT/Domain/Sources/UseCase/Content/FetchBookmarkedContentsUseCase.swift diff --git a/FLINT/Domain/Sources/UseCase/Content/FetchPopularContentsUseCase.swift b/FLINT/Domain/Sources/UseCase/Content/FetchPopularContentsUseCase.swift index 749e1b67..6acad23a 100644 --- a/FLINT/Domain/Sources/UseCase/Content/FetchPopularContentsUseCase.swift +++ b/FLINT/Domain/Sources/UseCase/Content/FetchPopularContentsUseCase.swift @@ -15,7 +15,7 @@ public protocol FetchPopularContentsUseCase { func fetchPopularContents() -> AnyPublisher<[ContentEntity], Error> } -public class DefaultContentsUseCase: FetchPopularContentsUseCase { +public class DefaultFetchPopularContentsUseCase: FetchPopularContentsUseCase { private let searchRepository: SearchRepository diff --git a/FLINT/Domain/Sources/UseCase/Nickname/CheckNicknameUseCase.swift b/FLINT/Domain/Sources/UseCase/Profile/CheckNicknameUseCase.swift similarity index 100% rename from FLINT/Domain/Sources/UseCase/Nickname/CheckNicknameUseCase.swift rename to FLINT/Domain/Sources/UseCase/Profile/CheckNicknameUseCase.swift diff --git a/FLINT/FLINT/Dependency/DIContainer.swift b/FLINT/FLINT/Dependency/DIContainer.swift index b47cf314..bdc057c9 100644 --- a/FLINT/FLINT/Dependency/DIContainer.swift +++ b/FLINT/FLINT/Dependency/DIContainer.swift @@ -39,6 +39,12 @@ final class DIContainer: DependencyFactory { private lazy var authInterceptor: AuthInterceptor = AuthInterceptor(tokenStorage: tokenStorage) private lazy var networkLoggerPlugin: NetworkLoggerPlugin = NetworkLoggerPlugin() + lazy var contentAPIProvider = MoyaProvider( + session: Session(interceptor: authInterceptor), + plugins: [ + networkLoggerPlugin + ] + ) lazy var userAPIProvider = MoyaProvider( session: Session(interceptor: authInterceptor), plugins: [ diff --git a/FLINT/FLINT/Dependency/Factory/APIProvider/AuthAPIFactory.swift b/FLINT/FLINT/Dependency/Factory/APIProvider/AuthAPIProviderFactory.swift similarity index 76% rename from FLINT/FLINT/Dependency/Factory/APIProvider/AuthAPIFactory.swift rename to FLINT/FLINT/Dependency/Factory/APIProvider/AuthAPIProviderFactory.swift index 911f5198..96580873 100644 --- a/FLINT/FLINT/Dependency/Factory/APIProvider/AuthAPIFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/APIProvider/AuthAPIProviderFactory.swift @@ -1,5 +1,5 @@ // -// AuthAPIFactory.swift +// AuthAPIProviderFactory.swift // FLINT // // Created by 김호성 on 2026.01.23. @@ -11,13 +11,13 @@ import Moya import Data -protocol AuthAPIFactory { +protocol AuthAPIProviderFactory { var authAPIProvider: MoyaProvider { get set } func makeAuthAPIProvider() -> MoyaProvider } -extension AuthAPIFactory { +extension AuthAPIProviderFactory { func makeAuthAPIProvider() -> MoyaProvider { return authAPIProvider } diff --git a/FLINT/FLINT/Dependency/Factory/APIProvider/CollectionAPIFactory.swift b/FLINT/FLINT/Dependency/Factory/APIProvider/CollectionAPIProviderFactory.swift similarity index 83% rename from FLINT/FLINT/Dependency/Factory/APIProvider/CollectionAPIFactory.swift rename to FLINT/FLINT/Dependency/Factory/APIProvider/CollectionAPIProviderFactory.swift index 5d8840ff..fb02d1fd 100644 --- a/FLINT/FLINT/Dependency/Factory/APIProvider/CollectionAPIFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/APIProvider/CollectionAPIProviderFactory.swift @@ -11,13 +11,13 @@ import Moya import Data -protocol CollectionAPIFactory { +protocol CollectionAPIProviderFactory { var collectionAPIProvider: MoyaProvider { get set } func makeCollectionAPIProvider() -> MoyaProvider } -extension CollectionAPIFactory { +extension CollectionAPIProviderFactory { func makeCollectionAPIProvider() -> MoyaProvider { return collectionAPIProvider } diff --git a/FLINT/FLINT/Dependency/Factory/APIProvider/ContentAPIProviderFactory.swift b/FLINT/FLINT/Dependency/Factory/APIProvider/ContentAPIProviderFactory.swift new file mode 100644 index 00000000..ec54d6a2 --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/APIProvider/ContentAPIProviderFactory.swift @@ -0,0 +1,24 @@ +// +// ContentAPIProviderFactory.swift +// FLINT +// +// Created by 김호성 on 2026.02.09. +// + +import Foundation + +import Moya + +import Data + +protocol ContentAPIProviderFactory { + var contentAPIProvider: MoyaProvider { get set } + + func makeContentAPIProvider() -> MoyaProvider +} + +extension ContentAPIProviderFactory { + func makeContentAPIProvider() -> MoyaProvider { + return contentAPIProvider + } +} diff --git a/FLINT/FLINT/Dependency/Factory/APIProvider/HomeAPIFactory.swift b/FLINT/FLINT/Dependency/Factory/APIProvider/HomeAPIProviderFactory.swift similarity index 76% rename from FLINT/FLINT/Dependency/Factory/APIProvider/HomeAPIFactory.swift rename to FLINT/FLINT/Dependency/Factory/APIProvider/HomeAPIProviderFactory.swift index fa8bd8af..45cab367 100644 --- a/FLINT/FLINT/Dependency/Factory/APIProvider/HomeAPIFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/APIProvider/HomeAPIProviderFactory.swift @@ -1,5 +1,5 @@ // -// HomeAPIFactory.swift +// HomeAPIProviderFactory.swift // FLINT // // Created by 김호성 on 2026.01.31. @@ -11,13 +11,13 @@ import Moya import Data -protocol HomeAPIFactory { +protocol HomeAPIProviderFactory { var homeAPIProvider: MoyaProvider { get set } func makeHomeAPIProvider() -> MoyaProvider } -extension HomeAPIFactory { +extension HomeAPIProviderFactory { func makeHomeAPIProvider() -> MoyaProvider { return homeAPIProvider } diff --git a/FLINT/FLINT/Dependency/Factory/APIProvider/SearchAPIFactory.swift b/FLINT/FLINT/Dependency/Factory/APIProvider/SearchAPIProviderFactory.swift similarity index 75% rename from FLINT/FLINT/Dependency/Factory/APIProvider/SearchAPIFactory.swift rename to FLINT/FLINT/Dependency/Factory/APIProvider/SearchAPIProviderFactory.swift index 86c289e9..8ba2dc01 100644 --- a/FLINT/FLINT/Dependency/Factory/APIProvider/SearchAPIFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/APIProvider/SearchAPIProviderFactory.swift @@ -1,5 +1,5 @@ // -// SearchAPIFactory.swift +// SearchAPIProviderFactory.swift // FLINT // // Created by 김호성 on 2026.01.22. @@ -11,13 +11,13 @@ import Moya import Data -protocol SearchAPIFactory { +protocol SearchAPIProviderFactory { var searchAPIProvider: MoyaProvider { get set } func makeSearchAPIProvider() -> MoyaProvider } -extension SearchAPIFactory { +extension SearchAPIProviderFactory { func makeSearchAPIProvider() -> MoyaProvider { return searchAPIProvider } diff --git a/FLINT/FLINT/Dependency/Factory/APIProvider/UserAPIFactory.swift b/FLINT/FLINT/Dependency/Factory/APIProvider/UserAPIProviderFactory.swift similarity index 76% rename from FLINT/FLINT/Dependency/Factory/APIProvider/UserAPIFactory.swift rename to FLINT/FLINT/Dependency/Factory/APIProvider/UserAPIProviderFactory.swift index f29fb4a5..ab049839 100644 --- a/FLINT/FLINT/Dependency/Factory/APIProvider/UserAPIFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/APIProvider/UserAPIProviderFactory.swift @@ -1,5 +1,5 @@ // -// File.swift +// UserAPIProviderFactory.swift // FLINT // // Created by 김호성 on 2026.01.22. @@ -11,13 +11,13 @@ import Moya import Data -protocol UserAPIFactory { +protocol UserAPIProviderFactory { var userAPIProvider: MoyaProvider { get set } func makeUserAPIProvider() -> MoyaProvider } -extension UserAPIFactory { +extension UserAPIProviderFactory { func makeUserAPIProvider() -> MoyaProvider { return userAPIProvider } diff --git a/FLINT/FLINT/Dependency/Factory/Repository/CollectionRepositoryFactory.swift b/FLINT/FLINT/Dependency/Factory/Repository/CollectionRepositoryFactory.swift index 75fb9cd5..4238c2a8 100644 --- a/FLINT/FLINT/Dependency/Factory/Repository/CollectionRepositoryFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/Repository/CollectionRepositoryFactory.swift @@ -1,5 +1,5 @@ // -// File.swift +// CollectionRepositoryFactory.swift // FLINT // // Created by 김호성 on 2026.01.22. diff --git a/FLINT/FLINT/Dependency/Factory/Repository/ContentRepositoryFactory.swift b/FLINT/FLINT/Dependency/Factory/Repository/ContentRepositoryFactory.swift new file mode 100644 index 00000000..5c494686 --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/Repository/ContentRepositoryFactory.swift @@ -0,0 +1,25 @@ +// +// ContentRepositoryFactory.swift +// FLINT +// +// Created by 김호성 on 2026.02.09. +// + +import Foundation + +import Data +import Domain + +protocol ContentRepositoryFactory: ContentServiceFactory { + func makeContentRepository() -> ContentRepository + func makeContentRepository(contentService: ContentService) -> ContentRepository +} + +extension ContentRepositoryFactory { + func makeContentRepository() -> ContentRepository { + return makeContentRepository(contentService: makeContentService()) + } + func makeContentRepository(contentService: ContentService) -> ContentRepository { + return DefaultContentRepository(contentService: contentService) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/Repository/UserRepositoryFactory.swift b/FLINT/FLINT/Dependency/Factory/Repository/UserRepositoryFactory.swift index bc0d0a11..db0c9e42 100644 --- a/FLINT/FLINT/Dependency/Factory/Repository/UserRepositoryFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/Repository/UserRepositoryFactory.swift @@ -1,5 +1,5 @@ // -// File.swift +// UserRepositoryFactory.swift // FLINT // // Created by 김호성 on 2026.01.22. diff --git a/FLINT/FLINT/Dependency/Factory/Service/AuthServiceFactory.swift b/FLINT/FLINT/Dependency/Factory/Service/AuthServiceFactory.swift index 13c40c88..928ea206 100644 --- a/FLINT/FLINT/Dependency/Factory/Service/AuthServiceFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/Service/AuthServiceFactory.swift @@ -11,7 +11,7 @@ import Moya import Data -protocol AuthServiceFactory: AuthAPIFactory, TokenStorageFactory { +protocol AuthServiceFactory: AuthAPIProviderFactory, TokenStorageFactory { func makeAuthService() -> AuthService func makeAuthService(tokenStorage: TokenStorage, authAPIProvider: MoyaProvider) -> AuthService } diff --git a/FLINT/FLINT/Dependency/Factory/Service/BookmarkServiceFactory.swift b/FLINT/FLINT/Dependency/Factory/Service/BookmarkServiceFactory.swift index 307559dd..0b724d86 100644 --- a/FLINT/FLINT/Dependency/Factory/Service/BookmarkServiceFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/Service/BookmarkServiceFactory.swift @@ -13,14 +13,14 @@ import Data protocol BookmarkServiceFactory: BookmarkAPIProviderFactory { func makeBookmarkService() -> BookmarkService - func makeBookmarkService(provider: MoyaProvider) -> BookmarkService + func makeBookmarkService(bookmarkAPIProvider: MoyaProvider) -> BookmarkService } extension BookmarkServiceFactory { func makeBookmarkService() -> BookmarkService { - return makeBookmarkService(provider: makeBookmarkAPIProvider()) + return makeBookmarkService(bookmarkAPIProvider: makeBookmarkAPIProvider()) } - func makeBookmarkService(provider: MoyaProvider) -> BookmarkService { - return DefaultBookmarkService(provider: provider) + func makeBookmarkService(bookmarkAPIProvider: MoyaProvider) -> BookmarkService { + return DefaultBookmarkService(bookmarkAPIProvider: bookmarkAPIProvider) } } diff --git a/FLINT/FLINT/Dependency/Factory/Service/CollectionServiceFactory.swift b/FLINT/FLINT/Dependency/Factory/Service/CollectionServiceFactory.swift index e4a471fd..b231ed7b 100644 --- a/FLINT/FLINT/Dependency/Factory/Service/CollectionServiceFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/Service/CollectionServiceFactory.swift @@ -1,5 +1,5 @@ // -// File.swift +// CollectionServiceFactory.swift // FLINT // // Created by 김호성 on 2026.01.22. @@ -11,16 +11,16 @@ import Moya import Data -protocol CollectionServiceFactory: CollectionAPIFactory { +protocol CollectionServiceFactory: CollectionAPIProviderFactory { func makeCollectionService() -> CollectionService - func makeCollectionService(exploreAPIProvider: MoyaProvider) -> CollectionService + func makeCollectionService(collectionAPIProvider: MoyaProvider) -> CollectionService } extension CollectionServiceFactory { func makeCollectionService() -> CollectionService { - return makeCollectionService(exploreAPIProvider: makeCollectionAPIProvider()) + return makeCollectionService(collectionAPIProvider: makeCollectionAPIProvider()) } - func makeCollectionService(exploreAPIProvider: MoyaProvider) -> CollectionService { - return DefaultCollectionService(provider: exploreAPIProvider) + func makeCollectionService(collectionAPIProvider: MoyaProvider) -> CollectionService { + return DefaultCollectionService(collectionAPIProvider: collectionAPIProvider) } } diff --git a/FLINT/FLINT/Dependency/Factory/Service/ContentServiceFactory.swift b/FLINT/FLINT/Dependency/Factory/Service/ContentServiceFactory.swift new file mode 100644 index 00000000..150d256e --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/Service/ContentServiceFactory.swift @@ -0,0 +1,26 @@ +// +// ContentServiceFactory.swift +// FLINT +// +// Created by 김호성 on 2026.02.09. +// + +import Foundation + +import Moya + +import Data + +protocol ContentServiceFactory: ContentAPIProviderFactory { + func makeContentService() -> ContentService + func makeContentService(contentAPIProvider: MoyaProvider) -> ContentService +} + +extension ContentServiceFactory { + func makeContentService() -> ContentService { + return makeContentService(contentAPIProvider: makeContentAPIProvider()) + } + func makeContentService(contentAPIProvider: MoyaProvider) -> ContentService { + return DefaultContentService(contentAPIProvider: contentAPIProvider) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/Service/HomeServiceFactory.swift b/FLINT/FLINT/Dependency/Factory/Service/HomeServiceFactory.swift index 26afd2ac..76801699 100644 --- a/FLINT/FLINT/Dependency/Factory/Service/HomeServiceFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/Service/HomeServiceFactory.swift @@ -11,7 +11,7 @@ import Moya import Data -protocol HomeServiceFactory: HomeAPIFactory { +protocol HomeServiceFactory: HomeAPIProviderFactory { func makeHomeService() -> HomeService func makeHomeService(homeAPIProvider: MoyaProvider) -> HomeService } @@ -21,6 +21,6 @@ extension HomeServiceFactory { return makeHomeService(homeAPIProvider: makeHomeAPIProvider()) } func makeHomeService(homeAPIProvider: MoyaProvider) -> HomeService { - return DefaultHomeService(provider: homeAPIProvider) + return DefaultHomeService(homeAPIProvider: homeAPIProvider) } } diff --git a/FLINT/FLINT/Dependency/Factory/Service/SearchServiceFactory.swift b/FLINT/FLINT/Dependency/Factory/Service/SearchServiceFactory.swift index c11adef7..897c7e28 100644 --- a/FLINT/FLINT/Dependency/Factory/Service/SearchServiceFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/Service/SearchServiceFactory.swift @@ -11,7 +11,7 @@ import Moya import Data -protocol SearchServiceFactory: SearchAPIFactory { +protocol SearchServiceFactory: SearchAPIProviderFactory { func makeSearchService() -> SearchService func makeSearchService(searchAPIProvider: MoyaProvider) -> SearchService } @@ -21,6 +21,6 @@ extension SearchServiceFactory { return makeSearchService(searchAPIProvider: makeSearchAPIProvider()) } func makeSearchService(searchAPIProvider: MoyaProvider) -> SearchService { - return DefaultSearchService(provider: searchAPIProvider) + return DefaultSearchService(searchAPIProvider: searchAPIProvider) } } diff --git a/FLINT/FLINT/Dependency/Factory/Service/UserServiceFactory.swift b/FLINT/FLINT/Dependency/Factory/Service/UserServiceFactory.swift index 88579ba1..b22147c4 100644 --- a/FLINT/FLINT/Dependency/Factory/Service/UserServiceFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/Service/UserServiceFactory.swift @@ -1,5 +1,5 @@ // -// File.swift +// UserServiceFactory.swift // FLINT // // Created by 김호성 on 2026.01.22. @@ -11,7 +11,7 @@ import Moya import Data -protocol UserServiceFactory: UserAPIFactory { +protocol UserServiceFactory: UserAPIProviderFactory { func makeUserService() -> UserService func makeUserService(userAPIProvider: MoyaProvider) -> UserService } diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/SignupUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Auth/SignupUseCaseFactory.swift similarity index 100% rename from FLINT/FLINT/Dependency/Factory/UseCase/SignupUseCaseFactory.swift rename to FLINT/FLINT/Dependency/Factory/UseCase/Auth/SignupUseCaseFactory.swift diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/SocialVerifyUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Auth/SocialVerifyUseCaseFactory.swift similarity index 100% rename from FLINT/FLINT/Dependency/Factory/UseCase/SocialVerifyUseCaseFactory.swift rename to FLINT/FLINT/Dependency/Factory/UseCase/Auth/SocialVerifyUseCaseFactory.swift diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/Auth/WithDrawUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Auth/WithDrawUseCaseFactory.swift new file mode 100644 index 00000000..7fb0adbb --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/UseCase/Auth/WithDrawUseCaseFactory.swift @@ -0,0 +1,24 @@ +// +// WithDrawUseCaseFactory.swift +// FLINT +// +// Created by 김호성 on 2026.02.09. +// + +import Foundation + +import Domain + +protocol WithDrawUseCaseFactory: AuthRepositoryFactory { + func makeWithDrawUseCase() -> WithDrawUseCase + func makeWithDrawUseCase(authRepository: AuthRepository) -> WithDrawUseCase +} + +extension WithDrawUseCaseFactory { + func makeWithDrawUseCase() -> WithDrawUseCase { + return makeWithDrawUseCase(authRepository: makeAuthRepository()) + } + func makeWithDrawUseCase(authRepository: AuthRepository) -> WithDrawUseCase { + return DefaultWithDrawUseCase(authRepository: authRepository) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/CreateCollectionUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Collection/CreateCollectionUseCaseFactory.swift similarity index 100% rename from FLINT/FLINT/Dependency/Factory/UseCase/CreateCollectionUseCaseFactory.swift rename to FLINT/FLINT/Dependency/Factory/UseCase/Collection/CreateCollectionUseCaseFactory.swift diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchBookmarkedCollectionsUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchBookmarkedCollectionsUseCaseFactory.swift new file mode 100644 index 00000000..06ce9ccd --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchBookmarkedCollectionsUseCaseFactory.swift @@ -0,0 +1,24 @@ +// +// FetchBookmarkedCollectionsUseCaseFactory.swift +// FLINT +// +// Created by 김호성 on 2026.02.09. +// + +import Foundation + +import Domain + +protocol FetchBookmarkedCollectionsUseCaseFactory: UserRepositoryFactory { + func makeFetchBookmarkedCollectionsUseCase() -> FetchBookmarkedCollectionsUseCase + func makeFetchBookmarkedCollectionsUseCase(userRepository: UserRepository) -> FetchBookmarkedCollectionsUseCase +} + +extension FetchBookmarkedCollectionsUseCaseFactory { + func makeFetchBookmarkedCollectionsUseCase() -> FetchBookmarkedCollectionsUseCase { + return makeFetchBookmarkedCollectionsUseCase(userRepository: makeUserRepository()) + } + func makeFetchBookmarkedCollectionsUseCase(userRepository: UserRepository) -> FetchBookmarkedCollectionsUseCase { + return DefaultFetchBookmarkedCollectionsUseCase(userRepository: userRepository) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchCollectionBookmarkUsersUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchCollectionBookmarkUsersUseCaseFactory.swift new file mode 100644 index 00000000..9442a4f5 --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchCollectionBookmarkUsersUseCaseFactory.swift @@ -0,0 +1,24 @@ +// +// FetchCollectionBookmarkUsersUseCaseFactory.swift +// FLINT +// +// Created by 진소은 on 1/23/26. +// + +import Foundation + +import Domain + +protocol FetchCollectionBookmarkUsersUseCaseFactory: BookmarkRepositoryFactory { + func makeFetchCollectionBookmarkUsersUseCase() -> FetchCollectionBookmarkUsersUseCase + func makeFetchCollectionBookmarkUsersUseCase(bookmarkRepository: BookmarkRepository) -> FetchCollectionBookmarkUsersUseCase +} + +extension FetchCollectionBookmarkUsersUseCaseFactory { + func makeFetchCollectionBookmarkUsersUseCase() -> FetchCollectionBookmarkUsersUseCase { + return makeFetchCollectionBookmarkUsersUseCase(bookmarkRepository: makeBookmarkRepository()) + } + func makeFetchCollectionBookmarkUsersUseCase(bookmarkRepository: BookmarkRepository) -> FetchCollectionBookmarkUsersUseCase { + return DefaultFetchCollectionBookmarkUsersUseCase(bookmarkRepository: bookmarkRepository) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchCollectionDetailUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchCollectionDetailUseCaseFactory.swift new file mode 100644 index 00000000..f6a91b93 --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchCollectionDetailUseCaseFactory.swift @@ -0,0 +1,24 @@ +// +// FetchCollectionDetailUseCaseFactory.swift +// FLINT +// +// Created by 김호성 on 2026.02.02. +// + +import Foundation + +import Domain + +protocol FetchCollectionDetailUseCaseFactory: CollectionRepositoryFactory { + func makeFetchCollectionDetailUseCase() -> FetchCollectionDetailUseCase + func makeFetchCollectionDetailUseCase(collectionRepository: CollectionRepository) -> FetchCollectionDetailUseCase +} + +extension FetchCollectionDetailUseCaseFactory { + func makeFetchCollectionDetailUseCase() -> FetchCollectionDetailUseCase { + return makeFetchCollectionDetailUseCase(collectionRepository: makeCollectionRepository()) + } + func makeFetchCollectionDetailUseCase(collectionRepository: CollectionRepository) -> FetchCollectionDetailUseCase { + return DefaultFetchCollectionDetailUseCase(collectionRepository: collectionRepository) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchCreatedCollectionsUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchCreatedCollectionsUseCaseFactory.swift new file mode 100644 index 00000000..6ce01768 --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchCreatedCollectionsUseCaseFactory.swift @@ -0,0 +1,24 @@ +// +// FetchCreatedCollectionsUseCaseFactory.swift +// FLINT +// +// Created by 김호성 on 2026.02.09. +// + +import Foundation + +import Domain + +protocol FetchCreatedCollectionsUseCaseFactory: UserRepositoryFactory { + func makeFetchCreatedCollectionsUseCase() -> FetchCreatedCollectionsUseCase + func makeFetchCreatedCollectionsUseCase(userRepository: UserRepository) -> FetchCreatedCollectionsUseCase +} + +extension FetchKeywordsUseCaseFactory { + func makeFetchCreatedCollectionsUseCase() -> FetchCreatedCollectionsUseCase { + return makeFetchCreatedCollectionsUseCase(userRepository: makeUserRepository()) + } + func makeFetchCreatedCollectionsUseCase(userRepository: UserRepository) -> FetchCreatedCollectionsUseCase { + return DefaultFetchCreatedCollectionsUseCase(userRepository: userRepository) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchExploreCollectionsUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchExploreCollectionsUseCaseFactory.swift new file mode 100644 index 00000000..c886186e --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchExploreCollectionsUseCaseFactory.swift @@ -0,0 +1,24 @@ +// +// FetchExploreCollectionsUseCaseFactory.swift +// FLINT +// +// Created by 김호성 on 2026.01.22. +// + +import Foundation + +import Domain + +protocol FetchExploreCollectionsUseCaseFactory: CollectionRepositoryFactory { + func makeFetchExploreCollectionsUseCase() -> FetchExploreCollectionsUseCase + func makeFetchExploreCollectionsUseCase(collectionRepository: CollectionRepository) -> FetchExploreCollectionsUseCase +} + +extension FetchExploreCollectionsUseCaseFactory { + func makeFetchExploreCollectionsUseCase() -> FetchExploreCollectionsUseCase { + return makeFetchExploreCollectionsUseCase(collectionRepository: makeCollectionRepository()) + } + func makeFetchExploreCollectionsUseCase(collectionRepository: CollectionRepository) -> FetchExploreCollectionsUseCase { + return DefaultFetchExploreCollectionsUseCase(collectionRepository: collectionRepository) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchRecentViewedCollectionsUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchRecentViewedCollectionsUseCaseFactory.swift new file mode 100644 index 00000000..2e17afaa --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchRecentViewedCollectionsUseCaseFactory.swift @@ -0,0 +1,24 @@ +// +// FetchRecentViewedCollectionsUseCaseFactory.swift +// FLINT +// +// Created by 김호성 on 2026.02.09. +// + +import Foundation + +import Domain + +protocol FetchRecentViewedCollectionsUseCaseFactory: CollectionRepositoryFactory { + func makeFetchRecentViewedCollectionsUseCase() -> FetchRecentViewedCollectionsUseCase + func makeFetchRecentViewedCollectionsUseCase(collectionRepository: CollectionRepository) -> FetchRecentViewedCollectionsUseCase +} + +extension FetchRecentViewedCollectionsUseCaseFactory { + func makeFetchRecentViewedCollectionsUseCase() -> FetchRecentViewedCollectionsUseCase { + return makeFetchRecentViewedCollectionsUseCase(collectionRepository: makeCollectionRepository()) + } + func makeFetchRecentViewedCollectionsUseCase(collectionRepository: CollectionRepository) -> FetchRecentViewedCollectionsUseCase { + return DefaultFetchRecentViewedCollectionsUseCase(collectionRepository: collectionRepository) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchRecommendedCollectionsUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchRecommendedCollectionsUseCaseFactory.swift new file mode 100644 index 00000000..16575e6b --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/UseCase/Collection/FetchRecommendedCollectionsUseCaseFactory.swift @@ -0,0 +1,24 @@ +// +// FetchRecommendedCollectionsUseCaseFactory.swift +// FLINT +// +// Created by 김호성 on 2026.02.09. +// + +import Foundation + +import Domain + +protocol FetchRecommendedCollectionsUseCaseFactory: HomeRepositoryFactory { + func makeFetchRecommendedCollectionsUseCase() -> FetchRecommendedCollectionsUseCase + func makeFetchRecommendedCollectionsUseCase(homeRepository: HomeRepository) -> FetchRecommendedCollectionsUseCase +} + +extension FetchRecommendedCollectionsUseCaseFactory { + func makeFetchRecommendedCollectionsUseCase() -> FetchRecommendedCollectionsUseCase { + return makeFetchRecommendedCollectionsUseCase(homeRepository: makeHomeRepository()) + } + func makeFetchRecommendedCollectionsUseCase(homeRepository: HomeRepository) -> FetchRecommendedCollectionsUseCase { + return DefaultFetchRecommendedCollectionsUseCase(homeRepository: homeRepository) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/Collection/ToggleCollectionBookmarkUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Collection/ToggleCollectionBookmarkUseCaseFactory.swift new file mode 100644 index 00000000..961bfab3 --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/UseCase/Collection/ToggleCollectionBookmarkUseCaseFactory.swift @@ -0,0 +1,24 @@ +// +// ToggleCollectionBookmarkUseCaseFactory.swift +// FLINT +// +// Created by 김호성 on 2026.02.09. +// + +import Foundation + +import Domain + +protocol ToggleCollectionBookmarkUseCaseFactory: BookmarkRepositoryFactory { + func makeToggleCollectionBookmarkUseCase() -> ToggleCollectionBookmarkUseCase + func makeToggleCollectionBookmarkUseCase(bookmarkRepository: BookmarkRepository) -> ToggleCollectionBookmarkUseCase +} + +extension ToggleCollectionBookmarkUseCaseFactory { + func makeToggleCollectionBookmarkUseCase() -> ToggleCollectionBookmarkUseCase { + return makeToggleCollectionBookmarkUseCase(bookmarkRepository: makeBookmarkRepository()) + } + func makeToggleCollectionBookmarkUseCase(bookmarkRepository: BookmarkRepository) -> ToggleCollectionBookmarkUseCase { + return DefaultToggleCollectionBookmarkUseCase(bookmarkRepository: bookmarkRepository) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/CollectionDetailUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/CollectionDetailUseCaseFactory.swift deleted file mode 100644 index 2fb3a9e6..00000000 --- a/FLINT/FLINT/Dependency/Factory/UseCase/CollectionDetailUseCaseFactory.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// CollectionDetailUseCaseFactory.swift -// FLINT -// -// Created by 김호성 on 2026.02.02. -// - -import Foundation - -import Domain - -protocol CollectionDetailUseCaseFactory: CollectionRepositoryFactory { - func makeCollectionDetailUseCase(collectionRepository: CollectionRepository) -> CollectionDetailUseCase - func makeCollectionDetailUseCase() -> CollectionDetailUseCase -} - -extension CollectionDetailUseCaseFactory { - func makeCollectionDetailUseCase() -> CollectionDetailUseCase { - return makeCollectionDetailUseCase(collectionRepository: makeCollectionRepository()) - } - func makeCollectionDetailUseCase(collectionRepository: CollectionRepository) -> CollectionDetailUseCase { - return DefaultCollectionDetailUseCase(collectionRepository: collectionRepository) - } -} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/Content/FetchBookmarkedContentsUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Content/FetchBookmarkedContentsUseCaseFactory.swift new file mode 100644 index 00000000..471808bd --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/UseCase/Content/FetchBookmarkedContentsUseCaseFactory.swift @@ -0,0 +1,24 @@ +// +// FetchBookmarkedContentsUseCaseFactory.swift +// FLINT +// +// Created by 김호성 on 2026.02.09. +// + +import Foundation + +import Domain + +protocol FetchBookmarkedContentsUseCaseFactory: ContentRepositoryFactory, UserRepositoryFactory { + func makeFetchBookmarkedContentsUseCase() -> FetchBookmarkedContentsUseCase + func makeFetchBookmarkedContentsUseCase(contentRepository: ContentRepository, userRepository: UserRepository) -> FetchBookmarkedContentsUseCase +} + +extension FetchBookmarkedContentsUseCaseFactory { + func makeFetchBookmarkedContentsUseCase() -> FetchBookmarkedContentsUseCase { + return makeFetchBookmarkedContentsUseCase(contentRepository: makeContentRepository(), userRepository: makeUserRepository()) + } + func makeFetchBookmarkedContentsUseCase(contentRepository: ContentRepository, userRepository: UserRepository) -> FetchBookmarkedContentsUseCase { + return DefaultFetchBookmarkedContentsUseCase(contentRepository: contentRepository, userRepository: userRepository) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/Content/FetchOTTPlatformsForContentUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Content/FetchOTTPlatformsForContentUseCaseFactory.swift new file mode 100644 index 00000000..745b8bf4 --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/UseCase/Content/FetchOTTPlatformsForContentUseCaseFactory.swift @@ -0,0 +1,24 @@ +// +// FetchOTTPlatformsForContentUseCaseFactory.swift +// FLINT +// +// Created by 김호성 on 2026.02.09. +// + +import Foundation + +import Domain + +protocol FetchOTTPlatformsForContentUseCaseFactory: ContentRepositoryFactory { + func makeFetchOTTPlatformsForContentUseCase() -> FetchOTTPlatformsForContentUseCase + func makeFetchOTTPlatformsForContentUseCase(contentRepository: ContentRepository) -> FetchOTTPlatformsForContentUseCase +} + +extension FetchOTTPlatformsForContentUseCaseFactory { + func makeFetchOTTPlatformsForContentUseCase() -> FetchOTTPlatformsForContentUseCase { + return makeFetchOTTPlatformsForContentUseCase(contentRepository: makeContentRepository()) + } + func makeFetchOTTPlatformsForContentUseCase(contentRepository: ContentRepository) -> FetchOTTPlatformsForContentUseCase { + return DefaultFetchOTTPlatformsForContentUseCase(contentRepository: contentRepository) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/Content/FetchPopularContentsUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Content/FetchPopularContentsUseCaseFactory.swift new file mode 100644 index 00000000..8412702d --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/UseCase/Content/FetchPopularContentsUseCaseFactory.swift @@ -0,0 +1,24 @@ +// +// FetchPopularContentsUseCaseFactory.swift +// FLINT +// +// Created by 김호성 on 2026.02.09. +// + +import Foundation + +import Domain + +protocol FetchPopularContentsUseCaseFactory: SearchRepositoryFactory { + func makeFetchPopularContentsUseCase() -> FetchPopularContentsUseCase + func makeFetchPopularContentsUseCase(searchRepository: SearchRepository) -> FetchPopularContentsUseCase +} + +extension FetchPopularContentsUseCaseFactory { + func makeFetchPopularContentsUseCase() -> FetchPopularContentsUseCase { + return makeFetchPopularContentsUseCase(searchRepository: makeSearchRepository()) + } + func makeFetchPopularContentsUseCase(searchRepository: SearchRepository) -> FetchPopularContentsUseCase { + return DefaultFetchPopularContentsUseCase(searchRepository: searchRepository) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/SearchContentsUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Content/SearchContentsUseCaseFactory.swift similarity index 100% rename from FLINT/FLINT/Dependency/Factory/UseCase/SearchContentsUseCaseFactory.swift rename to FLINT/FLINT/Dependency/Factory/UseCase/Content/SearchContentsUseCaseFactory.swift diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/Content/ToggleContentBookmarkUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Content/ToggleContentBookmarkUseCaseFactory.swift new file mode 100644 index 00000000..5526e86b --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/UseCase/Content/ToggleContentBookmarkUseCaseFactory.swift @@ -0,0 +1,24 @@ +// +// ToggleContentBookmarkUseCaseFactory.swift +// FLINT +// +// Created by 김호성 on 2026.02.09. +// + +import Foundation + +import Domain + +protocol ToggleContentBookmarkUseCaseFactory: BookmarkRepositoryFactory { + func makeToggleContentBookmarkUseCase() -> ToggleContentBookmarkUseCase + func makeToggleContentBookmarkUseCase(bookmarkRepository: BookmarkRepository) -> ToggleContentBookmarkUseCase +} + +extension ToggleContentBookmarkUseCaseFactory { + func makeToggleContentBookmarkUseCase() -> ToggleContentBookmarkUseCase { + return makeToggleContentBookmarkUseCase(bookmarkRepository: makeBookmarkRepository()) + } + func makeToggleContentBookmarkUseCase(bookmarkRepository: BookmarkRepository) -> ToggleContentBookmarkUseCase { + return DefaultToggleContentBookmarkUseCase(bookmarkRepository: bookmarkRepository) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/ContentsUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/ContentsUseCaseFactory.swift deleted file mode 100644 index 315451b5..00000000 --- a/FLINT/FLINT/Dependency/Factory/UseCase/ContentsUseCaseFactory.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// ContentsUseCase.swift -// FLINT -// -// Created by 김호성 on 2026.01.22. -// - -import Foundation - -import Domain - -protocol ContentsUseCaseFactory: SearchRepositoryFactory { - func makeContentsUseCase() -> ContentsUseCase - func makeContentsUseCase(searchRepository: SearchRepository) -> ContentsUseCase -} - -extension ContentsUseCaseFactory { - func makeContentsUseCase() -> ContentsUseCase { - return makeContentsUseCase(searchRepository: makeSearchRepository()) - } - func makeContentsUseCase(searchRepository: SearchRepository) -> ContentsUseCase { - return DefaultContentsUseCase(searchRepository: searchRepository) - } -} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/ExploreUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/ExploreUseCaseFactory.swift deleted file mode 100644 index 65766bf2..00000000 --- a/FLINT/FLINT/Dependency/Factory/UseCase/ExploreUseCaseFactory.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// File.swift -// FLINT -// -// Created by 김호성 on 2026.01.22. -// - -import Foundation - -import Domain - -protocol ExploreUseCaseFactory: CollectionRepositoryFactory { - func makeExploreUseCase() -> ExploreUseCase - func makeExploreUseCase(collectionRepository: CollectionRepository) -> ExploreUseCase -} - -extension ExploreUseCaseFactory { - func makeExploreUseCase() -> ExploreUseCase { - return makeExploreUseCase(collectionRepository: makeCollectionRepository()) - } - func makeExploreUseCase(collectionRepository: CollectionRepository) -> ExploreUseCase { - return DefaultExploreUseCase(collectionRepository: collectionRepository) - } -} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/FetchBookmarkedUserUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/FetchBookmarkedUserUseCaseFactory.swift deleted file mode 100644 index 84dd9db7..00000000 --- a/FLINT/FLINT/Dependency/Factory/UseCase/FetchBookmarkedUserUseCaseFactory.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// BookmarkFactory.swift -// FLINT -// -// Created by 진소은 on 1/23/26. -// - -import Foundation -import Moya - -import Data -import Domain -import Presentation - -protocol FetchBookmarkedUserUseCaseFactory: BookmarkRepositoryFactory { - func makeFetchBookmarkedUserUseCase() -> FetchBookmarkedUserUseCase - func makeFetchBookmarkedUserUseCase(bookmarkRepository: BookmarkRepository) -> FetchBookmarkedUserUseCase -} - -extension FetchBookmarkedUserUseCaseFactory { - func makeFetchBookmarkedUserUseCase() -> FetchBookmarkedUserUseCase { - return makeFetchBookmarkedUserUseCase(bookmarkRepository: makeBookmarkRepository()) - } - func makeFetchBookmarkedUserUseCase(bookmarkRepository: BookmarkRepository) -> FetchBookmarkedUserUseCase { - return DefaultFetchBookmarkedUserUseCase(bookmarkRepository: bookmarkRepository) - } -} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/FetchWatchingCollectionsUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/FetchWatchingCollectionsUseCaseFactory.swift deleted file mode 100644 index c3dcb30c..00000000 --- a/FLINT/FLINT/Dependency/Factory/UseCase/FetchWatchingCollectionsUseCaseFactory.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// FetchWatchingCollectionsUseCaseFactory.swift -// FLINT -// -// Created by 김호성 on 2026.02.02. -// - -import Foundation - -import Domain - -protocol FetchWatchingCollectionsUseCaseFactory: CollectionRepositoryFactory { - func makeFetchWatchingCollectionsUseCase() -> FetchWatchingCollectionsUseCase - func makeFetchWatchingCollectionsUseCase(collectionRepository: CollectionRepository) -> FetchWatchingCollectionsUseCase -} - -extension FetchWatchingCollectionsUseCaseFactory { - func makeFetchWatchingCollectionsUseCase() -> FetchWatchingCollectionsUseCase { - return makeFetchWatchingCollectionsUseCase(collectionRepository: makeCollectionRepository()) - } - func makeFetchWatchingCollectionsUseCase(collectionRepository: CollectionRepository) -> FetchWatchingCollectionsUseCase { - return DefaultFetchWatchingCollectionsUseCase(collectionRepository: collectionRepository) - } -} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/HomeUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/HomeUseCaseFactory.swift deleted file mode 100644 index e2db3a5a..00000000 --- a/FLINT/FLINT/Dependency/Factory/UseCase/HomeUseCaseFactory.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// HomeUseCaseFactory.swift -// FLINT -// -// Created by 김호성 on 2026.02.02. -// - -import Foundation - -import Domain - -protocol HomeUseCaseFactory: HomeRepositoryFactory { - func makeHomeUseCase() -> HomeUseCase - func makeHomeUseCase(homeRepository: HomeRepository) -> HomeUseCase -} - -extension HomeUseCaseFactory { - func makeHomeUseCase() -> HomeUseCase { - return makeHomeUseCase(homeRepository: makeHomeRepository()) - } - func makeHomeUseCase(homeRepository: HomeRepository) -> HomeUseCase { - return DefaultHomeUseCase(homeRepository: homeRepository) - } -} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/NicknameUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/NicknameUseCaseFactory.swift deleted file mode 100644 index c3123495..00000000 --- a/FLINT/FLINT/Dependency/Factory/UseCase/NicknameUseCaseFactory.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// File.swift -// FLINT -// -// Created by 김호성 on 2026.01.22. -// - -import Foundation - -import Domain - -protocol NicknameUseCaseFactory: UserRepositoryFactory { - func makeNicknameUseCase() -> NicknameUseCase - func makeNicknameUseCase(userRepository: UserRepository) -> NicknameUseCase -} - -extension NicknameUseCaseFactory { - func makeNicknameUseCase() -> NicknameUseCase { - return makeNicknameUseCase(userRepository: makeUserRepository()) - } - func makeNicknameUseCase(userRepository: UserRepository) -> NicknameUseCase { - return DefaultNicknameUseCase(userRepository: userRepository) - } -} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/Profile/CheckNicknameUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Profile/CheckNicknameUseCaseFactory.swift new file mode 100644 index 00000000..16e0b2c4 --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/UseCase/Profile/CheckNicknameUseCaseFactory.swift @@ -0,0 +1,24 @@ +// +// CheckNicknameUseCaseFactory.swift +// FLINT +// +// Created by 김호성 on 2026.01.22. +// + +import Foundation + +import Domain + +protocol CheckNicknameUseCaseFactory: UserRepositoryFactory { + func makeCheckNicknameUseCase() -> CheckNicknameUseCase + func makeCheckNicknameUseCase(userRepository: UserRepository) -> CheckNicknameUseCase +} + +extension CheckNicknameUseCaseFactory { + func makeCheckNicknameUseCase() -> CheckNicknameUseCase { + return makeCheckNicknameUseCase(userRepository: makeUserRepository()) + } + func makeCheckNicknameUseCase(userRepository: UserRepository) -> CheckNicknameUseCase { + return DefaultCheckNicknameUseCase(userRepository: userRepository) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/Profile/FetchKeywordsUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Profile/FetchKeywordsUseCaseFactory.swift new file mode 100644 index 00000000..7a1a728a --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/UseCase/Profile/FetchKeywordsUseCaseFactory.swift @@ -0,0 +1,24 @@ +// +// FetchKeywordsUseCaseFactory.swift +// FLINT +// +// Created by 김호성 on 2026.02.09. +// + +import Foundation + +import Domain + +protocol FetchKeywordsUseCaseFactory: UserRepositoryFactory { + func makeFetchKeywordsUseCase() -> FetchKeywordsUseCase + func makeFetchKeywordsUseCase(userRepository: UserRepository) -> FetchKeywordsUseCase +} + +extension FetchKeywordsUseCaseFactory { + func makeFetchKeywordsUseCase() -> FetchKeywordsUseCase { + return makeFetchKeywordsUseCase(userRepository: makeUserRepository()) + } + func makeFetchKeywordsUseCase(userRepository: UserRepository) -> FetchKeywordsUseCase { + return DefaultFetchKeywordsUseCase(userRepository: userRepository) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/Profile/FetchProfileUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Profile/FetchProfileUseCaseFactory.swift new file mode 100644 index 00000000..f5065b44 --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/UseCase/Profile/FetchProfileUseCaseFactory.swift @@ -0,0 +1,24 @@ +// +// FetchProfileUseCaseFactory.swift +// FLINT +// +// Created by 김호성 on 2026.02.09. +// + +import Foundation + +import Domain + +protocol FetchProfileUseCaseFactory: UserRepositoryFactory { + func makeFetchProfileUseCase() -> FetchProfileUseCase + func makeFetchProfileUseCase(userRepository: UserRepository) -> FetchProfileUseCase +} + +extension FetchProfileUseCaseFactory { + func makeFetchProfileUseCase() -> FetchProfileUseCase { + return makeFetchProfileUseCase(userRepository: makeUserRepository()) + } + func makeFetchProfileUseCase(userRepository: UserRepository) -> FetchProfileUseCase { + return DefaultFetchProfileUseCase(userRepository: userRepository) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/UserProfileUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/UserProfileUseCaseFactory.swift deleted file mode 100644 index f0f08ed6..00000000 --- a/FLINT/FLINT/Dependency/Factory/UseCase/UserProfileUseCaseFactory.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// UserProfileUseCaseFactory.swift -// FLINT -// -// Created by 김호성 on 2026.01.31. -// - -import Foundation - -import Domain - -protocol UserProfileUseCaseFactory: UserRepositoryFactory { - func makeUserProfileUseCase() -> UserProfileUseCase - func makeUserProfileUseCase(userRepository: UserRepository) -> UserProfileUseCase -} - -extension UserProfileUseCaseFactory { - func makeUserProfileUseCase() -> UserProfileUseCase { - return makeUserProfileUseCase(userRepository: makeUserRepository()) - } - func makeUserProfileUseCase(userRepository: UserRepository) -> UserProfileUseCase { - return DefaultUserProfileUseCase(userRepository: userRepository) - } -} diff --git a/FLINT/FLINT/Dependency/Factory/ViewController/ProfileViewControllerFactory+.swift b/FLINT/FLINT/Dependency/Factory/ViewController/ProfileViewControllerFactory+.swift index b6d6bdab..9b04e531 100644 --- a/FLINT/FLINT/Dependency/Factory/ViewController/ProfileViewControllerFactory+.swift +++ b/FLINT/FLINT/Dependency/Factory/ViewController/ProfileViewControllerFactory+.swift @@ -7,6 +7,7 @@ import Foundation +import Domain import Presentation extension ProfileViewControllerFactory where Self: ProfileViewModelFactory & ViewControllerFactory { @@ -15,7 +16,7 @@ extension ProfileViewControllerFactory where Self: ProfileViewModelFactory & Vie } func makeProfileViewController( - target: ProfileViewModel.Target = .me + target: UserTarget = .me ) -> ProfileViewController { return ProfileViewController( profileViewModel: makeProfileViewModel(target: target), diff --git a/FLINT/FLINT/Dependency/Factory/ViewModel/AddContentSelectViewModelFactory.swift b/FLINT/FLINT/Dependency/Factory/ViewModel/AddContentSelectViewModelFactory.swift index e5db071b..f36f9610 100644 --- a/FLINT/FLINT/Dependency/Factory/ViewModel/AddContentSelectViewModelFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/ViewModel/AddContentSelectViewModelFactory.swift @@ -10,10 +10,10 @@ import Foundation import Domain import Presentation -protocol AddContentSelectViewModelFactory: SearchContentsUseCaseFactory, ContentsUseCaseFactory { +protocol AddContentSelectViewModelFactory: SearchContentsUseCaseFactory, FetchPopularContentsUseCaseFactory { func makeAddContentSelectViewModel() -> AddContentSelectViewModel func makeAddContentSelectViewModel( - contentsUseCase: ContentsUseCase, + fetchPopularContentsUseCase: FetchPopularContentsUseCase, searchContentsUseCase: SearchContentsUseCase ) -> AddContentSelectViewModel } @@ -22,17 +22,17 @@ extension AddContentSelectViewModelFactory { func makeAddContentSelectViewModel() -> AddContentSelectViewModel { return makeAddContentSelectViewModel( - contentsUseCase: makeContentsUseCase(), + fetchPopularContentsUseCase: makeFetchPopularContentsUseCase(), searchContentsUseCase: makeSearchContentsUseCase() ) } func makeAddContentSelectViewModel( - contentsUseCase: ContentsUseCase, + fetchPopularContentsUseCase: FetchPopularContentsUseCase, searchContentsUseCase: SearchContentsUseCase ) -> AddContentSelectViewModel { return DefaultAddContentSelectViewModel( - contentsUseCase: contentsUseCase, + fetchPopularContentsUseCase: fetchPopularContentsUseCase, searchContentsUseCase: searchContentsUseCase ) } diff --git a/FLINT/FLINT/Dependency/Factory/ViewModel/CollectionDetailViewModelFactory.swift b/FLINT/FLINT/Dependency/Factory/ViewModel/CollectionDetailViewModelFactory.swift index 9f8e18d6..51beb499 100644 --- a/FLINT/FLINT/Dependency/Factory/ViewModel/CollectionDetailViewModelFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/ViewModel/CollectionDetailViewModelFactory.swift @@ -10,11 +10,12 @@ import Foundation import Domain import Presentation -protocol CollectionDetailViewModelFactory: CollectionDetailUseCaseFactory, FetchBookmarkedUserUseCaseFactory { +protocol CollectionDetailViewModelFactory: FetchCollectionDetailUseCaseFactory, FetchCollectionBookmarkUsersUseCaseFactory { func makeCollectionDetailViewModel(collectionId: Int64) -> CollectionDetailViewModel func makeCollectionDetailViewModel( collectionId: Int64, - collectionDetailUseCase: CollectionDetailUseCase + fetchCollectionDetailUseCase: FetchCollectionDetailUseCase, + fetchCollectionBookmarkUsersUseCase: FetchCollectionBookmarkUsersUseCase ) -> CollectionDetailViewModel } @@ -22,17 +23,19 @@ extension CollectionDetailViewModelFactory { func makeCollectionDetailViewModel(collectionId: Int64) -> CollectionDetailViewModel { return makeCollectionDetailViewModel( collectionId: collectionId, - collectionDetailUseCase: makeCollectionDetailUseCase() + fetchCollectionDetailUseCase: makeFetchCollectionDetailUseCase(), + fetchCollectionBookmarkUsersUseCase: makeFetchCollectionBookmarkUsersUseCase() ) } func makeCollectionDetailViewModel( collectionId: Int64, - collectionDetailUseCase: CollectionDetailUseCase + fetchCollectionDetailUseCase: FetchCollectionDetailUseCase, + fetchCollectionBookmarkUsersUseCase: FetchCollectionBookmarkUsersUseCase ) -> CollectionDetailViewModel { return CollectionDetailViewModel( collectionId: collectionId, - collectionDetailUseCase: collectionDetailUseCase, - fetchBookmarkedUserUseCase: makeFetchBookmarkedUserUseCase() + fetchCollectionDetailUseCase: fetchCollectionDetailUseCase, + fetchCollectionBookmarkUsersUseCase: fetchCollectionBookmarkUsersUseCase ) } } diff --git a/FLINT/FLINT/Dependency/Factory/ViewModel/CollectionFolderListViewModelFactory.swift b/FLINT/FLINT/Dependency/Factory/ViewModel/CollectionFolderListViewModelFactory.swift index e51f8564..cf6fc1e9 100644 --- a/FLINT/FLINT/Dependency/Factory/ViewModel/CollectionFolderListViewModelFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/ViewModel/CollectionFolderListViewModelFactory.swift @@ -10,16 +10,16 @@ import Foundation import Domain import Presentation -protocol CollectionFolderListViewModelFactory: FetchWatchingCollectionsUseCaseFactory { +protocol CollectionFolderListViewModelFactory: FetchRecentViewedCollectionsUseCaseFactory { func makeCollectionFolderListViewModel() -> CollectionFolderListViewModel - func makeCollectionFolderListViewModel(fetchWatchingCollectionsUseCase: FetchWatchingCollectionsUseCase) -> CollectionFolderListViewModel + func makeCollectionFolderListViewModel(fetchRecentViewedCollectionsUseCase: FetchRecentViewedCollectionsUseCase) -> CollectionFolderListViewModel } extension CollectionFolderListViewModelFactory { func makeCollectionFolderListViewModel() -> CollectionFolderListViewModel { - return makeCollectionFolderListViewModel(fetchWatchingCollectionsUseCase: makeFetchWatchingCollectionsUseCase()) + return makeCollectionFolderListViewModel(fetchRecentViewedCollectionsUseCase: makeFetchRecentViewedCollectionsUseCase()) } - func makeCollectionFolderListViewModel(fetchWatchingCollectionsUseCase: FetchWatchingCollectionsUseCase) -> CollectionFolderListViewModel { - return CollectionFolderListViewModel(fetchWatchingCollectionsUseCase: fetchWatchingCollectionsUseCase) + func makeCollectionFolderListViewModel(fetchRecentViewedCollectionsUseCase: FetchRecentViewedCollectionsUseCase) -> CollectionFolderListViewModel { + return CollectionFolderListViewModel(fetchRecentViewedCollectionsUseCase: fetchRecentViewedCollectionsUseCase) } } diff --git a/FLINT/FLINT/Dependency/Factory/ViewModel/ExploreViewModelFactory.swift b/FLINT/FLINT/Dependency/Factory/ViewModel/ExploreViewModelFactory.swift index d208d7ce..6565c1c8 100644 --- a/FLINT/FLINT/Dependency/Factory/ViewModel/ExploreViewModelFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/ViewModel/ExploreViewModelFactory.swift @@ -1,5 +1,5 @@ // -// File.swift +// ExploreViewModelFactory.swift // FLINT // // Created by 김호성 on 2026.01.22. @@ -10,16 +10,16 @@ import Foundation import Domain import Presentation -protocol ExploreViewModelFactory: ExploreUseCaseFactory { +protocol ExploreViewModelFactory: FetchExploreCollectionsUseCaseFactory { func makeExploreViewModel() -> ExploreViewModel - func makeExploreViewModel(exploreUseCase: ExploreUseCase) -> ExploreViewModel + func makeExploreViewModel(fetchExploreCollectionsUseCase: FetchExploreCollectionsUseCase) -> ExploreViewModel } extension ExploreViewModelFactory { func makeExploreViewModel() -> ExploreViewModel { - return makeExploreViewModel(exploreUseCase: makeExploreUseCase()) + return makeExploreViewModel(fetchExploreCollectionsUseCase: makeFetchExploreCollectionsUseCase()) } - func makeExploreViewModel(exploreUseCase: ExploreUseCase) -> ExploreViewModel { - return DefaultExploreViewModel(exploreUseCase: exploreUseCase) + func makeExploreViewModel(fetchExploreCollectionsUseCase: FetchExploreCollectionsUseCase) -> ExploreViewModel { + return DefaultExploreViewModel(fetchExploreCollectionsUseCase: fetchExploreCollectionsUseCase) } } diff --git a/FLINT/FLINT/Dependency/Factory/ViewModel/HomeViewModelFactory.swift b/FLINT/FLINT/Dependency/Factory/ViewModel/HomeViewModelFactory.swift index 3425cfcf..a34c5053 100644 --- a/FLINT/FLINT/Dependency/Factory/ViewModel/HomeViewModelFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/ViewModel/HomeViewModelFactory.swift @@ -10,33 +10,40 @@ import Foundation import Domain import Presentation -protocol HomeViewModelFactory: HomeUseCaseFactory, UserProfileUseCaseFactory, FetchWatchingCollectionsUseCaseFactory { +protocol HomeViewModelFactory: FetchRecommendedCollectionsUseCaseFactory, FetchBookmarkedContentsUseCaseFactory, FetchProfileUseCaseFactory, FetchRecentViewedCollectionsUseCaseFactory { func makeHomeViewModel() -> HomeViewModel func makeHomeViewModel( - homeUseCase: HomeUseCase, - userProfileUseCase: UserProfileUseCase, - fetchWatchingCollectionsUseCase: FetchWatchingCollectionsUseCase + fetchRecommendedCollectionsUseCase: FetchRecommendedCollectionsUseCase, + fetchBookmarkedContentsUseCase: FetchBookmarkedContentsUseCase, + fetchProfileUseCase: FetchProfileUseCase, + fetchRecentViewedCollectionsUseCase: FetchRecentViewedCollectionsUseCase, + initialUserName: String ) -> HomeViewModel } extension HomeViewModelFactory { func makeHomeViewModel() -> HomeViewModel { return makeHomeViewModel( - homeUseCase: makeHomeUseCase(), - userProfileUseCase: makeUserProfileUseCase(), - fetchWatchingCollectionsUseCase: makeFetchWatchingCollectionsUseCase() + fetchRecommendedCollectionsUseCase: makeFetchRecommendedCollectionsUseCase(), + fetchBookmarkedContentsUseCase: makeFetchBookmarkedContentsUseCase(), + fetchProfileUseCase: makeFetchProfileUseCase(), + fetchRecentViewedCollectionsUseCase: makeFetchRecentViewedCollectionsUseCase(), + initialUserName: "얀비" ) } func makeHomeViewModel( - homeUseCase: HomeUseCase, - userProfileUseCase: UserProfileUseCase, - fetchWatchingCollectionsUseCase: FetchWatchingCollectionsUseCase + fetchRecommendedCollectionsUseCase: FetchRecommendedCollectionsUseCase, + fetchBookmarkedContentsUseCase: FetchBookmarkedContentsUseCase, + fetchProfileUseCase: FetchProfileUseCase, + fetchRecentViewedCollectionsUseCase: FetchRecentViewedCollectionsUseCase, + initialUserName: String ) -> HomeViewModel { return HomeViewModel( - homeUseCase: homeUseCase, - userProfileUseCase: userProfileUseCase, - fetchWatchingCollectionsUseCase: fetchWatchingCollectionsUseCase, + fetchRecommendedCollectionsUseCase: fetchRecommendedCollectionsUseCase, + fetchBookmarkedContentsUseCase: fetchBookmarkedContentsUseCase, + fetchProfileUseCase: fetchProfileUseCase, + fetchRecentViewedCollectionsUseCase: fetchRecentViewedCollectionsUseCase, initialUserName: "얀비" ) } diff --git a/FLINT/FLINT/Dependency/Factory/ViewModel/OnboardingViewModelFactory.swift b/FLINT/FLINT/Dependency/Factory/ViewModel/OnboardingViewModelFactory.swift index 84181aff..53afcad9 100644 --- a/FLINT/FLINT/Dependency/Factory/ViewModel/OnboardingViewModelFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/ViewModel/OnboardingViewModelFactory.swift @@ -1,5 +1,5 @@ // -// File.swift +// OnboardingViewModelFactory.swift // FLINT // // Created by 김호성 on 2026.01.22. @@ -10,21 +10,21 @@ import Foundation import Domain import Presentation -protocol OnboardingViewModelFactory: NicknameUseCaseFactory, SearchContentsUseCaseFactory, ContentsUseCaseFactory, SignupUseCaseFactory { +protocol OnboardingViewModelFactory: CheckNicknameUseCaseFactory, SearchContentsUseCaseFactory, FetchPopularContentsUseCaseFactory, SignupUseCaseFactory { func makeOnboardingViewModel() -> OnboardingViewModel - func makeOnboardingViewModel(nicknameUseCase: NicknameUseCase, contentsUseCase: ContentsUseCase, searchContentsUseCase: SearchContentsUseCase, signupUseCase: SignupUseCase) -> OnboardingViewModel + func makeOnboardingViewModel(checkNicknameUseCase: CheckNicknameUseCase, fetchPopularContentsUseCase: FetchPopularContentsUseCase, searchContentsUseCase: SearchContentsUseCase, signupUseCase: SignupUseCase) -> OnboardingViewModel } extension OnboardingViewModelFactory { func makeOnboardingViewModel() -> OnboardingViewModel { return makeOnboardingViewModel( - nicknameUseCase: makeNicknameUseCase(), - contentsUseCase: makeContentsUseCase(), + checkNicknameUseCase: makeCheckNicknameUseCase(), + fetchPopularContentsUseCase: makeFetchPopularContentsUseCase(), searchContentsUseCase: makeSearchContentsUseCase(), signupUseCase: makeSignupUseCase() ) } - func makeOnboardingViewModel(nicknameUseCase: NicknameUseCase, contentsUseCase: ContentsUseCase, searchContentsUseCase: SearchContentsUseCase, signupUseCase: SignupUseCase) -> OnboardingViewModel { - return DefaultOnboardingViewModel(nicknameUseCase: nicknameUseCase, contentsUseCase: contentsUseCase, searchContentsUseCase: searchContentsUseCase, signupUseCase: signupUseCase) + func makeOnboardingViewModel(checkNicknameUseCase: CheckNicknameUseCase, fetchPopularContentsUseCase: FetchPopularContentsUseCase, searchContentsUseCase: SearchContentsUseCase, signupUseCase: SignupUseCase) -> OnboardingViewModel { + return DefaultOnboardingViewModel(checkNicknameUseCase: checkNicknameUseCase, fetchPopularContentsUseCase: fetchPopularContentsUseCase, searchContentsUseCase: searchContentsUseCase, signupUseCase: signupUseCase) } } diff --git a/FLINT/FLINT/Dependency/Factory/ViewModel/ProfileViewModelFactory.swift b/FLINT/FLINT/Dependency/Factory/ViewModel/ProfileViewModelFactory.swift index 94bdd973..e20a2073 100644 --- a/FLINT/FLINT/Dependency/Factory/ViewModel/ProfileViewModelFactory.swift +++ b/FLINT/FLINT/Dependency/Factory/ViewModel/ProfileViewModelFactory.swift @@ -10,24 +10,44 @@ import Foundation import Domain import Presentation -protocol ProfileViewModelFactory: UserProfileUseCaseFactory { - func makeProfileViewModel() -> ProfileViewModel +protocol ProfileViewModelFactory: FetchProfileUseCaseFactory, FetchKeywordsUseCaseFactory, FetchCreatedCollectionsUseCaseFactory, FetchBookmarkedCollectionsUseCaseFactory, FetchBookmarkedContentsUseCaseFactory { + func makeProfileViewModel(target: UserTarget) -> ProfileViewModel func makeProfileViewModel( - target: ProfileViewModel.Target - ) -> ProfileViewModel + target: UserTarget, + fetchProfileUseCase: FetchProfileUseCase, + fetchKeywordsUseCase: FetchKeywordsUseCase, + fetchCreatedCollectionsUseCase: FetchCreatedCollectionsUseCase, + fetchBookmarkedCollectionsUseCase: FetchBookmarkedCollectionsUseCase, + fetchBookmarkedContentsUseCase: FetchBookmarkedContentsUseCase + ) -> ProfileViewModel } extension ProfileViewModelFactory { - func makeProfileViewModel() -> ProfileViewModel { - return makeProfileViewModel(target: .me) + func makeProfileViewModel(target: UserTarget) -> ProfileViewModel { + return makeProfileViewModel( + target: target, + fetchProfileUseCase: makeFetchProfileUseCase(), + fetchKeywordsUseCase: makeFetchKeywordsUseCase(), + fetchCreatedCollectionsUseCase: makeFetchCreatedCollectionsUseCase(), + fetchBookmarkedCollectionsUseCase: makeFetchBookmarkedCollectionsUseCase(), + fetchBookmarkedContentsUseCase: makeFetchBookmarkedContentsUseCase() + ) } - func makeProfileViewModel( - target: ProfileViewModel.Target + target: UserTarget, + fetchProfileUseCase: FetchProfileUseCase, + fetchKeywordsUseCase: FetchKeywordsUseCase, + fetchCreatedCollectionsUseCase: FetchCreatedCollectionsUseCase, + fetchBookmarkedCollectionsUseCase: FetchBookmarkedCollectionsUseCase, + fetchBookmarkedContentsUseCase: FetchBookmarkedContentsUseCase ) -> ProfileViewModel { return ProfileViewModel( target: target, - userProfileUseCase: makeUserProfileUseCase() + fetchProfileUseCase: fetchProfileUseCase, + fetchKeywordsUseCase: fetchKeywordsUseCase, + fetchCreatedCollectionsUseCase: fetchCreatedCollectionsUseCase, + fetchBookmarkedCollectionsUseCase: fetchBookmarkedCollectionsUseCase, + fetchBookmarkedContentsUseCase: fetchBookmarkedContentsUseCase ) } } diff --git a/FLINT/Presentation/Sources/View/Component/MoreNoMoreCollection/MoreNoMoreCollectionItemCell.swift b/FLINT/Presentation/Sources/View/Component/MoreNoMoreCollection/MoreNoMoreCollectionItemCell.swift index 2cd927de..2fe268d5 100644 --- a/FLINT/Presentation/Sources/View/Component/MoreNoMoreCollection/MoreNoMoreCollectionItemCell.swift +++ b/FLINT/Presentation/Sources/View/Component/MoreNoMoreCollection/MoreNoMoreCollectionItemCell.swift @@ -110,10 +110,10 @@ public final class MoreNoMoreCollectionItemCell: BaseCollectionViewCell { userNameLabel.attributedText = nil } - public func configure(entity: CollectionEntity) { + public func configure(entity: CollectionInfoEntity) { // 썸네일 - if let url = URL(string: entity.thumbnailUrl) { + if let url = entity.imageUrl { posterImageView.kf.setImage( with: url, placeholder: UIImage(resource: .imgBackgroundGradiantMiddle) @@ -123,7 +123,7 @@ public final class MoreNoMoreCollectionItemCell: BaseCollectionViewCell { } // 프로필 이미지 - if let url = URL(string: entity.profileImageUrl) { + if let url = entity.profileImageUrl { profileImageView.kf.setImage( with: url, placeholder: UIImage(resource: .imgProfileGray) @@ -141,7 +141,7 @@ public final class MoreNoMoreCollectionItemCell: BaseCollectionViewCell { userNameLabel.attributedText = .pretendard( .caption1_r_12, - text: entity.nickname, + text: entity.userName, color: .flintGray200 ) } diff --git a/FLINT/Presentation/Sources/View/Component/MoreNoMoreCollection/MoreNoMoreCollectionTableViewCell.swift b/FLINT/Presentation/Sources/View/Component/MoreNoMoreCollection/MoreNoMoreCollectionTableViewCell.swift index f0588dd4..7be44e0f 100644 --- a/FLINT/Presentation/Sources/View/Component/MoreNoMoreCollection/MoreNoMoreCollectionTableViewCell.swift +++ b/FLINT/Presentation/Sources/View/Component/MoreNoMoreCollection/MoreNoMoreCollectionTableViewCell.swift @@ -14,8 +14,8 @@ import Entity public final class MoreNoMoreCollectionTableViewCell: BaseTableViewCell { - public var onSelectItem: ((CollectionEntity) -> Void)? - private var items: [CollectionEntity] = [] + public var onSelectItem: ((CollectionInfoEntity) -> Void)? + private var items: [CollectionInfoEntity] = [] // MARK: - UI @@ -62,7 +62,7 @@ public final class MoreNoMoreCollectionTableViewCell: BaseTableViewCell { // MARK: - Public - public func configure(items: [CollectionEntity]) { + public func configure(items: [CollectionInfoEntity]) { self.items = items collectionView.reloadData() } diff --git a/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/KeywordColor+.swift b/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/KeywordColor+.swift new file mode 100644 index 00000000..1a012418 --- /dev/null +++ b/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/KeywordColor+.swift @@ -0,0 +1,22 @@ +// +// KeywordColor+.swift +// FLINT +// +// Created by 진소은 on 1/18/26. +// + +import UIKit + +import Domain + +extension KeywordColor { + public var tagBackgroundImage: UIImage { + switch self { + case .pink: return UIImage(resource: .imgTagPink) + case .green: return UIImage(resource: .imgTagGreen) + case .orange: return UIImage(resource: .imgTagOrange) + case .yellow: return UIImage(resource: .imgTagYellow) + case .blue: return UIImage(resource: .imgTagBlue) + } + } +} diff --git a/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/KeywordColor.swift b/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/KeywordColor.swift deleted file mode 100644 index fed07294..00000000 --- a/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/KeywordColor.swift +++ /dev/null @@ -1,45 +0,0 @@ -// -// KeywordColor.swift -// FLINT -// -// Created by 진소은 on 1/18/26. -// - -import Foundation -import UIKit - -public enum KeywordColor: String, Decodable { - case pink = "PINK" - case green = "GREEN" - case orange = "ORANGE" - case yellow = "YELLOW" - case blue = "BLUE" -} - -public struct KeywordDTO: Decodable { - public let color: KeywordColor - public let rank: Int - public let name: String - public let percentage: Int - public let imageUrl: String - - public init(color: KeywordColor, rank: Int, name: String, percentage: Int, imageUrl: String) { - self.color = color - self.rank = rank - self.name = name - self.percentage = percentage - self.imageUrl = imageUrl - } -} - -extension KeywordColor { - public var tagBackgroundImage: UIImage { - switch self { - case .pink: return UIImage(resource: .imgTagPink) - case .green: return UIImage(resource: .imgTagGreen) - case .orange: return UIImage(resource: .imgTagOrange) - case .yellow: return UIImage(resource: .imgTagYellow) - case .blue: return UIImage(resource: .imgTagBlue) - } - } -} diff --git a/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/PreferenceChip.swift b/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/PreferenceChip.swift index 4cd44f1a..c1fc4ba9 100644 --- a/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/PreferenceChip.swift +++ b/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/PreferenceChip.swift @@ -7,9 +7,11 @@ import UIKit +import Kingfisher import SnapKit import Then -import Kingfisher + +import Domain public final class PreferenceChip: BaseView { @@ -64,12 +66,12 @@ public final class PreferenceChip: BaseView { // MARK: - Public - public func configure(dto: KeywordDTO) { - style = PreferenceChipStyle.from(rank: dto.rank, color: dto.color) + public func configure(keyword: KeywordEntity) { + style = PreferenceChipStyle.from(rank: keyword.rank, color: keyword.color) - keywordLabel.attributedText = .pretendard(.head2_m_20, text: dto.name, color: .white) + keywordLabel.attributedText = .pretendard(.head2_m_20, text: keyword.name, color: .white) - applyResizableBackground(style.backgroundImage(for: dto.color)) + applyResizableBackground(style.backgroundImage(for: keyword.color)) contentStackView.spacing = style.spacing iconImageView.isHidden = (style.iconSize == 0) @@ -78,15 +80,11 @@ public final class PreferenceChip: BaseView { iconImageView.kf.cancelDownloadTask() iconImageView.image = nil } else { - if let url = URL(string: dto.imageUrl) { - iconImageView.kf.setImage( - with: url, - placeholder: nil, - options: [.transition(.fade(0.15)), .cacheOriginalImage] - ) - } else { - iconImageView.image = nil - } + iconImageView.kf.setImage( + with: keyword.imageUrl, + placeholder: nil, + options: [.transition(.fade(0.15)), .cacheOriginalImage] + ) } invalidateIntrinsicContentSize() diff --git a/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/PreferenceChipStyle.swift b/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/PreferenceChipStyle.swift index 02f341c4..4b4937f3 100644 --- a/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/PreferenceChipStyle.swift +++ b/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/PreferenceChipStyle.swift @@ -8,6 +8,8 @@ import Foundation import UIKit +import Domain + public enum PreferenceChipStyle { case colored(KeywordColor) case gray diff --git a/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/PreferenceExampleView.swift b/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/PreferenceExampleView.swift index 1e6aac4b..b422dbee 100644 --- a/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/PreferenceExampleView.swift +++ b/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/PreferenceExampleView.swift @@ -11,6 +11,8 @@ import Kingfisher import SnapKit import Then +import Domain + public final class PreferenceExampleView: BaseView { private let rankedView = PreferenceRankedChipView() @@ -26,13 +28,13 @@ public final class PreferenceExampleView: BaseView { $0.center.equalToSuperview() } - let dummyData: [KeywordDTO] = [ - .init(color: .blue, rank: 1, name: "영화", percentage: 0, imageUrl: "https://picsum.photos/seed/1/80"), - .init(color: .pink, rank: 2, name: "SF", percentage: 0, imageUrl: "https://picsum.photos/seed/2/80"), - .init(color: .green, rank: 3, name: "로맨스", percentage: 0, imageUrl: "https://picsum.photos/seed/3/80"), - .init(color: .orange, rank: 4, name: "공포", percentage: 0, imageUrl: "https://picsum.photos/seed/4/80"), - .init(color: .yellow, rank: 5, name: "액션", percentage: 0, imageUrl: "https://picsum.photos/seed/5/80"), - .init(color: .pink, rank: 6, name: "성장", percentage: 0, imageUrl: "https://picsum.photos/seed/6/80"), + let dummyData: [KeywordEntity] = [ + .init(color: .blue, rank: 1, name: "영화", percentage: 0, imageUrl: URL(string: "https://picsum.photos/seed/1/80")), + .init(color: .pink, rank: 2, name: "SF", percentage: 0, imageUrl: URL(string: "https://picsum.photos/seed/2/80")), + .init(color: .green, rank: 3, name: "로맨스", percentage: 0, imageUrl: URL(string: "https://picsum.photos/seed/3/80")), + .init(color: .orange, rank: 4, name: "공포", percentage: 0, imageUrl: URL(string: "https://picsum.photos/seed/4/80")), + .init(color: .yellow, rank: 5, name: "액션", percentage: 0, imageUrl: URL(string: "https://picsum.photos/seed/5/80")), + .init(color: .pink, rank: 6, name: "성장", percentage: 0, imageUrl: URL(string: "https://picsum.photos/seed/6/80")), ] rankedView.configure(keywords: dummyData) diff --git a/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/PreferenceRankedChipView.swift b/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/PreferenceRankedChipView.swift index f068bf28..5f670937 100644 --- a/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/PreferenceRankedChipView.swift +++ b/FLINT/Presentation/Sources/View/Component/PreferenceKeyword/PreferenceRankedChipView.swift @@ -10,6 +10,8 @@ import UIKit import SnapKit import Then +import Domain + public final class PreferenceRankedChipView: BaseView { private let vStack = UIStackView().then { @@ -29,7 +31,7 @@ public final class PreferenceRankedChipView: BaseView { } } - public func configure(keywords: [KeywordDTO]) { + public func configure(keywords: [KeywordEntity]) { let byRank = Dictionary(uniqueKeysWithValues: keywords.map { ($0.rank, $0) }) let sumA = [1, 2, 4].compactMap { byRank[$0]?.name.count }.reduce(0, +) @@ -70,7 +72,7 @@ public final class PreferenceRankedChipView: BaseView { rankRow.forEach { r in guard let dto = byRank[r] else { return } let chip = PreferenceChip() - chip.configure(dto: dto) + chip.configure(keyword: dto) rowStack.addArrangedSubview(chip) } diff --git a/FLINT/Presentation/Sources/View/Scene/Profile/PreferenceRankedChipTableViewCell.swift b/FLINT/Presentation/Sources/View/Scene/Profile/PreferenceRankedChipTableViewCell.swift index a76b97ff..5ad51ee3 100644 --- a/FLINT/Presentation/Sources/View/Scene/Profile/PreferenceRankedChipTableViewCell.swift +++ b/FLINT/Presentation/Sources/View/Scene/Profile/PreferenceRankedChipTableViewCell.swift @@ -44,16 +44,7 @@ public final class PreferenceRankedChipTableViewCell: BaseTableViewCell { // public func configure(keywords: [KeywordDTO]) { // chipView.configure(keywords: keywords) // } - public func configure(entities: [KeywordEntity]) { - let keywords: [KeywordDTO] = entities.map { entity in - KeywordDTO( - color: KeywordColor(rawValue: entity.color) ?? .pink, // ⚠️ entity.color가 String이라고 가정 - rank: entity.rank, - name: entity.name, - percentage: entity.percentage, - imageUrl: entity.imageUrl - ) - } + public func configure(keywords: [KeywordEntity]) { chipView.configure(keywords: keywords) } } diff --git a/FLINT/Presentation/Sources/View/Scene/Profile/ProfileHeaderTableViewCell.swift b/FLINT/Presentation/Sources/View/Scene/Profile/ProfileHeaderTableViewCell.swift index 7a2deae3..db4fee91 100644 --- a/FLINT/Presentation/Sources/View/Scene/Profile/ProfileHeaderTableViewCell.swift +++ b/FLINT/Presentation/Sources/View/Scene/Profile/ProfileHeaderTableViewCell.swift @@ -88,14 +88,14 @@ public final class ProfileHeaderTableViewCell: BaseTableViewCell { public func configure( nickname: String = "", - profileImageUrl: String? = nil, + profileImageUrl: URL? = nil, isFliner: Bool = false ) { nameLabel.attributedText = .pretendard(.display2_m_28, text: nickname) verificationBadge.isHidden = !isFliner let placeholder = UIImage(resource: .imgProfileGray) - guard let urlString = profileImageUrl, let url = URL(string: urlString) else { + guard let url = profileImageUrl else { profileImageView.image = placeholder return } diff --git a/FLINT/Presentation/Sources/ViewController/Scene/CollectionDetail/CollectionDetailViewController.swift b/FLINT/Presentation/Sources/ViewController/Scene/CollectionDetail/CollectionDetailViewController.swift index 96dc4b99..535f0559 100644 --- a/FLINT/Presentation/Sources/ViewController/Scene/CollectionDetail/CollectionDetailViewController.swift +++ b/FLINT/Presentation/Sources/ViewController/Scene/CollectionDetail/CollectionDetailViewController.swift @@ -119,7 +119,7 @@ public final class CollectionDetailViewController: BaseViewController { public let exploreViewModel: ExploreViewModel + private var mainCollectionViewDataSource: UICollectionViewDiffableDataSource? + // MARK: - Component private let gradientBackgroundView = FixedGradientView().then { @@ -49,10 +51,7 @@ public final class ExploreViewController: BaseViewController { super.viewDidLoad() setNavigationBar(.init(left: .logo)) - rootView.mainCollectionView.register(ExploreCollectionViewCell.self) - rootView.mainCollectionView.register(ExploreEmptyCollectionViewCell.self) - rootView.mainCollectionView.delegate = self - rootView.mainCollectionView.dataSource = self + setupMainCollectionView() } // MARK: - Setup @@ -60,7 +59,8 @@ public final class ExploreViewController: BaseViewController { public override func bind() { exploreViewModel.collections.sink { [weak self] exploreInfoEntity in Log.d(exploreInfoEntity) - self?.rootView.mainCollectionView.reloadData() + guard let self else { return } + mainCollectionViewDataSource?.apply(makeSnapshot(exploreInfoEntities: exploreViewModel.collections.value), animatingDifferences: false) } .store(in: &cancellables) } @@ -78,6 +78,57 @@ public final class ExploreViewController: BaseViewController { } } +extension ExploreViewController { + private enum MainCollectionViewSection: Int { + case main + case empty + } + + private enum MainCollectionViewItem: Equatable, Hashable, Sendable { + case collection(ExploreInfoEntity) + case empty + } + + private func setupMainCollectionView() { + rootView.mainCollectionView.register(ExploreCollectionViewCell.self) + rootView.mainCollectionView.register(ExploreEmptyCollectionViewCell.self) + rootView.mainCollectionView.delegate = self + rootView.mainCollectionView.dataSource = mainCollectionViewDataSource + + mainCollectionViewDataSource = UICollectionViewDiffableDataSource(collectionView: rootView.mainCollectionView, cellProvider: { collectionView, indexPath, itemIdentifier in + switch itemIdentifier { + case let .collection(collection): + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ExploreCollectionViewCell.reuseIdentifier, for: indexPath) as? ExploreCollectionViewCell else { + return UICollectionViewCell() + } + cell.collectionImageView.kf.setImage(with: collection.imageUrl) + cell.collectionTitleLabel.attributedText = .pretendard(.display2_m_28, text: collection.title) + cell.collectionDescriptionLabel.attributedText = .pretendard(.body1_r_16, text: collection.description) + cell.collectionDetailButton.addAction(UIAction(handler: { [weak self] _ in + guard let id = Int64(collection.id) else { return } + guard let vc = self?.viewControllerFactory?.makeCollectionDetailViewController(collectionId: id) else { return } + self?.navigationController?.pushViewController(vc, animated: true) + }), for: .touchUpInside) + return cell + case .empty: + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ExploreEmptyCollectionViewCell.reuseIdentifier, for: indexPath) as? ExploreEmptyCollectionViewCell else { + return UICollectionViewCell() + } + return cell + } + }) + mainCollectionViewDataSource?.apply(makeSnapshot(exploreInfoEntities: exploreViewModel.collections.value), animatingDifferences: false) + } + + private func makeSnapshot(exploreInfoEntities: [ExploreInfoEntity]) -> NSDiffableDataSourceSnapshot { + var snapshot = NSDiffableDataSourceSnapshot() + snapshot.appendSections([.main, .empty]) + snapshot.appendItems(exploreInfoEntities.map({ MainCollectionViewItem.collection($0) }), toSection: .main) + snapshot.appendItems([MainCollectionViewItem.empty], toSection: .empty) + return snapshot + } +} + // MARK: - UICollectionViewDataSource extension ExploreViewController: UICollectionViewDataSource { diff --git a/FLINT/Presentation/Sources/ViewController/Scene/Home/CollectionFolder/CollectionFolderListViewController.swift b/FLINT/Presentation/Sources/ViewController/Scene/Home/CollectionFolder/CollectionFolderListViewController.swift index 5e81cbf3..fd1e8552 100644 --- a/FLINT/Presentation/Sources/ViewController/Scene/Home/CollectionFolder/CollectionFolderListViewController.swift +++ b/FLINT/Presentation/Sources/ViewController/Scene/Home/CollectionFolder/CollectionFolderListViewController.swift @@ -109,10 +109,10 @@ extension CollectionFolderListViewController: UICollectionViewDataSource { let entity = viewModel.items[indexPath.item] - let firstURL = URL(string: entity.imageList.first ?? entity.thumbnailUrl) + let firstURL = URL(string: entity.imageList.first ?? "") ?? entity.thumbnailUrl let secondString = entity.imageList.count > 1 ? entity.imageList[1] : nil let secondURL = secondString.flatMap(URL.init(string:)) - let profileURL = URL(string: entity.profileImageUrl) + let profileURL = entity.profileImageUrl cell.configure( .init( diff --git a/FLINT/Presentation/Sources/ViewController/Scene/Home/HomeViewController.swift b/FLINT/Presentation/Sources/ViewController/Scene/Home/HomeViewController.swift index 3bf556bd..50f2388a 100644 --- a/FLINT/Presentation/Sources/ViewController/Scene/Home/HomeViewController.swift +++ b/FLINT/Presentation/Sources/ViewController/Scene/Home/HomeViewController.swift @@ -26,8 +26,9 @@ public final class HomeViewController: BaseViewController { self.viewControllerFactory = viewControllerFactory } - @available(*, unavailable) - required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } // MARK: - Lifecycle diff --git a/FLINT/Presentation/Sources/ViewController/Scene/Login/LoginViewController.swift b/FLINT/Presentation/Sources/ViewController/Scene/Login/LoginViewController.swift index 849cf5b0..72bb41ff 100644 --- a/FLINT/Presentation/Sources/ViewController/Scene/Login/LoginViewController.swift +++ b/FLINT/Presentation/Sources/ViewController/Scene/Login/LoginViewController.swift @@ -41,7 +41,6 @@ public final class LoginViewController: BaseViewController { public override func bind() { loginViewModel.socialVerifyResultEntity.sink { [weak self] socialVerifyResultEntity in Log.d(socialVerifyResultEntity) - guard let socialVerifyResultEntity else { return } if !socialVerifyResultEntity.isRegistered { self?.register() } else { diff --git a/FLINT/Presentation/Sources/ViewController/Scene/Onboarding/FilmSelect/FilmSelectViewController.swift b/FLINT/Presentation/Sources/ViewController/Scene/Onboarding/FilmSelect/FilmSelectViewController.swift index 0b367595..578c8c10 100644 --- a/FLINT/Presentation/Sources/ViewController/Scene/Onboarding/FilmSelect/FilmSelectViewController.swift +++ b/FLINT/Presentation/Sources/ViewController/Scene/Onboarding/FilmSelect/FilmSelectViewController.swift @@ -64,13 +64,13 @@ public final class FilmSelectViewController: BaseViewController setNavigationBar(.init(left: .back, backgroundStyle: .solid(DesignSystem.Color.background))) hideKeyboardWhenTappedAround(activeOnAction: false) - onboardingViewModel.fetchContents() + onboardingViewModel.fetchPopularContents() rootView.searchTextField.searchAction = { [weak self] keyword in self?.onboardingViewModel.searchContents(keyword ?? "") } rootView.searchTextField.clearAction = { [weak self] in - self?.onboardingViewModel.fetchContents() + self?.onboardingViewModel.fetchPopularContents() } rootView.progressLabel.attributedText = .pretendard(.caption1_m_12, text: "\(onboardingViewModel.selectedContents.value.count)/\(onboardingViewModel.filmSelectQuestions.count)") diff --git a/FLINT/Presentation/Sources/ViewController/Scene/Profile/ProfileViewController.swift b/FLINT/Presentation/Sources/ViewController/Scene/Profile/ProfileViewController.swift index 0450f37d..971b81f8 100644 --- a/FLINT/Presentation/Sources/ViewController/Scene/Profile/ProfileViewController.swift +++ b/FLINT/Presentation/Sources/ViewController/Scene/Profile/ProfileViewController.swift @@ -17,13 +17,13 @@ import ViewModel public protocol ProfileViewControllerFactory { func makeProfileViewController() -> ProfileViewController - func makeProfileViewController(target: ProfileViewModel.Target) -> ProfileViewController + func makeProfileViewController(target: UserTarget) -> ProfileViewController } public final class ProfileViewController: BaseViewController { - private let profileViewModel: ProfileViewModel + public init( profileViewModel: ProfileViewModel, viewControllerFactory: ViewControllerFactory, @@ -32,10 +32,12 @@ public final class ProfileViewController: BaseViewController { super.init(nibName: nil, bundle: nil) self.viewControllerFactory = viewControllerFactory } - - @available(*, unavailable) - required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + required init?(coder: NSCoder) { + fatalError( + "init(coder:) has not been implemented" + ) + } public override func viewDidLoad() { super.viewDidLoad() @@ -160,7 +162,7 @@ extension ProfileViewController: UITableViewDataSource { for: indexPath ) as! PreferenceRankedChipTableViewCell cell.selectionStyle = .none - cell.configure(entities: keywords) + cell.configure(keywords: keywords) return cell case let .titleHeader(style, title, subtitle): diff --git a/FLINT/Presentation/Sources/ViewController/Scene/Splash/SplashViewController.swift b/FLINT/Presentation/Sources/ViewController/Scene/Splash/SplashViewController.swift index c3b974b3..d47f6743 100644 --- a/FLINT/Presentation/Sources/ViewController/Scene/Splash/SplashViewController.swift +++ b/FLINT/Presentation/Sources/ViewController/Scene/Splash/SplashViewController.swift @@ -5,9 +5,8 @@ // Created by 진소은 on 1/22/26. // - -import UIKit import Combine +import UIKit import View import ViewModel diff --git a/FLINT/Presentation/Sources/ViewModel/Extension/Publisher+.swift b/FLINT/Presentation/Sources/ViewModel/Extension/Publisher+Thread.swift similarity index 92% rename from FLINT/Presentation/Sources/ViewModel/Extension/Publisher+.swift rename to FLINT/Presentation/Sources/ViewModel/Extension/Publisher+Thread.swift index e61c0d85..babfed39 100644 --- a/FLINT/Presentation/Sources/ViewModel/Extension/Publisher+.swift +++ b/FLINT/Presentation/Sources/ViewModel/Extension/Publisher+Thread.swift @@ -1,5 +1,5 @@ // -// File.swift +// Publisher+Thread.swift // Presentation // // Created by 김호성 on 2026.01.20. diff --git a/FLINT/Presentation/Sources/ViewModel/Scene/CollectionDetail/CollectionDetailViewModel.swift b/FLINT/Presentation/Sources/ViewModel/Scene/CollectionDetail/CollectionDetailViewModel.swift index 684f5d20..73d10feb 100644 --- a/FLINT/Presentation/Sources/ViewModel/Scene/CollectionDetail/CollectionDetailViewModel.swift +++ b/FLINT/Presentation/Sources/ViewModel/Scene/CollectionDetail/CollectionDetailViewModel.swift @@ -9,7 +9,6 @@ import Combine import Foundation import Domain -import Entity public final class CollectionDetailViewModel { @@ -51,8 +50,8 @@ public final class CollectionDetailViewModel { // MARK: - Dependency private let collectionId: Int64 - private let collectionDetailUseCase: CollectionDetailUseCase - private let fetchBookmarkedUserUseCase: FetchBookmarkedUserUseCase + private let fetchCollectionDetailUseCase: FetchCollectionDetailUseCase + private let fetchCollectionBookmarkUsersUseCase: FetchCollectionBookmarkUsersUseCase // MARK: - Private @@ -63,12 +62,12 @@ public final class CollectionDetailViewModel { public init( collectionId: Int64, - collectionDetailUseCase: CollectionDetailUseCase, - fetchBookmarkedUserUseCase: FetchBookmarkedUserUseCase + fetchCollectionDetailUseCase: FetchCollectionDetailUseCase, + fetchCollectionBookmarkUsersUseCase: FetchCollectionBookmarkUsersUseCase ) { self.collectionId = collectionId - self.collectionDetailUseCase = collectionDetailUseCase - self.fetchBookmarkedUserUseCase = fetchBookmarkedUserUseCase + self.fetchCollectionDetailUseCase = fetchCollectionDetailUseCase + self.fetchCollectionBookmarkUsersUseCase = fetchCollectionBookmarkUsersUseCase } // MARK: - Transform @@ -96,7 +95,7 @@ public final class CollectionDetailViewModel { private func fetch() { stateSubject.send(.loading) - collectionDetailUseCase.fetchCollectionDetail(collectionId: collectionId) + fetchCollectionDetailUseCase.fetchCollectionDetail(collectionId: collectionId) .sink( receiveCompletion: { [weak self] completion in guard let self else { return } @@ -109,7 +108,7 @@ public final class CollectionDetailViewModel { self.stateSubject.send(.loaded(detail: detail, bookmarkedUsers: nil)) - self.fetchBookmarkedUserUseCase.execute(collectionId: self.collectionId) + self.fetchCollectionBookmarkUsersUseCase.fetchCollectionBookmarkUsers(collectionId: self.collectionId) .sink( receiveCompletion: { _ in }, receiveValue: { [weak self] users in diff --git a/FLINT/Presentation/Sources/ViewModel/Scene/CreateCollection/AddContentSelectViewModel.swift b/FLINT/Presentation/Sources/ViewModel/Scene/CreateCollection/AddContentSelectViewModel.swift index 1b18d5c4..42ad43c9 100644 --- a/FLINT/Presentation/Sources/ViewModel/Scene/CreateCollection/AddContentSelectViewModel.swift +++ b/FLINT/Presentation/Sources/ViewModel/Scene/CreateCollection/AddContentSelectViewModel.swift @@ -26,7 +26,7 @@ public final class DefaultAddContentSelectViewModel: AddContentSelectViewModel { // MARK: - Dependency - private let contentsUseCase: ContentsUseCase + private let fetchPopularContentsUseCase: FetchPopularContentsUseCase private let searchContentsUseCase: SearchContentsUseCase // MARK: - Output @@ -42,10 +42,10 @@ public final class DefaultAddContentSelectViewModel: AddContentSelectViewModel { // MARK: - Init public init( - contentsUseCase: ContentsUseCase, + fetchPopularContentsUseCase: FetchPopularContentsUseCase, searchContentsUseCase: SearchContentsUseCase ) { - self.contentsUseCase = contentsUseCase + self.fetchPopularContentsUseCase = fetchPopularContentsUseCase self.searchContentsUseCase = searchContentsUseCase bind() } @@ -59,7 +59,7 @@ public final class DefaultAddContentSelectViewModel: AddContentSelectViewModel { public func fetchContents() { isSearching.send(false) - contentsUseCase.fetchContents() + fetchPopularContentsUseCase.fetchPopularContents() .manageThread() .sinkHandledCompletion { [weak self] contents in self?.results.send(contents) @@ -89,7 +89,7 @@ public extension DefaultAddContentSelectViewModel { isSearching.send(true) - searchContentsUseCase.searchContents(keyword) + searchContentsUseCase.searchContents(keyword: keyword) .manageThread() .sinkHandledCompletion { [weak self] contents in self?.results.send(contents) diff --git a/FLINT/Presentation/Sources/ViewModel/Scene/CreateCollection/CreateCollectionView/CreateCollectionViewModel.swift b/FLINT/Presentation/Sources/ViewModel/Scene/CreateCollection/CreateCollectionView/CreateCollectionViewModel.swift index cb2b2900..a7475e40 100644 --- a/FLINT/Presentation/Sources/ViewModel/Scene/CreateCollection/CreateCollectionView/CreateCollectionViewModel.swift +++ b/FLINT/Presentation/Sources/ViewModel/Scene/CreateCollection/CreateCollectionView/CreateCollectionViewModel.swift @@ -73,9 +73,9 @@ public final class DefaultCreateCollectionViewModel: CreateCollectionViewModel { guard isDoneEnabled.value else { return } guard let entity = createEntity else { return } - createCollectionUseCase.createCollection(entity) + createCollectionUseCase.createCollection(collectionInfo: entity) .manageThread() - .map { Result.success(()) } + .map { _ in Result.success(()) } .catch { Just(Result.failure($0)) } .sinkHandledCompletion { [weak self] result in switch result { diff --git a/FLINT/Presentation/Sources/ViewModel/Scene/Explore/ExploreViewModel.swift b/FLINT/Presentation/Sources/ViewModel/Scene/Explore/ExploreViewModel.swift index 1914ae00..6b2f6a46 100644 --- a/FLINT/Presentation/Sources/ViewModel/Scene/Explore/ExploreViewModel.swift +++ b/FLINT/Presentation/Sources/ViewModel/Scene/Explore/ExploreViewModel.swift @@ -1,5 +1,5 @@ // -// File.swift +// ExploreViewModel.swift // Presentation // // Created by 김호성 on 2026.01.22. @@ -17,23 +17,23 @@ public protocol ExploreViewModelInput { public protocol ExploreViewModelOutput { var index: CurrentValueSubject { get } var collections: CurrentValueSubject<[ExploreInfoEntity], Never> { get } - var cursor: UInt? { get set } + var cursor: Int64? { get set } } public typealias ExploreViewModel = ExploreViewModelInput & ExploreViewModelOutput public final class DefaultExploreViewModel: ExploreViewModel { - private let exploreUseCase: ExploreUseCase + private let fetchExploreCollectionsUseCase: FetchExploreCollectionsUseCase public var index: CurrentValueSubject = .init(0) public var collections: CurrentValueSubject<[ExploreInfoEntity], Never> = .init([]) - public var cursor: UInt? + public var cursor: Int64? private var cancellables: Set = Set() - public init(exploreUseCase: ExploreUseCase) { - self.exploreUseCase = exploreUseCase + public init(fetchExploreCollectionsUseCase: FetchExploreCollectionsUseCase) { + self.fetchExploreCollectionsUseCase = fetchExploreCollectionsUseCase bind() fetchCollections() } @@ -53,7 +53,7 @@ public final class DefaultExploreViewModel: ExploreViewModel { } private func fetchCollections() { - exploreUseCase.fetchExplore(cursor: cursor) + fetchExploreCollectionsUseCase.fetchExploreCollections(cursor: cursor) .manageThread() .sinkHandledCompletion { [weak self] collectionPagingEntity in guard let self else { return } diff --git a/FLINT/Presentation/Sources/ViewModel/Scene/Home/CollectionFolderListViewModel.swift b/FLINT/Presentation/Sources/ViewModel/Scene/Home/CollectionFolderListViewModel.swift index e743612c..187931af 100644 --- a/FLINT/Presentation/Sources/ViewModel/Scene/Home/CollectionFolderListViewModel.swift +++ b/FLINT/Presentation/Sources/ViewModel/Scene/Home/CollectionFolderListViewModel.swift @@ -17,15 +17,15 @@ public final class CollectionFolderListViewModel { @Published public private(set) var items: [CollectionEntity] = [] // MARK: - Dependency - private let fetchWatchingCollectionsUseCase: FetchWatchingCollectionsUseCase + private let fetchRecentViewedCollectionsUseCase: FetchRecentViewedCollectionsUseCase private var cancellables = Set() - public init(fetchWatchingCollectionsUseCase: FetchWatchingCollectionsUseCase) { - self.fetchWatchingCollectionsUseCase = fetchWatchingCollectionsUseCase + public init(fetchRecentViewedCollectionsUseCase: FetchRecentViewedCollectionsUseCase) { + self.fetchRecentViewedCollectionsUseCase = fetchRecentViewedCollectionsUseCase } public func load() { - fetchWatchingCollectionsUseCase.fetchWatchingCollections() + fetchRecentViewedCollectionsUseCase.fetchWatchingCollections() .receive(on: DispatchQueue.main) .sink { completion in if case let .failure(error) = completion { diff --git a/FLINT/Presentation/Sources/ViewModel/Scene/Home/HomeViewModel.swift b/FLINT/Presentation/Sources/ViewModel/Scene/Home/HomeViewModel.swift index 8030ac35..8b7b59d2 100644 --- a/FLINT/Presentation/Sources/ViewModel/Scene/Home/HomeViewModel.swift +++ b/FLINT/Presentation/Sources/ViewModel/Scene/Home/HomeViewModel.swift @@ -5,21 +5,12 @@ // Created by 소은 on 2026.01.23. // -// -// HomeViewModel.swift -// Presentation -// -// Created by 소은 on 2026.01.23. -// - -import Foundation import Combine +import Foundation import Domain -import Entity public final class HomeViewModel { - // MARK: - Section / Row @@ -35,7 +26,7 @@ public final class HomeViewModel { public enum Row { case greeting(userName: String) case header(style: TitleHeaderStyle, title: String, subtitle: String) - case fliner(items: [CollectionEntity]) + case fliner(items: [CollectionInfoEntity]) case recentSavedContents(items: [ContentInfoEntity]) case ctaButton(title: String) } @@ -46,29 +37,32 @@ public final class HomeViewModel { // MARK: - Dependencies - private let homeUseCase: HomeUseCase - private let userProfileUseCase: UserProfileUseCase - private let fetchWatchingCollectionsUseCase: FetchWatchingCollectionsUseCase + private let fetchRecommendedCollectionsUseCase: FetchRecommendedCollectionsUseCase + private let fetchBookmarkedContentsUseCase: FetchBookmarkedContentsUseCase + private let fetchProfileUseCase: FetchProfileUseCase + private let fetchRecentViewedCollectionsUseCase: FetchRecentViewedCollectionsUseCase private var cancellables = Set() // MARK: - State private var userName: String - private var flinerCollections: [CollectionEntity] = [] + private var flinerCollections: [CollectionInfoEntity] = [] private var recentSavedContents: [ContentInfoEntity] = [] private var watchingCollections: [CollectionEntity] = [] // MARK: - Init public init( - homeUseCase: HomeUseCase, - userProfileUseCase: UserProfileUseCase, - fetchWatchingCollectionsUseCase: FetchWatchingCollectionsUseCase, + fetchRecommendedCollectionsUseCase: FetchRecommendedCollectionsUseCase, + fetchBookmarkedContentsUseCase: FetchBookmarkedContentsUseCase, + fetchProfileUseCase: FetchProfileUseCase, + fetchRecentViewedCollectionsUseCase: FetchRecentViewedCollectionsUseCase, initialUserName: String = "얀비" ) { - self.homeUseCase = homeUseCase - self.userProfileUseCase = userProfileUseCase - self.fetchWatchingCollectionsUseCase = fetchWatchingCollectionsUseCase + self.fetchRecommendedCollectionsUseCase = fetchRecommendedCollectionsUseCase + self.fetchBookmarkedContentsUseCase = fetchBookmarkedContentsUseCase + self.fetchProfileUseCase = fetchProfileUseCase + self.fetchRecentViewedCollectionsUseCase = fetchRecentViewedCollectionsUseCase self.userName = initialUserName self.sections = makeSections() } @@ -77,8 +71,8 @@ public final class HomeViewModel { public func load() { - userProfileUseCase.fetchUserProfile(userId: 1) - .receive(on: DispatchQueue.main) + fetchProfileUseCase.fetchProfile(for: .user(id: 1)) + .manageThread() .sink { completion in if case let .failure(error) = completion { print(" fetchUserProfile failed:", error) @@ -91,8 +85,8 @@ public final class HomeViewModel { .store(in: &cancellables) // 1) Fliner 추천 - homeUseCase.fetchRecommendedCollections() - .receive(on: DispatchQueue.main) + fetchRecommendedCollectionsUseCase.fetchRecommendedCollections() + .manageThread() .sink { completion in if case let .failure(error) = completion { print("fetchRecommendedCollections failed:", error) @@ -100,29 +94,15 @@ public final class HomeViewModel { } receiveValue: { [weak self] items in guard let self else { return } - self.flinerCollections = items.map { info in - CollectionEntity( - id: info.id ?? "", - thumbnailUrl: info.imageUrlString, - title: info.title, - description: "", - imageList: [], - bookmarkCount: 0, - isBookmarked: false, - userId: "", - nickname: info.userName, - profileImageUrl: info.profileImageUrlString - ) - - } + self.flinerCollections = items self.sections = self.makeSections() } .store(in: &cancellables) // 2) 최근 저장한 콘텐츠 - userProfileUseCase.fetchMyBookmarkedContents() - .receive(on: DispatchQueue.main) + fetchBookmarkedContentsUseCase.fetchBookmarkedContents(for: .me) + .manageThread() .sink { completion in if case let .failure(error) = completion { print("fetchMyBookmarkedContents failed:", error) @@ -134,8 +114,8 @@ public final class HomeViewModel { } .store(in: &cancellables) - fetchWatchingCollectionsUseCase.fetchWatchingCollections() - .receive(on: DispatchQueue.main) + fetchRecentViewedCollectionsUseCase.fetchWatchingCollections() + .manageThread() .sink { completion in if case let .failure(error) = completion { print("fetchWatchingCollections failed:", error) @@ -146,8 +126,6 @@ public final class HomeViewModel { self.sections = self.makeSections() } .store(in: &cancellables) - - } // MARK: - Builder @@ -210,7 +188,9 @@ public final class HomeViewModel { title: "눈여겨보고 있는 컬렉션", subtitle: "\(userName)님이 최근 살펴본 컬렉션이에요" ), - .fliner(items: watchingCollections) + .fliner(items: watchingCollections.map({ collectionEntity in + return CollectionInfoEntity(id: collectionEntity.id, imageUrl: collectionEntity.thumbnailUrl, profileImageUrl: collectionEntity.profileImageUrl, title: collectionEntity.title, userName: collectionEntity.nickname) + })) ] } diff --git a/FLINT/Presentation/Sources/ViewModel/Scene/Login/LoginViewModel.swift b/FLINT/Presentation/Sources/ViewModel/Scene/Login/LoginViewModel.swift index a79baee5..25a047e7 100644 --- a/FLINT/Presentation/Sources/ViewModel/Scene/Login/LoginViewModel.swift +++ b/FLINT/Presentation/Sources/ViewModel/Scene/Login/LoginViewModel.swift @@ -18,7 +18,7 @@ public protocol LoginViewModelInput { } public protocol LoginViewModelOutput { - var socialVerifyResultEntity: CurrentValueSubject { get set } + var socialVerifyResultEntity: PassthroughSubject { get } } public typealias LoginViewModel = LoginViewModelInput & LoginViewModelOutput @@ -27,7 +27,7 @@ public final class DefaultLoginViewModel: LoginViewModel { private let socialVerifyUseCase: SocialVerifyUseCase - public var socialVerifyResultEntity: CurrentValueSubject = .init(nil) + public var socialVerifyResultEntity: PassthroughSubject = .init() private var cancellables: Set = Set() @@ -47,7 +47,7 @@ public final class DefaultLoginViewModel: LoginViewModel { } if let accessToken = oauthToken?.accessToken { socialVerifyUseCase.socialVerify( - socialVerifyEntity: SocialVerifyEntity( + socialAuthCredential: SocialVerifyEntity( provider: .kakao, accessToken: accessToken ) diff --git a/FLINT/Presentation/Sources/ViewModel/Scene/Onboarding/OnboardingViewModel.swift b/FLINT/Presentation/Sources/ViewModel/Scene/Onboarding/OnboardingViewModel.swift index 9c01d294..983d3ca9 100644 --- a/FLINT/Presentation/Sources/ViewModel/Scene/Onboarding/OnboardingViewModel.swift +++ b/FLINT/Presentation/Sources/ViewModel/Scene/Onboarding/OnboardingViewModel.swift @@ -1,5 +1,5 @@ // -// File.swift +// OnboardingViewModel.swift // Presentation // // Created by 김호성 on 2026.01.20. @@ -15,10 +15,10 @@ public protocol OnboardingViewModelInput { func checkNickname(_ nickname: String) // film select - func fetchContents() + func fetchPopularContents() func searchContents(_ keyword: String) func clickContent(_ content: ContentEntity) - func deleteContent(_ content: ContentEntity) + func deleteContent(_ content: ContentEntity) // ott select func clickOtt(_ ott: Ott) @@ -46,8 +46,8 @@ public typealias OnboardingViewModel = OnboardingViewModelInput & OnboardingView public final class DefaultOnboardingViewModel: OnboardingViewModel { - private let nicknameUseCase: NicknameUseCase - private let contentsUseCase: ContentsUseCase + private let checkNicknameUseCase: CheckNicknameUseCase + private let fetchPopularContentsUseCase: FetchPopularContentsUseCase private let searchContentsUseCase: SearchContentsUseCase private let signupUseCase: SignupUseCase @@ -72,13 +72,13 @@ public final class DefaultOnboardingViewModel: OnboardingViewModel { private var cancellables: Set = Set() public init( - nicknameUseCase: NicknameUseCase, - contentsUseCase: ContentsUseCase, + checkNicknameUseCase: CheckNicknameUseCase, + fetchPopularContentsUseCase: FetchPopularContentsUseCase, searchContentsUseCase: SearchContentsUseCase, - signupUseCase: SignupUseCase + signupUseCase: SignupUseCase, ) { - self.nicknameUseCase = nicknameUseCase - self.contentsUseCase = contentsUseCase + self.checkNicknameUseCase = checkNicknameUseCase + self.fetchPopularContentsUseCase = fetchPopularContentsUseCase self.searchContentsUseCase = searchContentsUseCase self.signupUseCase = signupUseCase } @@ -88,7 +88,7 @@ public final class DefaultOnboardingViewModel: OnboardingViewModel { nicknameValidState.send(.invalid) return } - nicknameUseCase.checkNickname(nickname) + checkNicknameUseCase.checkNickname(nickname) .manageThread() .sinkHandledCompletion(receiveValue: { [weak self] isValidNickname in self?.nicknameValidState.send(isValidNickname ? .valid : .duplicate) @@ -99,8 +99,8 @@ public final class DefaultOnboardingViewModel: OnboardingViewModel { .store(in: &cancellables) } - public func fetchContents() { - contentsUseCase.fetchContents() + public func fetchPopularContents() { + fetchPopularContentsUseCase.fetchPopularContents() .manageThread() .sinkHandledCompletion { [weak self] contents in self?.contents.send(contents) @@ -109,7 +109,7 @@ public final class DefaultOnboardingViewModel: OnboardingViewModel { } public func searchContents(_ keyword: String) { - searchContentsUseCase.searchContents(keyword) + searchContentsUseCase.searchContents(keyword: keyword) .manageThread() .sinkHandledCompletion { [weak self] contents in self?.contents.send(contents) @@ -141,7 +141,7 @@ public final class DefaultOnboardingViewModel: OnboardingViewModel { public func signup() { signupUseCase.signup( - SignupInfoEntity( + userInfo: SignupInfoEntity( nickname: nickname.value, favoriteContentIds: selectedContents.value.compactMap({ content in Int(content.id) diff --git a/FLINT/Presentation/Sources/ViewModel/Scene/Profile/ProfileViewModel.swift b/FLINT/Presentation/Sources/ViewModel/Scene/Profile/ProfileViewModel.swift index d5abb388..981ea57e 100644 --- a/FLINT/Presentation/Sources/ViewModel/Scene/Profile/ProfileViewModel.swift +++ b/FLINT/Presentation/Sources/ViewModel/Scene/Profile/ProfileViewModel.swift @@ -5,27 +5,34 @@ // Created by 진소은 on 1/22/26. // -import Foundation import Combine +import Foundation import Domain -import Entity +//public protocol ProfileViewModelInput { +// +//} + +//public protocol ProfileViewModelOutput { +// var userProfileEntity: CurrentValueSubject { get set } +//} + +//public typealias ProfileViewModel = ProfileViewModelInput & ProfileViewModelOutput + +//public final class DefaultProfileViewModel: ProfileViewModel { public final class ProfileViewModel { +// public var userProfileEntity: CurrentValueSubject - public enum Target: Equatable { - case me - case user(userId: String) - } - private let target: Target + private let target: UserTarget public enum Row { - case profileHeader(nickname: String, profileImageUrl: String, isFliner: Bool) + case profileHeader(nickname: String, profileImageUrl: URL?, isFliner: Bool) case titleHeader(style: TitleHeaderStyle, title: String, subtitle: String) case preferenceChips(keywords: [KeywordEntity]) - case myCollections(items: [CollectionEntity]) - case savedCollections(items: [CollectionEntity]) + case myCollections(items: [CollectionInfoEntity]) + case savedCollections(items: [CollectionInfoEntity]) case savedContents(items: [ContentInfoEntity]) } @@ -38,183 +45,116 @@ public final class ProfileViewModel { @Published public private(set) var rows: [Row] = [] // MARK: - Dependencies - private let userProfileUseCase: UserProfileUseCase + private let fetchProfileUseCase: FetchProfileUseCase + private let fetchKeywordsUseCase: FetchKeywordsUseCase + private let fetchCreatedCollectionsUseCase: FetchCreatedCollectionsUseCase + private let fetchBookmarkedCollectionsUseCase: FetchBookmarkedCollectionsUseCase + private let fetchBookmarkedContentsUseCase: FetchBookmarkedContentsUseCase private var cancellables = Set() // MARK: - State private var nickname: String private var isFliner: Bool - private var profileImageUrl: String? + private var profileImageUrl: URL? private var keywords: [KeywordEntity] = [] - private var myCollections: [CollectionEntity] = [] - private var savedCollections: [CollectionEntity] = [] + private var myCollections: [CollectionInfoEntity] = [] + private var savedCollections: [CollectionInfoEntity] = [] private var savedContents: [ContentInfoEntity] = [] public init( - target: Target = .me, - userProfileUseCase: UserProfileUseCase, + target: UserTarget, + fetchProfileUseCase: FetchProfileUseCase, + fetchKeywordsUseCase: FetchKeywordsUseCase, + fetchCreatedCollectionsUseCase: FetchCreatedCollectionsUseCase, + fetchBookmarkedCollectionsUseCase: FetchBookmarkedCollectionsUseCase, + fetchBookmarkedContentsUseCase: FetchBookmarkedContentsUseCase, initialNickname: String = "플링", initialIsFliner: Bool = true ) { self.target = target - self.userProfileUseCase = userProfileUseCase + self.fetchProfileUseCase = fetchProfileUseCase + self.fetchKeywordsUseCase = fetchKeywordsUseCase + self.fetchCreatedCollectionsUseCase = fetchCreatedCollectionsUseCase + self.fetchBookmarkedCollectionsUseCase = fetchBookmarkedCollectionsUseCase + self.fetchBookmarkedContentsUseCase = fetchBookmarkedContentsUseCase self.nickname = initialNickname self.isFliner = initialIsFliner - self.profileImageUrl = "" self.rows = makeRows() } // MARK: - Input public func load() { - switch target { - case .me: - userProfileUseCase.fetchMyProfile() - .receive(on: DispatchQueue.main) - .sink { completion in - if case let .failure(error) = completion { - print("❌ fetchProfile failed:", error) - } - } receiveValue: { [weak self] profile in - guard let self else { return } - self.nickname = profile.nickname - self.isFliner = profile.isFliner - self.profileImageUrl = profile.profileImageUrl - self.rows = self.makeRows() - } - .store(in: &cancellables) - userProfileUseCase.fetchMyKeywords() - .receive(on: DispatchQueue.main) - .sink { completion in - if case let .failure(error) = completion { - print("❌ fetchKeywords failed:", error) - } - } receiveValue: { [weak self] keywords in - guard let self else { return } - self.keywords = keywords - self.rows = self.makeRows() - } - .store(in: &cancellables) - - userProfileUseCase.fetchMyCollections() - .receive(on: DispatchQueue.main) - .sink { completion in - if case let .failure(error) = completion { - print("❌ fetchMyCollections failed:", error) - } - } receiveValue: { [weak self] items in - guard let self else { return } - self.myCollections = items - self.rows = self.makeRows() - } - .store(in: &cancellables) - - userProfileUseCase.fetchMyBookmarkedCollections() - .receive(on: DispatchQueue.main) - .sink { completion in - if case let .failure(error) = completion { - print("❌ fetchSavedCollections failed:", error) - } - } receiveValue: { [weak self] items in - print("asdf", items.count) - guard let self else { return } - self.savedCollections = items - self.rows = self.makeRows() - } - .store(in: &cancellables) - - userProfileUseCase.fetchMyBookmarkedContents() - .receive(on: DispatchQueue.main) - .sink { completion in - if case let .failure(error) = completion { - print("❌ fetchSavedContents failed:", error) - } - } receiveValue: { [weak self] items in - guard let self else { return } - self.savedContents = items - self.rows = self.makeRows() + fetchProfileUseCase.fetchProfile(for: target) + .manageThread() + .sinkHandledCompletion(receiveValue: { [weak self] userProfileEntity in + guard let self else { return } + nickname = userProfileEntity.nickname + isFliner = userProfileEntity.role == .fliner + profileImageUrl = userProfileEntity.profileImageUrl + rows = makeRows() + }) + .store(in: &cancellables) + + fetchKeywordsUseCase.fetchKeywords(for: target) + .manageThread() + .sink { completion in + if case let .failure(error) = completion { + print("❌ fetchKeywords failed:", error) } - .store(in: &cancellables) - - - - case .user(let userIdString): - guard let userId = Int64(userIdString) else { - print("❌ invalid userId:", userIdString) - return + } receiveValue: { [weak self] keywords in + guard let self else { return } + self.keywords = keywords + self.rows = self.makeRows() } - userProfileUseCase.fetchUserProfile(userId: userId) - .receive(on: DispatchQueue.main) - .sink { completion in - if case let .failure(error) = completion { - print("❌ fetchProfile failed:", error) - } - } receiveValue: { [weak self] profile in - guard let self else { return } - self.nickname = profile.nickname - self.isFliner = profile.isFliner - self.profileImageUrl = profile.profileImageUrl - self.rows = self.makeRows() - } - .store(in: &cancellables) - userProfileUseCase.fetchUserKeywords(userId: Int64(userId)) - .receive(on: DispatchQueue.main) - .sink { completion in - if case let .failure(error) = completion { - print("❌ fetchKeywords failed:", error) - } - } receiveValue: { [weak self] keywords in - guard let self else { return } - self.keywords = keywords - self.rows = self.makeRows() - } - .store(in: &cancellables) - - userProfileUseCase.fetchUserCollections(userId: userId) - .receive(on: DispatchQueue.main) - .sink { completion in - if case let .failure(error) = completion { - print("❌ fetchMyCollections failed:", error) - } - } receiveValue: { [weak self] items in - guard let self else { return } - self.myCollections = items - self.rows = self.makeRows() + .store(in: &cancellables) + + fetchCreatedCollectionsUseCase.fetchCreatedCollections(for: target) + .manageThread() + .sink { completion in + if case let .failure(error) = completion { + print("❌ fetchMyCollections failed:", error) } - .store(in: &cancellables) - - userProfileUseCase.fetchBookmarkedCollections(userId: userId) - .receive(on: DispatchQueue.main) - .sink { completion in - if case let .failure(error) = completion { - print("❌ fetchSavedCollections failed:", error) - } - } receiveValue: { [weak self] items in - print("asdf", items.count) - guard let self else { return } - self.savedCollections = items - self.rows = self.makeRows() + } receiveValue: { [weak self] items in + guard let self else { return } + self.myCollections = items.map({ collectionEntity in + return CollectionInfoEntity(id: collectionEntity.id, imageUrl: collectionEntity.thumbnailUrl, profileImageUrl: collectionEntity.profileImageUrl, title: collectionEntity.title, userName: collectionEntity.nickname) + }) + self.rows = self.makeRows() + } + .store(in: &cancellables) + + fetchBookmarkedCollectionsUseCase.fetchBookmarkedCollections(for: target) + .manageThread() + .sink { completion in + if case let .failure(error) = completion { + print("❌ fetchSavedCollections failed:", error) } - .store(in: &cancellables) - - userProfileUseCase.fetchBookmarkedContents(userId: userId) - .receive(on: DispatchQueue.main) - .sink { completion in - if case let .failure(error) = completion { - print("❌ fetchSavedContents failed:", error) - } - } receiveValue: { [weak self] items in - guard let self else { return } - self.savedContents = items - self.rows = self.makeRows() + } receiveValue: { [weak self] items in + print("asdf", items.count) + guard let self else { return } + self.savedCollections = items.map({ collectionEntity in + return CollectionInfoEntity(id: collectionEntity.id, imageUrl: collectionEntity.thumbnailUrl, profileImageUrl: collectionEntity.profileImageUrl, title: collectionEntity.title, userName: collectionEntity.nickname) + }) + self.rows = self.makeRows() + } + .store(in: &cancellables) + + fetchBookmarkedContentsUseCase.fetchBookmarkedContents(for: target) + .manageThread() + .sink { completion in + if case let .failure(error) = completion { + print("❌ fetchSavedContents failed:", error) } - .store(in: &cancellables) - } + } receiveValue: { [weak self] items in + guard let self else { return } + self.savedContents = items + self.rows = self.makeRows() + } + .store(in: &cancellables) } - // - // MARK: - Row builder private func makeRows() -> [Row] { var result: [Row] = [] @@ -223,7 +163,7 @@ public final class ProfileViewModel { result.append( .profileHeader( nickname: nickname, - profileImageUrl: profileImageUrl ?? "", + profileImageUrl: profileImageUrl, isFliner: isFliner ) ) diff --git a/FLINT/Presentation/Sources/ViewModel/Scene/Splash/SplashViewModel.swift b/FLINT/Presentation/Sources/ViewModel/Scene/Splash/SplashViewModel.swift deleted file mode 100644 index 3492ccd7..00000000 --- a/FLINT/Presentation/Sources/ViewModel/Scene/Splash/SplashViewModel.swift +++ /dev/null @@ -1,50 +0,0 @@ -// -// SplashViewModel.swift -// Presentation -// -// Created by 진소은 on 1/22/26. -// - - -import Combine - -public final class SplashViewModel: BaseViewModelType { - - public struct Input { - public let viewDidAppear: AnyPublisher - public let lottieFinished: AnyPublisher - - public init( - viewDidAppear: AnyPublisher, - lottieFinished: AnyPublisher - ) { - self.viewDidAppear = viewDidAppear - self.lottieFinished = lottieFinished - } - } - - public struct Output { - /// SplashViewController가 이 이벤트 받으면 rootView.play() 호출 - public let playLottie: AnyPublisher - - /// SplashViewController / Coordinator가 이 이벤트 받으면 Login으로 전환 - public let routeToLogin: AnyPublisher - } - - public init() {} - - public func transform(input: Input) -> Output { - let playLottie = input.viewDidAppear - .prefix(1) - .eraseToAnyPublisher() - - let routeToLogin = input.lottieFinished - .prefix(1) - .eraseToAnyPublisher() - - return Output( - playLottie: playLottie, - routeToLogin: routeToLogin - ) - } -}