From f57c9821121c350ac6bde0b2142fab89bbc3ae25 Mon Sep 17 00:00:00 2001 From: Hyowon Jeon Date: Sun, 23 Mar 2025 00:44:52 +0900 Subject: [PATCH 1/7] =?UTF-8?q?[Refactor]=20#510=20-=20SearchKeyword=20DTO?= =?UTF-8?q?/Entity=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Network/Keyword/KeywordService.swift | 6 +++--- ...esult.swift => SearchKeywordResponse.swift} | 4 ++-- .../Data/Entity/SearchKeywordEntity.swift | 18 ++++++++++++++++++ .../Data/Repository/KeywordRepository.swift | 5 +++-- .../NovelKeywordSelectModalViewModel.swift | 2 +- .../DetailSearchViewModel.swift | 2 +- 6 files changed, 28 insertions(+), 9 deletions(-) rename WSSiOS/WSSiOS/Source/Data/DTO/{SearchKeywordResult.swift => SearchKeywordResponse.swift} (81%) create mode 100644 WSSiOS/WSSiOS/Source/Data/Entity/SearchKeywordEntity.swift diff --git a/WSSiOS/WSSiOS/Network/Keyword/KeywordService.swift b/WSSiOS/WSSiOS/Network/Keyword/KeywordService.swift index 15fffd35a..d9c926e64 100644 --- a/WSSiOS/WSSiOS/Network/Keyword/KeywordService.swift +++ b/WSSiOS/WSSiOS/Network/Keyword/KeywordService.swift @@ -10,11 +10,11 @@ import Foundation import RxSwift protocol KeywordService { - func searchKeyword(query: String?) -> Single + func searchKeyword(query: String?) -> Single } final class DefaultKeywordService: NSObject, Networking, KeywordService { - func searchKeyword(query: String? = nil) -> RxSwift.Single { + func searchKeyword(query: String? = nil) -> RxSwift.Single { var searchKeywordQueryItems: [URLQueryItem] = [] if let query { @@ -32,7 +32,7 @@ final class DefaultKeywordService: NSObject, Networking, KeywordService { return tokenCheckURLSession.rx.data(request: request) .map { try self.decode(data: $0, - to: SearchKeywordResult.self) } + to: SearchKeywordResponse.self) } .asSingle() } catch { diff --git a/WSSiOS/WSSiOS/Source/Data/DTO/SearchKeywordResult.swift b/WSSiOS/WSSiOS/Source/Data/DTO/SearchKeywordResponse.swift similarity index 81% rename from WSSiOS/WSSiOS/Source/Data/DTO/SearchKeywordResult.swift rename to WSSiOS/WSSiOS/Source/Data/DTO/SearchKeywordResponse.swift index 7bbafbead..6c7f3c43c 100644 --- a/WSSiOS/WSSiOS/Source/Data/DTO/SearchKeywordResult.swift +++ b/WSSiOS/WSSiOS/Source/Data/DTO/SearchKeywordResponse.swift @@ -1,5 +1,5 @@ // -// SearchKeywordResult.swift +// SearchKeywordResponse.swift // WSSiOS // // Created by Hyowon Jeon on 9/27/24. @@ -7,7 +7,7 @@ import Foundation -struct SearchKeywordResult: Codable { +struct SearchKeywordResponse: Decodable { let categories: [KeywordCategory] } diff --git a/WSSiOS/WSSiOS/Source/Data/Entity/SearchKeywordEntity.swift b/WSSiOS/WSSiOS/Source/Data/Entity/SearchKeywordEntity.swift new file mode 100644 index 000000000..f733ca264 --- /dev/null +++ b/WSSiOS/WSSiOS/Source/Data/Entity/SearchKeywordEntity.swift @@ -0,0 +1,18 @@ +// +// SearchKeywordEntity.swift +// WSSiOS +// +// Created by Hyowon Jeon on 3/23/25. +// + +import Foundation + +struct SearchKeywordEntity { + let categories: [KeywordCategory] +} + +extension SearchKeywordResponse { + func toEntity() -> SearchKeywordEntity { + return SearchKeywordEntity(categories: self.categories) + } +} diff --git a/WSSiOS/WSSiOS/Source/Data/Repository/KeywordRepository.swift b/WSSiOS/WSSiOS/Source/Data/Repository/KeywordRepository.swift index 73e6c135d..4644d64b8 100644 --- a/WSSiOS/WSSiOS/Source/Data/Repository/KeywordRepository.swift +++ b/WSSiOS/WSSiOS/Source/Data/Repository/KeywordRepository.swift @@ -10,7 +10,7 @@ import Foundation import RxSwift protocol KeywordRepository { - func searchKeyword(query: String?) -> Observable + func searchKeyword(query: String?) -> Observable } struct DefaultKeywordRepository: KeywordRepository { @@ -21,8 +21,9 @@ struct DefaultKeywordRepository: KeywordRepository { self.keywordService = keywordService } - func searchKeyword(query: String?) -> Observable { + func searchKeyword(query: String?) -> Observable { return keywordService.searchKeyword(query: query) + .map{ $0.toEntity() } .asObservable() } } diff --git a/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelKeywordSelectModalViewModel.swift b/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelKeywordSelectModalViewModel.swift index 5688d6fbf..04afa247e 100644 --- a/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelKeywordSelectModalViewModel.swift +++ b/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelKeywordSelectModalViewModel.swift @@ -237,7 +237,7 @@ final class NovelKeywordSelectModalViewModel: ViewModelType { //MARK: - API - private func searchKeyword(query: String? = nil) -> Observable { + private func searchKeyword(query: String? = nil) -> Observable { keywordRepository.searchKeyword(query: query) .observe(on: MainScheduler.instance) } diff --git a/WSSiOS/WSSiOS/Source/Presentation/Search/DetailSearch/DetailSearchViewModel/DetailSearchViewModel.swift b/WSSiOS/WSSiOS/Source/Presentation/Search/DetailSearch/DetailSearchViewModel/DetailSearchViewModel.swift index 4914cca57..79b228def 100644 --- a/WSSiOS/WSSiOS/Source/Presentation/Search/DetailSearch/DetailSearchViewModel/DetailSearchViewModel.swift +++ b/WSSiOS/WSSiOS/Source/Presentation/Search/DetailSearch/DetailSearchViewModel/DetailSearchViewModel.swift @@ -392,7 +392,7 @@ final class DetailSearchViewModel: ViewModelType { //MARK: - API - private func searchKeyword(query: String? = nil) -> Observable { + private func searchKeyword(query: String? = nil) -> Observable { keywordRepository.searchKeyword(query: query) .observe(on: MainScheduler.instance) } From 872ae2062e42f5a38b1edc8c371c996117e2fba4 Mon Sep 17 00:00:00 2001 From: Hyowon Jeon Date: Sun, 23 Mar 2025 01:03:55 +0900 Subject: [PATCH 2/7] =?UTF-8?q?[Refactor]=20#510=20-=20NovelReview=20DTO/E?= =?UTF-8?q?ntity=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NovelReview/NovelReviewService.swift | 22 +++++------ ...Result.swift => NovelReviewResponse.swift} | 6 +-- .../Data/Entity/NovelReviewEntity.swift | 37 +++++++++++++++++++ .../Repository/NovelReviewRepository.swift | 5 ++- .../NovelReviewViewModel.swift | 8 ++-- 5 files changed, 57 insertions(+), 21 deletions(-) rename WSSiOS/WSSiOS/Source/Data/DTO/{NovelReviewResult.swift => NovelReviewResponse.swift} (84%) create mode 100644 WSSiOS/WSSiOS/Source/Data/Entity/NovelReviewEntity.swift diff --git a/WSSiOS/WSSiOS/Network/NovelReview/NovelReviewService.swift b/WSSiOS/WSSiOS/Network/NovelReview/NovelReviewService.swift index 7f60c6f2c..31f386218 100644 --- a/WSSiOS/WSSiOS/Network/NovelReview/NovelReviewService.swift +++ b/WSSiOS/WSSiOS/Network/NovelReview/NovelReviewService.swift @@ -24,7 +24,7 @@ protocol NovelReviewService { endDate: String?, attractivePoints: [String], keywordIds: [Int]) -> Single - func getNovelReview(novelId: Int) -> Single + func getNovelReview(novelId: Int) -> Single } final class DefaultNovelReviewService: NSObject, Networking, NovelReviewService { @@ -35,7 +35,7 @@ final class DefaultNovelReviewService: NSObject, Networking, NovelReviewService endDate: String?, attractivePoints: [String], keywordIds: [Int]) -> Single { - guard let novelReviewContentData = try? JSONEncoder().encode(PostNovelReviewContent(novelId: novelId, userNovelRating: userNovelRating, status: status, startDate: startDate, endDate: endDate, attractivePoints: attractivePoints, keywordIds: keywordIds)) else { + guard let novelReviewContentData = try? JSONEncoder().encode(PostNovelReviewRequest(novelId: novelId, userNovelRating: userNovelRating, status: status, startDate: startDate, endDate: endDate, attractivePoints: attractivePoints, keywordIds: keywordIds)) else { return Single.error(NetworkServiceError.invalidRequestError) } @@ -56,13 +56,13 @@ final class DefaultNovelReviewService: NSObject, Networking, NovelReviewService } func putNovelReview(novelId: Int, - userNovelRating: Float, - status: String, - startDate: String?, - endDate: String?, - attractivePoints: [String], - keywordIds: [Int]) -> Single { - guard let novelReviewContentData = try? JSONEncoder().encode(PutNovelReviewContent(userNovelRating: userNovelRating, status: status, startDate: startDate, endDate: endDate, attractivePoints: attractivePoints, keywordIds: keywordIds)) else { + userNovelRating: Float, + status: String, + startDate: String?, + endDate: String?, + attractivePoints: [String], + keywordIds: [Int]) -> Single { + guard let novelReviewContentData = try? JSONEncoder().encode(PutNovelReviewRequest(userNovelRating: userNovelRating, status: status, startDate: startDate, endDate: endDate, attractivePoints: attractivePoints, keywordIds: keywordIds)) else { return Single.error(NetworkServiceError.invalidRequestError) } @@ -82,7 +82,7 @@ final class DefaultNovelReviewService: NSObject, Networking, NovelReviewService } } - func getNovelReview(novelId: Int) -> Single { + func getNovelReview(novelId: Int) -> Single { do { let request = try makeHTTPRequest(method: .get, path: URLs.NovelReview.getNovelReview(novelId: novelId), @@ -93,7 +93,7 @@ final class DefaultNovelReviewService: NSObject, Networking, NovelReviewService return tokenCheckURLSession.rx.data(request: request) .map { try self.decode(data: $0, - to: NovelReviewResult.self) } + to: NovelReviewResponse.self) } .asSingle() } catch { diff --git a/WSSiOS/WSSiOS/Source/Data/DTO/NovelReviewResult.swift b/WSSiOS/WSSiOS/Source/Data/DTO/NovelReviewResponse.swift similarity index 84% rename from WSSiOS/WSSiOS/Source/Data/DTO/NovelReviewResult.swift rename to WSSiOS/WSSiOS/Source/Data/DTO/NovelReviewResponse.swift index 88aa3b9b0..48cda9d3b 100644 --- a/WSSiOS/WSSiOS/Source/Data/DTO/NovelReviewResult.swift +++ b/WSSiOS/WSSiOS/Source/Data/DTO/NovelReviewResponse.swift @@ -7,7 +7,7 @@ import Foundation -struct NovelReviewResult: Codable { +struct NovelReviewResponse: Decodable { let novelTitle: String let status: String? let startDate: String? @@ -17,7 +17,7 @@ struct NovelReviewResult: Codable { let keywords: [KeywordData] } -struct PostNovelReviewContent: Codable { +struct PostNovelReviewRequest: Encodable { let novelId: Int let userNovelRating: Float let status: String @@ -27,7 +27,7 @@ struct PostNovelReviewContent: Codable { let keywordIds: [Int] } -struct PutNovelReviewContent: Codable { +struct PutNovelReviewRequest: Encodable { let userNovelRating: Float let status: String let startDate: String? diff --git a/WSSiOS/WSSiOS/Source/Data/Entity/NovelReviewEntity.swift b/WSSiOS/WSSiOS/Source/Data/Entity/NovelReviewEntity.swift new file mode 100644 index 000000000..a43585975 --- /dev/null +++ b/WSSiOS/WSSiOS/Source/Data/Entity/NovelReviewEntity.swift @@ -0,0 +1,37 @@ +// +// NovelReviewEntity.swift +// WSSiOS +// +// Created by Hyowon Jeon on 3/23/25. +// + +import Foundation + +struct NovelReviewEntity { + let novelTitle: String + let status: String? + let startDate: Date? + let endDate: Date? + let userNovelRating: Float + let attractivePoints: [String] + let keywords: [KeywordData] +} + +extension NovelReviewResponse { + func toEntity() -> NovelReviewEntity { + let dateFormatter = DateFormatter().then { + $0.dateFormat = "yyyy-MM-dd" + $0.timeZone = TimeZone(identifier: "ko_KR") + } + + let startDate = self.startDate.flatMap { dateFormatter.date(from: $0) } + let endDate = self.endDate.flatMap { dateFormatter.date(from: $0) } + return NovelReviewEntity(novelTitle: self.novelTitle, + status: self.status, + startDate: startDate, + endDate: endDate, + userNovelRating: self.userNovelRating, + attractivePoints: self.attractivePoints, + keywords: self.keywords) + } +} diff --git a/WSSiOS/WSSiOS/Source/Data/Repository/NovelReviewRepository.swift b/WSSiOS/WSSiOS/Source/Data/Repository/NovelReviewRepository.swift index 972104560..4c7faa4b4 100644 --- a/WSSiOS/WSSiOS/Source/Data/Repository/NovelReviewRepository.swift +++ b/WSSiOS/WSSiOS/Source/Data/Repository/NovelReviewRepository.swift @@ -24,7 +24,7 @@ protocol NovelReviewRepository { endDate: String?, attractivePoints: [String], keywordIds: [Int]) -> Observable - func getNovelReview(novelId: Int) -> Observable + func getNovelReview(novelId: Int) -> Observable } struct DefaultNovelReviewRepository: NovelReviewRepository { @@ -68,8 +68,9 @@ struct DefaultNovelReviewRepository: NovelReviewRepository { .asObservable() } - func getNovelReview(novelId: Int) -> Observable { + func getNovelReview(novelId: Int) -> Observable { return novelReviewService.getNovelReview(novelId: novelId) + .map { $0.toEntity() } .asObservable() } } diff --git a/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelReviewViewModel.swift b/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelReviewViewModel.swift index 741b182a8..26e03bcc9 100644 --- a/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelReviewViewModel.swift +++ b/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelReviewViewModel.swift @@ -102,10 +102,8 @@ final class NovelReviewViewModel: ViewModelType { } .subscribe(with: self, onNext: { owner, data in owner.isNovelReviewExist = data.status != nil || owner.isInterest == true - if data.startDate != nil || data.endDate != nil { - owner.startDate = data.startDate.flatMap { owner.dateFormatter.date(from: $0) } ?? Date() - owner.endDate = data.endDate.flatMap { owner.dateFormatter.date(from: $0) } ?? Date() - } + owner.startDate = data.startDate + owner.endDate = data.endDate owner.startDateEndDateData.accept([owner.startDate, owner.endDate]) owner.starRating.accept(data.userNovelRating) owner.selectedKeywordListData.accept(data.keywords) @@ -313,7 +311,7 @@ final class NovelReviewViewModel: ViewModelType { .observe(on: MainScheduler.instance) } - private func getNovelReview(novelId: Int) -> Observable { + private func getNovelReview(novelId: Int) -> Observable { novelReviewRepository.getNovelReview(novelId: novelId) .observe(on: MainScheduler.instance) } From d89bd969bdbb8086e4dc2a9856a43ce7c64bdaca Mon Sep 17 00:00:00 2001 From: Hyowon Jeon Date: Sun, 23 Mar 2025 01:11:53 +0900 Subject: [PATCH 3/7] =?UTF-8?q?[Refactor]=20#510=20-=20Auth=20DTO/Entity?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- WSSiOS/WSSiOS/Network/Auth/AuthService.swift | 2 +- .../DTO/{AuthResult.swift => AuthDTO.swift} | 2 +- .../Source/Data/Entity/AuthEntity.swift | 22 +++++++++++++++++++ .../Data/Repository/AuthRepository.swift | 10 +++++---- .../Login/LoginViewModel/LoginViewModel.swift | 4 ++-- 5 files changed, 32 insertions(+), 8 deletions(-) rename WSSiOS/WSSiOS/Source/Data/DTO/{AuthResult.swift => AuthDTO.swift} (94%) create mode 100644 WSSiOS/WSSiOS/Source/Data/Entity/AuthEntity.swift diff --git a/WSSiOS/WSSiOS/Network/Auth/AuthService.swift b/WSSiOS/WSSiOS/Network/Auth/AuthService.swift index 7a67c62ff..4828702a3 100644 --- a/WSSiOS/WSSiOS/Network/Auth/AuthService.swift +++ b/WSSiOS/WSSiOS/Network/Auth/AuthService.swift @@ -22,7 +22,7 @@ protocol AuthService { final class DefaultAuthService: NSObject, Networking, AuthService { func loginWithApple(authorizationCode: String, idToken: String) -> RxSwift.Single { - guard let appleLoginBody = try? JSONEncoder().encode(AppleLoginBody(authorizationCode: authorizationCode, idToken: idToken)) else { + guard let appleLoginBody = try? JSONEncoder().encode(AppleLoginRequest(authorizationCode: authorizationCode, idToken: idToken)) else { return Single.error(NetworkServiceError.invalidRequestError) } diff --git a/WSSiOS/WSSiOS/Source/Data/DTO/AuthResult.swift b/WSSiOS/WSSiOS/Source/Data/DTO/AuthDTO.swift similarity index 94% rename from WSSiOS/WSSiOS/Source/Data/DTO/AuthResult.swift rename to WSSiOS/WSSiOS/Source/Data/DTO/AuthDTO.swift index ca4df25ea..43bac18dc 100644 --- a/WSSiOS/WSSiOS/Source/Data/DTO/AuthResult.swift +++ b/WSSiOS/WSSiOS/Source/Data/DTO/AuthDTO.swift @@ -7,7 +7,7 @@ import Foundation -struct AppleLoginBody: Codable { +struct AppleLoginRequest: Encodable { let authorizationCode: String let idToken: String } diff --git a/WSSiOS/WSSiOS/Source/Data/Entity/AuthEntity.swift b/WSSiOS/WSSiOS/Source/Data/Entity/AuthEntity.swift new file mode 100644 index 000000000..d9dafb462 --- /dev/null +++ b/WSSiOS/WSSiOS/Source/Data/Entity/AuthEntity.swift @@ -0,0 +1,22 @@ +// +// AuthEntity.swift +// WSSiOS +// +// Created by Hyowon Jeon on 3/23/25. +// + +import Foundation + +struct LoginEntity { + let Authorization: String + let refreshToken: String + let isRegister: Bool +} + +extension LoginResponse { + func toEntity() -> LoginEntity { + return LoginEntity(Authorization: self.Authorization, + refreshToken: self.refreshToken, + isRegister: self.isRegister) + } +} diff --git a/WSSiOS/WSSiOS/Source/Data/Repository/AuthRepository.swift b/WSSiOS/WSSiOS/Source/Data/Repository/AuthRepository.swift index 08f4f15bb..3e196ea83 100644 --- a/WSSiOS/WSSiOS/Source/Data/Repository/AuthRepository.swift +++ b/WSSiOS/WSSiOS/Source/Data/Repository/AuthRepository.swift @@ -12,8 +12,8 @@ import RxKakaoSDKAuth import RxSwift protocol AuthRepository { - func loginWithApple(authorizationCode: String, idToken: String) -> Observable - func loginWithKakao(_ kakaoAccessToken: OAuthToken) -> Single + func loginWithApple(authorizationCode: String, idToken: String) -> Observable + func loginWithKakao(_ kakaoAccessToken: OAuthToken) -> Single func postWithdrawId(withdrawData: WithdrawRequest) -> Observable func postLogout(refreshToken: String, deviceIdentifier: String) -> Observable } @@ -26,13 +26,15 @@ struct DefaultAuthRepository: AuthRepository { self.authService = authService } - func loginWithApple(authorizationCode: String, idToken: String) -> Observable { + func loginWithApple(authorizationCode: String, idToken: String) -> Observable { return authService.loginWithApple(authorizationCode: authorizationCode, idToken: idToken) + .map { $0.toEntity() } .asObservable() } - func loginWithKakao(_ kakaoAccessToken: OAuthToken) -> Single { + func loginWithKakao(_ kakaoAccessToken: OAuthToken) -> Single { return authService.loginWithKakao(kakaoAccessToken.accessToken) + .map { $0.toEntity() } } func postWithdrawId(withdrawData: WithdrawRequest) -> Observable { diff --git a/WSSiOS/WSSiOS/Source/Presentation/Login/LoginViewModel/LoginViewModel.swift b/WSSiOS/WSSiOS/Source/Presentation/Login/LoginViewModel/LoginViewModel.swift index e3b1d36c5..c05de1e38 100644 --- a/WSSiOS/WSSiOS/Source/Presentation/Login/LoginViewModel/LoginViewModel.swift +++ b/WSSiOS/WSSiOS/Source/Presentation/Login/LoginViewModel/LoginViewModel.swift @@ -137,7 +137,7 @@ final class LoginViewModel: NSObject, ViewModelType { }) } - private func loginSuccess(result: LoginResponse) { + private func loginSuccess(result: LoginEntity) { UserDefaults.standard.setValue(result.Authorization, forKey: StringLiterals.UserDefault.accessToken) UserDefaults.standard.setValue(result.refreshToken, @@ -154,7 +154,7 @@ final class LoginViewModel: NSObject, ViewModelType { //MARK: - API/Apple - private func loginWithApple(authorizationCode: String, idToken: String) -> Observable { + private func loginWithApple(authorizationCode: String, idToken: String) -> Observable { authRepository.loginWithApple(authorizationCode: authorizationCode, idToken: idToken) .observe(on: MainScheduler.instance) } From a3023032ea5641920a5265e25711b55010448db1 Mon Sep 17 00:00:00 2001 From: Hyowon Jeon Date: Sun, 23 Mar 2025 01:30:38 +0900 Subject: [PATCH 4/7] =?UTF-8?q?[Refactor]=20#510=20-=20NovelReview=20DTO/E?= =?UTF-8?q?ntity=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NovelReview/NovelReviewService.swift | 36 ++--------- .../Data/Entity/NovelReviewEntity.swift | 42 +++++++++++++ .../Repository/NovelReviewRepository.swift | 54 ++++------------- .../NovelReviewViewModel.swift | 60 +++++++------------ 4 files changed, 80 insertions(+), 112 deletions(-) diff --git a/WSSiOS/WSSiOS/Network/NovelReview/NovelReviewService.swift b/WSSiOS/WSSiOS/Network/NovelReview/NovelReviewService.swift index 31f386218..05e92d7cb 100644 --- a/WSSiOS/WSSiOS/Network/NovelReview/NovelReviewService.swift +++ b/WSSiOS/WSSiOS/Network/NovelReview/NovelReviewService.swift @@ -10,32 +10,14 @@ import Foundation import RxSwift protocol NovelReviewService { - func postNovelReview(novelId: Int, - userNovelRating: Float, - status: String, - startDate: String?, - endDate: String?, - attractivePoints: [String], - keywordIds: [Int]) -> Single - func putNovelReview(novelId: Int, - userNovelRating: Float, - status: String, - startDate: String?, - endDate: String?, - attractivePoints: [String], - keywordIds: [Int]) -> Single + func postNovelReview(novelReviewData: PostNovelReviewRequest) -> Single + func putNovelReview(novelId: Int, novelReviewData: PutNovelReviewRequest) -> Single func getNovelReview(novelId: Int) -> Single } final class DefaultNovelReviewService: NSObject, Networking, NovelReviewService { - func postNovelReview(novelId: Int, - userNovelRating: Float, - status: String, - startDate: String?, - endDate: String?, - attractivePoints: [String], - keywordIds: [Int]) -> Single { - guard let novelReviewContentData = try? JSONEncoder().encode(PostNovelReviewRequest(novelId: novelId, userNovelRating: userNovelRating, status: status, startDate: startDate, endDate: endDate, attractivePoints: attractivePoints, keywordIds: keywordIds)) else { + func postNovelReview(novelReviewData: PostNovelReviewRequest) -> Single { + guard let novelReviewContentData = try? JSONEncoder().encode(novelReviewData) else { return Single.error(NetworkServiceError.invalidRequestError) } @@ -55,14 +37,8 @@ final class DefaultNovelReviewService: NSObject, Networking, NovelReviewService } } - func putNovelReview(novelId: Int, - userNovelRating: Float, - status: String, - startDate: String?, - endDate: String?, - attractivePoints: [String], - keywordIds: [Int]) -> Single { - guard let novelReviewContentData = try? JSONEncoder().encode(PutNovelReviewRequest(userNovelRating: userNovelRating, status: status, startDate: startDate, endDate: endDate, attractivePoints: attractivePoints, keywordIds: keywordIds)) else { + func putNovelReview(novelId: Int, novelReviewData: PutNovelReviewRequest) -> Single { + guard let novelReviewContentData = try? JSONEncoder().encode(novelReviewData) else { return Single.error(NetworkServiceError.invalidRequestError) } diff --git a/WSSiOS/WSSiOS/Source/Data/Entity/NovelReviewEntity.swift b/WSSiOS/WSSiOS/Source/Data/Entity/NovelReviewEntity.swift index a43585975..eef9a9edd 100644 --- a/WSSiOS/WSSiOS/Source/Data/Entity/NovelReviewEntity.swift +++ b/WSSiOS/WSSiOS/Source/Data/Entity/NovelReviewEntity.swift @@ -35,3 +35,45 @@ extension NovelReviewResponse { keywords: self.keywords) } } + +struct PostNovelReviewEntity { + let novelId: Int + let userNovelRating: Float + let status: String + let startDate: String? + let endDate: String? + let attractivePoints: [String] + let keywordIds: [Int] +} + +extension PostNovelReviewEntity { + func toDTO() -> PostNovelReviewRequest { + return PostNovelReviewRequest(novelId: self.novelId, + userNovelRating: self.userNovelRating, + status: self.status, + startDate: self.startDate, + endDate: self.endDate, + attractivePoints: self.attractivePoints, + keywordIds: self.keywordIds) + } +} + +struct PutNovelReviewEntity { + let userNovelRating: Float + let status: String + let startDate: String? + let endDate: String? + let attractivePoints: [String] + let keywordIds: [Int] +} + +extension PutNovelReviewEntity { + func toDTO() -> PutNovelReviewRequest { + return PutNovelReviewRequest(userNovelRating: self.userNovelRating, + status: self.status, + startDate: self.startDate, + endDate: self.endDate, + attractivePoints: self.attractivePoints, + keywordIds: self.keywordIds) + } +} diff --git a/WSSiOS/WSSiOS/Source/Data/Repository/NovelReviewRepository.swift b/WSSiOS/WSSiOS/Source/Data/Repository/NovelReviewRepository.swift index 4c7faa4b4..6b5664a95 100644 --- a/WSSiOS/WSSiOS/Source/Data/Repository/NovelReviewRepository.swift +++ b/WSSiOS/WSSiOS/Source/Data/Repository/NovelReviewRepository.swift @@ -10,20 +10,8 @@ import Foundation import RxSwift protocol NovelReviewRepository { - func postNovelReview(novelId: Int, - userNovelRating: Float, - status: String, - startDate: String?, - endDate: String?, - attractivePoints: [String], - keywordIds: [Int]) -> Observable - func putNovelReview(novelId: Int, - userNovelRating: Float, - status: String, - startDate: String?, - endDate: String?, - attractivePoints: [String], - keywordIds: [Int]) -> Observable + func postNovelReview(novelReviewData: PostNovelReviewEntity) -> Observable + func putNovelReview(novelId: Int, novelReviewData: PutNovelReviewEntity) -> Observable func getNovelReview(novelId: Int) -> Observable } @@ -34,38 +22,16 @@ struct DefaultNovelReviewRepository: NovelReviewRepository { self.novelReviewService = novelReviewService } - func postNovelReview(novelId: Int, - userNovelRating: Float, - status: String, - startDate: String?, - endDate: String?, - attractivePoints: [String], - keywordIds: [Int]) -> Observable { - return novelReviewService.postNovelReview(novelId: novelId, - userNovelRating: userNovelRating, - status: status, - startDate: startDate, - endDate: endDate, - attractivePoints: attractivePoints, - keywordIds: keywordIds) - .asObservable() + func postNovelReview(novelReviewData: PostNovelReviewEntity) -> Observable { + let novelReviewDataDTO = novelReviewData.toDTO() + return novelReviewService.postNovelReview(novelReviewData: novelReviewDataDTO) + .asObservable() } - func putNovelReview(novelId: Int, - userNovelRating: Float, - status: String, - startDate: String?, - endDate: String?, - attractivePoints: [String], - keywordIds: [Int]) -> Observable { - return novelReviewService.putNovelReview(novelId: novelId, - userNovelRating: userNovelRating, - status: status, - startDate: startDate, - endDate: endDate, - attractivePoints: attractivePoints, - keywordIds: keywordIds) - .asObservable() + func putNovelReview(novelId: Int, novelReviewData: PutNovelReviewEntity) -> Observable { + let novelReviewDataDTO = novelReviewData.toDTO() + return novelReviewService.putNovelReview(novelId: novelId, novelReviewData: novelReviewDataDTO) + .asObservable() } func getNovelReview(novelId: Int) -> Observable { diff --git a/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelReviewViewModel.swift b/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelReviewViewModel.swift index 26e03bcc9..2616128e1 100644 --- a/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelReviewViewModel.swift +++ b/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelReviewViewModel.swift @@ -23,7 +23,7 @@ final class NovelReviewViewModel: ViewModelType { let novelTitle: String private var isNovelReviewExist: Bool = false - + private var startDate: Date? private var endDate: Date? var selectedAttractivePointList: [String] = [] @@ -126,14 +126,13 @@ final class NovelReviewViewModel: ViewModelType { .throttle(.seconds(3), latest: false, scheduler: MainScheduler.instance) .flatMapLatest { AmplitudeManager.shared.track(AmplitudeEvent.Novel.rateNovel) - + let startDateString = self.readStatus != .quit ? self.startDate.map { self.dateFormatter.string(from: $0) } : nil let endDateString = self.readStatus != .watching ? self.endDate.map { self.dateFormatter.string(from: $0) } : nil let keywordIdList = self.selectedKeywordListData.value.map { $0.keywordId } if self.isNovelReviewExist { - return self.putNovelReview( - novelId: self.novelId, + let novelReviewData = PutNovelReviewEntity( userNovelRating: self.starRating.value, status: self.readStatus.rawValue, startDate: startDateString, @@ -141,8 +140,13 @@ final class NovelReviewViewModel: ViewModelType { attractivePoints: self.selectedAttractivePointList, keywordIds: keywordIdList ) + + return self.putNovelReview( + novelId: self.novelId, + novelReviewData: novelReviewData + ) } else { - return self.postNovelReview( + let novelReviewData = PostNovelReviewEntity( novelId: self.novelId, userNovelRating: self.starRating.value, status: self.readStatus.rawValue, @@ -151,6 +155,10 @@ final class NovelReviewViewModel: ViewModelType { attractivePoints: self.selectedAttractivePointList, keywordIds: keywordIdList ) + + return self.postNovelReview( + novelReviewData: novelReviewData + ) } } .subscribe(with: self, onNext: { owner, _ in @@ -171,8 +179,8 @@ final class NovelReviewViewModel: ViewModelType { input.dateLabelTapGesture .subscribe(with: self, onNext: { owner, _ in owner.presentNovelDateSelectModalViewController.accept((owner.readStatus, - owner.startDate, - owner.endDate)) + owner.startDate, + owner.endDate)) }) .disposed(by: disposeBag) @@ -260,7 +268,7 @@ final class NovelReviewViewModel: ViewModelType { owner.popViewController.accept(()) }) .disposed(by: disposeBag) - + return Output(popViewController: popViewController.asObservable(), readStatusListData: readStatusListData.asObservable(), readStatusData: readStatusData.asObservable(), @@ -277,38 +285,14 @@ final class NovelReviewViewModel: ViewModelType { //MARK: - API - private func postNovelReview(novelId: Int, - userNovelRating: Float, - status: String, - startDate: String?, - endDate: String?, - attractivePoints: [String], - keywordIds: [Int]) -> Observable { - novelReviewRepository.postNovelReview(novelId: novelId, - userNovelRating: userNovelRating, - status: status, - startDate: startDate, - endDate: endDate, - attractivePoints: attractivePoints, - keywordIds: keywordIds) - .observe(on: MainScheduler.instance) + private func postNovelReview(novelReviewData: PostNovelReviewEntity) -> Observable { + novelReviewRepository.postNovelReview(novelReviewData: novelReviewData) + .observe(on: MainScheduler.instance) } - private func putNovelReview(novelId: Int, - userNovelRating: Float, - status: String, - startDate: String?, - endDate: String?, - attractivePoints: [String], - keywordIds: [Int]) -> Observable { - novelReviewRepository.putNovelReview(novelId: novelId, - userNovelRating: userNovelRating, - status: status, - startDate: startDate, - endDate: endDate, - attractivePoints: attractivePoints, - keywordIds: keywordIds) - .observe(on: MainScheduler.instance) + private func putNovelReview(novelId: Int, novelReviewData: PutNovelReviewEntity) -> Observable { + novelReviewRepository.putNovelReview(novelId: novelId, novelReviewData: novelReviewData) + .observe(on: MainScheduler.instance) } private func getNovelReview(novelId: Int) -> Observable { From 829f1bf6c822483af2052be7dd4b5ccd08be0d45 Mon Sep 17 00:00:00 2001 From: Hyowon Jeon Date: Sun, 23 Mar 2025 01:43:24 +0900 Subject: [PATCH 5/7] =?UTF-8?q?[Refactor]=20#510=20-=20Auth=20DTO/Entity?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- WSSiOS/WSSiOS/Network/Auth/AuthService.swift | 7 +++---- .../WSSiOS/Source/Data/Entity/AuthEntity.swift | 14 ++++++++++++++ .../Data/Repository/AuthRepository.swift | 7 ++++--- .../Login/LoginViewModel/LoginViewModel.swift | 18 +++++++++--------- 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/WSSiOS/WSSiOS/Network/Auth/AuthService.swift b/WSSiOS/WSSiOS/Network/Auth/AuthService.swift index 4828702a3..f9b405461 100644 --- a/WSSiOS/WSSiOS/Network/Auth/AuthService.swift +++ b/WSSiOS/WSSiOS/Network/Auth/AuthService.swift @@ -10,8 +10,7 @@ import Foundation import RxSwift protocol AuthService { - func loginWithApple(authorizationCode: String, - idToken: String) -> Single + func loginWithApple(appleLoginData: AppleLoginRequest) -> Single func loginWithKakao(_ kakaoAccessToken: String) -> Single func reissueToken() -> Single func postWithdrawId(withdrawData: WithdrawRequest) -> Single @@ -21,8 +20,8 @@ protocol AuthService { final class DefaultAuthService: NSObject, Networking, AuthService { - func loginWithApple(authorizationCode: String, idToken: String) -> RxSwift.Single { - guard let appleLoginBody = try? JSONEncoder().encode(AppleLoginRequest(authorizationCode: authorizationCode, idToken: idToken)) else { + func loginWithApple(appleLoginData: AppleLoginRequest) -> RxSwift.Single { + guard let appleLoginBody = try? JSONEncoder().encode(appleLoginData) else { return Single.error(NetworkServiceError.invalidRequestError) } diff --git a/WSSiOS/WSSiOS/Source/Data/Entity/AuthEntity.swift b/WSSiOS/WSSiOS/Source/Data/Entity/AuthEntity.swift index d9dafb462..ba15fc91e 100644 --- a/WSSiOS/WSSiOS/Source/Data/Entity/AuthEntity.swift +++ b/WSSiOS/WSSiOS/Source/Data/Entity/AuthEntity.swift @@ -7,6 +7,20 @@ import Foundation +struct AppleLoginEntity { + let authorizationCode: Data + let idToken: Data +} + +extension AppleLoginEntity { + func toDTO() -> AppleLoginRequest { + let authorizationCode = String(data: authorizationCode, encoding: String.Encoding.utf8)! + let idToken = String(data: idToken, encoding: String.Encoding.utf8)! + return AppleLoginRequest(authorizationCode: authorizationCode, + idToken: idToken) + } +} + struct LoginEntity { let Authorization: String let refreshToken: String diff --git a/WSSiOS/WSSiOS/Source/Data/Repository/AuthRepository.swift b/WSSiOS/WSSiOS/Source/Data/Repository/AuthRepository.swift index 3e196ea83..7e3c87498 100644 --- a/WSSiOS/WSSiOS/Source/Data/Repository/AuthRepository.swift +++ b/WSSiOS/WSSiOS/Source/Data/Repository/AuthRepository.swift @@ -12,7 +12,7 @@ import RxKakaoSDKAuth import RxSwift protocol AuthRepository { - func loginWithApple(authorizationCode: String, idToken: String) -> Observable + func loginWithApple(appleLoginData: AppleLoginEntity) -> Observable func loginWithKakao(_ kakaoAccessToken: OAuthToken) -> Single func postWithdrawId(withdrawData: WithdrawRequest) -> Observable func postLogout(refreshToken: String, deviceIdentifier: String) -> Observable @@ -26,8 +26,9 @@ struct DefaultAuthRepository: AuthRepository { self.authService = authService } - func loginWithApple(authorizationCode: String, idToken: String) -> Observable { - return authService.loginWithApple(authorizationCode: authorizationCode, idToken: idToken) + func loginWithApple(appleLoginData: AppleLoginEntity) -> Observable { + let appleLoginDataDTO = appleLoginData.toDTO() + return authService.loginWithApple(appleLoginData: appleLoginDataDTO) .map { $0.toEntity() } .asObservable() } diff --git a/WSSiOS/WSSiOS/Source/Presentation/Login/LoginViewModel/LoginViewModel.swift b/WSSiOS/WSSiOS/Source/Presentation/Login/LoginViewModel/LoginViewModel.swift index c05de1e38..6cc8ede3b 100644 --- a/WSSiOS/WSSiOS/Source/Presentation/Login/LoginViewModel/LoginViewModel.swift +++ b/WSSiOS/WSSiOS/Source/Presentation/Login/LoginViewModel/LoginViewModel.swift @@ -35,8 +35,7 @@ final class LoginViewModel: NSObject, ViewModelType { private let navigateToHome = PublishRelay() private let navigateToOnboarding = PublishRelay() - private let loginWithApple = PublishRelay<(authorizationCode: String, - idToken: String)>() + private let loginWithApple = PublishRelay() //MARK: - Life Cycle @@ -103,9 +102,8 @@ final class LoginViewModel: NSObject, ViewModelType { // 애플로그인 후 authorizationCode와 idToken을 받아와서 로그인 요청 loginWithApple - .flatMapLatest { authorizationCode, idToken in - self.loginWithApple(authorizationCode: authorizationCode, - idToken: idToken) + .flatMapLatest { loginWithApple in + self.loginWithApple(appleLoginData: loginWithApple) } .subscribe(with: self, onNext: { owner, result in owner.loginSuccess(result: result) @@ -154,8 +152,8 @@ final class LoginViewModel: NSObject, ViewModelType { //MARK: - API/Apple - private func loginWithApple(authorizationCode: String, idToken: String) -> Observable { - authRepository.loginWithApple(authorizationCode: authorizationCode, idToken: idToken) + private func loginWithApple(appleLoginData: AppleLoginEntity) -> Observable { + authRepository.loginWithApple(appleLoginData: appleLoginData) .observe(on: MainScheduler.instance) } @@ -221,8 +219,10 @@ extension LoginViewModel: ASAuthorizationControllerDelegate { return } - loginWithApple.accept((authorizationCode: String(data: credential.authorizationCode!, encoding: String.Encoding.utf8)!, - idToken: String(data: credential.identityToken!, encoding: String.Encoding.utf8)!)) + let appleLoginData = AppleLoginEntity(authorizationCode: credential.authorizationCode!, + idToken: credential.identityToken!) + + loginWithApple.accept(appleLoginData) } func authorizationController( From 78de1e1eaa2f8e2b989065c0f76e5bae864e5dfe Mon Sep 17 00:00:00 2001 From: Hyowon Jeon Date: Mon, 24 Mar 2025 18:44:11 +0900 Subject: [PATCH 6/7] =?UTF-8?q?[Refactor]=20#510=20-=20VM=20=EA=B1=B0?= =?UTF-8?q?=EC=B9=A0=20=ED=95=84=EC=9A=94=20=EC=97=86=EB=8A=94=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20VC=EC=97=91=EC=84=9C=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FeedEditViewController.swift | 15 +++++----- .../FeedNovelConnectModalViewController.swift | 10 ++++++- .../FeedEditViewModel/FeedEditViewModel.swift | 21 ++----------- .../FeedNovelConnectModalViewModel.swift | 7 ----- .../NovelDetailViewController.swift | 30 ++++++++----------- .../NovelDetailViewModel.swift | 20 +------------ .../NovelDateSelectModalViewController.swift | 12 ++++++-- .../NovelReviewViewController.swift | 16 +++++----- .../NovelDateSelectModalViewModel.swift | 7 ----- .../NovelReviewViewModel.swift | 21 ++----------- 10 files changed, 53 insertions(+), 106 deletions(-) diff --git a/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewController/FeedEditViewController.swift b/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewController/FeedEditViewController.swift index d79c7af29..a5f10261d 100644 --- a/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewController/FeedEditViewController.swift +++ b/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewController/FeedEditViewController.swift @@ -19,7 +19,6 @@ final class FeedEditViewController: UIViewController { private let disposeBag = DisposeBag() private let viewDidLoadEvent = PublishRelay() - private let stopEditingEvent = PublishRelay() //MARK: - Components @@ -54,6 +53,7 @@ final class FeedEditViewController: UIViewController { register() delegate() bindViewModel() + bindAction() viewDidLoadEvent.accept(()) @@ -104,7 +104,6 @@ final class FeedEditViewController: UIViewController { return true } .asObservable(), - backButtonDidTap: rootView.backButton.rx.tap, completeButtonDidTap: rootView.completeButton.rx.tap, spoilerButtonDidTap: rootView.feedEditContentView.spoilerButton.rx.tap, categoryCollectionViewItemSelected: rootView.feedEditCategoryView.categoryCollectionView.rx.itemSelected.asObservable(), @@ -114,8 +113,7 @@ final class FeedEditViewController: UIViewController { feedContentViewDidEndEditing: rootView.feedEditContentView.feedTextView.rx.didEndEditing, novelConnectViewDidTap: rootView.feedEditNovelConnectView.rx.tapGesture().when(.recognized).asObservable(), feedNovelConnectedNotification: NotificationCenter.default.rx.notification(Notification.Name("FeedNovelConnected")).asObservable(), - novelRemoveButtonDidTap: rootView.feedEditConnectedNovelView.removeButton.rx.tap, - stopEditButtonDidTap: stopEditingEvent.asObservable() + novelRemoveButtonDidTap: rootView.feedEditConnectedNovelView.removeButton.rx.tap ) let output = self.feedEditViewModel.transform(from: input, disposeBag: self.disposeBag) @@ -194,8 +192,11 @@ final class FeedEditViewController: UIViewController { owner.showToast(.novelAlreadyConnected) }) .disposed(by: disposeBag) - - output.showStopEditingAlert + } + + private func bindAction() { + rootView.backButton.rx.tap + .throttle(.seconds(3), latest: false, scheduler: MainScheduler.instance) .flatMapLatest { _ -> Observable in return self.presentToAlertViewController(iconImage: .icModalWarning, titleText: StringLiterals.FeedEdit.Alert.titleText, @@ -206,7 +207,7 @@ final class FeedEditViewController: UIViewController { } .subscribe(with: self, onNext: { owner, buttonType in if buttonType == .left { - owner.stopEditingEvent.accept(()) + owner.navigationController?.popViewController(animated: true) } }) .disposed(by: disposeBag) diff --git a/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewController/FeedNovelConnectModalViewController.swift b/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewController/FeedNovelConnectModalViewController.swift index 1f1319dd6..2de2713a6 100644 --- a/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewController/FeedNovelConnectModalViewController.swift +++ b/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewController/FeedNovelConnectModalViewController.swift @@ -42,6 +42,7 @@ final class FeedNovelConnectModalViewController: UIViewController { register() bindViewModel() + bindAction() } override func touchesBegan(_ touches: Set, with event: UIEvent?) { @@ -58,7 +59,6 @@ final class FeedNovelConnectModalViewController: UIViewController { private func bindViewModel() { let input = FeedNovelConnectModalViewModel.Input( - closeButtonDidTap: rootView.closeButton.rx.tap, searchTextUpdated: rootView.feedNovelConnectSearchBarView.titleTextField.rx.text.orEmpty.asObservable(), searchButtonDidTap: rootView.feedNovelConnectSearchBarView.searchButton.rx.tap, searchResultCollectionViewReachedBottom: observeReachedBottom(rootView.feedNovelConnectSearchResultView.searchResultCollectionView), @@ -102,6 +102,14 @@ final class FeedNovelConnectModalViewController: UIViewController { .disposed(by: disposeBag) } + private func bindAction() { + rootView.closeButton.rx.tap + .subscribe(with: self, onNext: { owner, _ in + owner.dismissModalViewController() + }) + .disposed(by: disposeBag) + } + // MARK: - Custom Method private func observeReachedBottom(_ scrollView: UIScrollView) -> Observable { diff --git a/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewModel/FeedEditViewModel.swift b/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewModel/FeedEditViewModel.swift index c6b05f938..f6c873fbd 100644 --- a/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewModel/FeedEditViewModel.swift +++ b/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewModel/FeedEditViewModel.swift @@ -49,7 +49,6 @@ final class FeedEditViewModel: ViewModelType { private let presentFeedEditNovelConnectModalViewController = PublishRelay() private let connectedNovelTitle = BehaviorRelay(value: nil) private let showAlreadyConnectedToast = PublishRelay() - private let showStopEditingAlert = PublishRelay() //MARK: - Life Cycle @@ -67,7 +66,6 @@ final class FeedEditViewModel: ViewModelType { struct Input { let viewDidLoadEvent: Observable let viewDidTap: Observable - let backButtonDidTap: ControlEvent let completeButtonDidTap: ControlEvent let spoilerButtonDidTap: ControlEvent let categoryCollectionViewItemSelected: Observable @@ -78,7 +76,6 @@ final class FeedEditViewModel: ViewModelType { let novelConnectViewDidTap: Observable let feedNovelConnectedNotification: Observable let novelRemoveButtonDidTap: ControlEvent - let stopEditButtonDidTap: Observable } struct Output { @@ -93,7 +90,6 @@ final class FeedEditViewModel: ViewModelType { let presentFeedEditNovelConnectModalViewController: Observable let connectedNovelTitle: Observable let showAlreadyConnectedToast: Observable - let showStopEditingAlert: Observable } func transform(from input: Input, disposeBag: DisposeBag) -> Output { @@ -126,13 +122,6 @@ final class FeedEditViewModel: ViewModelType { }) .disposed(by: disposeBag) - input.backButtonDidTap - .throttle(.seconds(3), latest: false, scheduler: MainScheduler.instance) - .subscribe(with: self, onNext: { owner, _ in - owner.showStopEditingAlert.accept(()) - }) - .disposed(by: disposeBag) - input.completeButtonDidTap .throttle(.seconds(3), latest: false, scheduler: MainScheduler.instance) .do(onNext: { _ in @@ -239,12 +228,6 @@ final class FeedEditViewModel: ViewModelType { }) .disposed(by: disposeBag) - input.stopEditButtonDidTap - .subscribe(with: self, onNext: { owner, _ in - owner.popViewController.accept(()) - }) - .disposed(by: disposeBag) - return Output(endEditing: endEditing.asObservable(), categoryListData: categoryListData.asObservable(), popViewController: popViewController.asObservable(), @@ -255,8 +238,8 @@ final class FeedEditViewModel: ViewModelType { showPlaceholder: showPlaceholder.asObservable(), presentFeedEditNovelConnectModalViewController: presentFeedEditNovelConnectModalViewController.asObservable(), connectedNovelTitle: connectedNovelTitle.asObservable(), - showAlreadyConnectedToast: showAlreadyConnectedToast.asObservable(), - showStopEditingAlert: showStopEditingAlert.asObservable()) + showAlreadyConnectedToast: showAlreadyConnectedToast.asObservable() + ) } // MARK: - Custom Method diff --git a/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewModel/FeedNovelConnectModalViewModel.swift b/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewModel/FeedNovelConnectModalViewModel.swift index 4ba25ac24..73f8c4b8d 100644 --- a/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewModel/FeedNovelConnectModalViewModel.swift +++ b/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewModel/FeedNovelConnectModalViewModel.swift @@ -38,7 +38,6 @@ final class FeedNovelConnectModalViewModel: ViewModelType { } struct Input { - let closeButtonDidTap: ControlEvent let searchTextUpdated: Observable let searchButtonDidTap: ControlEvent let searchResultCollectionViewReachedBottom: Observable @@ -57,12 +56,6 @@ final class FeedNovelConnectModalViewModel: ViewModelType { } func transform(from input: Input, disposeBag: DisposeBag) -> Output { - input.closeButtonDidTap - .subscribe(with: self, onNext: { owner, _ in - owner.dismissModalViewController.accept(()) - }) - .disposed(by: disposeBag) - input.searchTextUpdated .subscribe(with: self, onNext: { owner, text in owner.searchText = text diff --git a/WSSiOS/WSSiOS/Source/Presentation/NovelDetail/NovelDetailViewController/NovelDetailViewController.swift b/WSSiOS/WSSiOS/Source/Presentation/NovelDetail/NovelDetailViewController/NovelDetailViewController.swift index c6cd049c7..2698619b8 100644 --- a/WSSiOS/WSSiOS/Source/Presentation/NovelDetail/NovelDetailViewController/NovelDetailViewController.swift +++ b/WSSiOS/WSSiOS/Source/Presentation/NovelDetail/NovelDetailViewController/NovelDetailViewController.swift @@ -442,26 +442,12 @@ final class NovelDetailViewController: UIViewController { }) .disposed(by: disposeBag) - output.showFeedEditedToast - .subscribe(with: self, onNext: { owner, _ in - owner.showToast(.feedEdited) - }) - .disposed(by: disposeBag) - output.showWithdrawalUserToastView .observe(on: MainScheduler.instance) .subscribe(with: self, onNext: { owner, _ in owner.showToast(.unknownUser) }) .disposed(by: disposeBag) - - //MARK: - Bind/NovelReview - - output.showNovelReviewedToast - .subscribe(with: self, onNext: { owner, _ in - owner.showToast(.novelReviewed) - }) - .disposed(by: disposeBag) } //MARK: - Actions @@ -483,6 +469,18 @@ final class NovelDetailViewController: UIViewController { owner.popToLastViewController() }) .disposed(by: disposeBag) + + NotificationCenter.default.rx.notification(Notification.Name("FeedEdited")) + .subscribe(with: self, onNext: { owner, _ in + owner.showToast(.feedEdited) + }) + .disposed(by: disposeBag) + + NotificationCenter.default.rx.notification(Notification.Name("NovelReviewed")) + .subscribe(with: self, onNext: { owner, _ in + owner.showToast(.novelReviewed) + }) + .disposed(by: disposeBag) } private func createViewModelInput() -> NovelDetailViewModel.Input { @@ -542,9 +540,7 @@ final class NovelDetailViewController: UIViewController { novelDetailFeedLikeViewDidTap: novelDetailFeedLikeViewDidTap.asObservable(), reloadNovelDetailFeed: reloadNovelDetailFeed.asObservable(), scrollViewReachedBottom: observeReachedBottom(rootView.scrollView), - createFeedButtonDidTap: rootView.createFeedButton.rx.tap, - feedEditedNotification: NotificationCenter.default.rx.notification(Notification.Name("FeedEdited")).asObservable(), - novelReviewedNotification: NotificationCenter.default.rx.notification(Notification.Name("NovelReviewed")).asObservable() + createFeedButtonDidTap: rootView.createFeedButton.rx.tap ) } diff --git a/WSSiOS/WSSiOS/Source/Presentation/NovelDetail/NovelDetailViewModel/NovelDetailViewModel.swift b/WSSiOS/WSSiOS/Source/Presentation/NovelDetail/NovelDetailViewModel/NovelDetailViewModel.swift index c1adfb065..6d257af3c 100644 --- a/WSSiOS/WSSiOS/Source/Presentation/NovelDetail/NovelDetailViewModel/NovelDetailViewModel.swift +++ b/WSSiOS/WSSiOS/Source/Presentation/NovelDetail/NovelDetailViewModel/NovelDetailViewModel.swift @@ -113,10 +113,6 @@ final class NovelDetailViewModel: ViewModelType { let reloadNovelDetailFeed: Observable let scrollViewReachedBottom: Observable let createFeedButtonDidTap: ControlEvent - let feedEditedNotification: Observable - - // NovelReview - let novelReviewedNotification: Observable } struct Output { @@ -158,11 +154,7 @@ final class NovelDetailViewModel: ViewModelType { let showImproperAlertView: Observable<((Int) -> Observable, Int)> let pushToFeedEditViewController: Observable let showDeleteAlertView: Observable<((Int) -> Observable, Int)> - let showFeedEditedToast: Observable let showWithdrawalUserToastView: Observable - - // NovelReview - let showNovelReviewedToast: Observable } func transform(from input: Input, disposeBag: DisposeBag) -> Output { @@ -483,14 +475,6 @@ final class NovelDetailViewModel: ViewModelType { }) .disposed(by: disposeBag) - let showFeedEditedToast = input.feedEditedNotification - .map { _ in () } - .asObservable() - - let showNovelReviewedToast = input.novelReviewedNotification - .map { _ in () } - .asObservable() - input.novelDetailFeedProfileViewDidTap .subscribe(with: self, onNext: { owner, userId in if userId == -1 { @@ -531,9 +515,7 @@ final class NovelDetailViewModel: ViewModelType { showImproperAlertView: showImproperAlertView.asObservable(), pushToFeedEditViewController: pushToFeedEditViewController.asObservable(), showDeleteAlertView: showDeleteAlertView.asObservable(), - showFeedEditedToast: showFeedEditedToast, - showWithdrawalUserToastView: showWithdrawalUserToastView.asObservable(), - showNovelReviewedToast: showNovelReviewedToast + showWithdrawalUserToastView: showWithdrawalUserToastView.asObservable() ) } diff --git a/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewController/NovelDateSelectModalViewController.swift b/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewController/NovelDateSelectModalViewController.swift index f3d4bc667..b2c70af33 100644 --- a/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewController/NovelDateSelectModalViewController.swift +++ b/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewController/NovelDateSelectModalViewController.swift @@ -48,18 +48,16 @@ final class NovelDateSelectModalViewController: UIViewController { super.viewDidLoad() bindViewModel() + bindAction() viewDidLoadEvent.accept(()) } - //MARK: - UI - //MARK: - Bind private func bindViewModel() { let input = NovelDateSelectModalViewModel.Input( viewDidLoadEvent: viewDidLoadEvent.asObservable(), - closeButtonDidTap: rootView.closeButton.rx.tap, startDateButonDidTap: rootView.novelDateSelectModalDateButtonView.startDateButton.rx.tap, endDateButonDidTap: rootView.novelDateSelectModalDateButtonView.endDateButton.rx.tap, datePickerDateDidChanged: rootView.novelDateSelectModalDatePickerView.datePicker.rx.date.changed, @@ -105,4 +103,12 @@ final class NovelDateSelectModalViewController: UIViewController { }) .disposed(by: disposeBag) } + + private func bindAction() { + rootView.closeButton.rx.tap + .subscribe(with: self, onNext: { owner, _ in + owner.dismissModalViewController() + }) + .disposed(by: disposeBag) + } } diff --git a/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewController/NovelReviewViewController.swift b/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewController/NovelReviewViewController.swift index da1ebe061..3753e194e 100644 --- a/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewController/NovelReviewViewController.swift +++ b/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewController/NovelReviewViewController.swift @@ -19,7 +19,6 @@ final class NovelReviewViewController: UIViewController { private let disposeBag = DisposeBag() private let viewDidLoadEvent = PublishRelay() - private let stopReviewingEvent = PublishRelay() //MARK: - Components @@ -47,6 +46,7 @@ final class NovelReviewViewController: UIViewController { register() delegate() bindViewModel() + bindAction() viewDidLoadEvent.accept(()) } @@ -78,7 +78,6 @@ final class NovelReviewViewController: UIViewController { private func bindViewModel() { let input = NovelReviewViewModel.Input( viewDidLoadEvent: viewDidLoadEvent.asObservable(), - backButtonDidTap: rootView.backButton.rx.tap, completeButtonDidTap: rootView.completeButton.rx.tap, statusCollectionViewItemSelected: rootView.novelReviewStatusView.statusCollectionView.rx.itemSelected.asObservable(), dateLabelTapGesture: rootView.novelReviewStatusView.dateLabel.rx.tapGesture() @@ -110,8 +109,7 @@ final class NovelReviewViewController: UIViewController { selectedKeywordCollectionViewItemSelected: rootView.novelReviewKeywordView.selectedKeywordCollectionView.rx.itemSelected.asObservable(), novelReviewKeywordSelectedNotification: NotificationCenter.default.rx.notification(Notification.Name("NovelReviewKeywordSelected")).asObservable(), novelReviewDateSelectedNotification: NotificationCenter.default.rx.notification(Notification.Name("NovelReviewDateSelected")).asObservable(), - novelReviewDateRemovedNotification: NotificationCenter.default.rx.notification(Notification.Name("NovelReviewDateRemoved")).asObservable(), - stopReviewButtonDidTap: stopReviewingEvent.asObservable() + novelReviewDateRemovedNotification: NotificationCenter.default.rx.notification(Notification.Name("NovelReviewDateRemoved")).asObservable() ) let output = self.novelReviewViewModel.transform(from: input, disposeBag: self.disposeBag) @@ -195,8 +193,11 @@ final class NovelReviewViewController: UIViewController { owner.rootView.novelReviewKeywordView.updateCollectionViewHeight(height: height) }) .disposed(by: disposeBag) - - output.showStopReviewingAlert + } + + private func bindAction() { + rootView.backButton.rx.tap + .throttle(.seconds(3), latest: false, scheduler: MainScheduler.instance) .flatMapLatest { _ -> Observable in return self.presentToAlertViewController(iconImage: .icModalWarning, titleText: StringLiterals.NovelReview.Alert.titleText, @@ -207,10 +208,11 @@ final class NovelReviewViewController: UIViewController { } .subscribe(with: self, onNext: { owner, buttonType in if buttonType == .left { - owner.stopReviewingEvent.accept(()) + owner.navigationController?.popViewController(animated: true) } }) .disposed(by: disposeBag) + } } diff --git a/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelDateSelectModalViewModel.swift b/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelDateSelectModalViewModel.swift index 97c15effc..975a4d75a 100644 --- a/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelDateSelectModalViewModel.swift +++ b/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelDateSelectModalViewModel.swift @@ -30,7 +30,6 @@ final class NovelDateSelectModalViewModel: ViewModelType { struct Input { let viewDidLoadEvent: Observable - let closeButtonDidTap: ControlEvent let startDateButonDidTap: ControlEvent let endDateButonDidTap: ControlEvent let datePickerDateDidChanged: ControlEvent @@ -73,12 +72,6 @@ final class NovelDateSelectModalViewModel: ViewModelType { }) .disposed(by: disposeBag) - input.closeButtonDidTap - .subscribe(onNext: { _ in - output.dismissModalViewController.accept(()) - }) - .disposed(by: disposeBag) - input.startDateButonDidTap .subscribe(with: self, onNext: { owner, _ in owner.isStartDateEditing = true diff --git a/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelReviewViewModel.swift b/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelReviewViewModel.swift index 2616128e1..670cefc9b 100644 --- a/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelReviewViewModel.swift +++ b/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelReviewViewModel.swift @@ -49,7 +49,6 @@ final class NovelReviewViewModel: ViewModelType { private let presentNovelKeywordSelectModalViewController = PublishRelay<[KeywordData]>() let selectedKeywordListData = BehaviorRelay<[KeywordData]>(value: []) private let selectedKeywordCollectionViewHeight = BehaviorRelay(value: 0) - private let showStopReviewingAlert = PublishRelay() //MARK: - Life Cycle @@ -63,7 +62,6 @@ final class NovelReviewViewModel: ViewModelType { struct Input { let viewDidLoadEvent: Observable - let backButtonDidTap: ControlEvent let completeButtonDidTap: ControlEvent let statusCollectionViewItemSelected: Observable let dateLabelTapGesture: Observable @@ -77,7 +75,6 @@ final class NovelReviewViewModel: ViewModelType { let novelReviewKeywordSelectedNotification: Observable let novelReviewDateSelectedNotification: Observable let novelReviewDateRemovedNotification: Observable - let stopReviewButtonDidTap: Observable } struct Output { @@ -92,7 +89,6 @@ final class NovelReviewViewModel: ViewModelType { let presentNovelKeywordSelectModalViewController: Observable<[KeywordData]> let selectedKeywordListData: Observable<[KeywordData]> let selectedKeywordCollectionViewHeight: Observable - let showStopReviewingAlert: Observable } func transform(from input: Input, disposeBag: DisposeBag) -> Output { @@ -115,13 +111,6 @@ final class NovelReviewViewModel: ViewModelType { }) .disposed(by: disposeBag) - input.backButtonDidTap - .throttle(.seconds(3), latest: false, scheduler: MainScheduler.instance) - .subscribe(with: self, onNext: { owner, _ in - owner.showStopReviewingAlert.accept(()) - }) - .disposed(by: disposeBag) - input.completeButtonDidTap .throttle(.seconds(3), latest: false, scheduler: MainScheduler.instance) .flatMapLatest { @@ -263,12 +252,6 @@ final class NovelReviewViewModel: ViewModelType { }) .disposed(by: disposeBag) - input.stopReviewButtonDidTap - .subscribe(with: self, onNext: { owner, _ in - owner.popViewController.accept(()) - }) - .disposed(by: disposeBag) - return Output(popViewController: popViewController.asObservable(), readStatusListData: readStatusListData.asObservable(), readStatusData: readStatusData.asObservable(), @@ -279,8 +262,8 @@ final class NovelReviewViewModel: ViewModelType { isAttractivePointCountOverLimit: isAttractivePointCountOverLimit.asObservable(), presentNovelKeywordSelectModalViewController: presentNovelKeywordSelectModalViewController.asObservable(), selectedKeywordListData: selectedKeywordListData.asObservable(), - selectedKeywordCollectionViewHeight: selectedKeywordCollectionViewHeight.asObservable(), - showStopReviewingAlert: showStopReviewingAlert.asObservable()) + selectedKeywordCollectionViewHeight: selectedKeywordCollectionViewHeight.asObservable() + ) } //MARK: - API From 3242018b26dd6f7b3885c5057973c77957a0ccd4 Mon Sep 17 00:00:00 2001 From: Hyowon Jeon Date: Sat, 19 Apr 2025 16:53:10 +0900 Subject: [PATCH 7/7] =?UTF-8?q?[Fix]=20#510=20-=20=EA=B5=AC=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=20=EC=BD=94=EB=A6=AC=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Data/DTO/{AuthDTO.swift => Auth.swift} | 2 +- .../Data/Entity/NovelReviewEntity.swift | 31 ++++++++++++------- .../FeedEditViewController.swift | 4 +-- .../NovelReviewViewController.swift | 6 ++-- .../NovelReviewViewModel.swift | 10 +++--- 5 files changed, 30 insertions(+), 23 deletions(-) rename WSSiOS/WSSiOS/Source/Data/DTO/{AuthDTO.swift => Auth.swift} (96%) diff --git a/WSSiOS/WSSiOS/Source/Data/DTO/AuthDTO.swift b/WSSiOS/WSSiOS/Source/Data/DTO/Auth.swift similarity index 96% rename from WSSiOS/WSSiOS/Source/Data/DTO/AuthDTO.swift rename to WSSiOS/WSSiOS/Source/Data/DTO/Auth.swift index 43bac18dc..b309a99a6 100644 --- a/WSSiOS/WSSiOS/Source/Data/DTO/AuthDTO.swift +++ b/WSSiOS/WSSiOS/Source/Data/DTO/Auth.swift @@ -1,5 +1,5 @@ // -// AuthResult.swift +// Auth.swift // WSSiOS // // Created by Hyowon Jeon on 11/2/24. diff --git a/WSSiOS/WSSiOS/Source/Data/Entity/NovelReviewEntity.swift b/WSSiOS/WSSiOS/Source/Data/Entity/NovelReviewEntity.swift index eef9a9edd..911633a73 100644 --- a/WSSiOS/WSSiOS/Source/Data/Entity/NovelReviewEntity.swift +++ b/WSSiOS/WSSiOS/Source/Data/Entity/NovelReviewEntity.swift @@ -9,11 +9,11 @@ import Foundation struct NovelReviewEntity { let novelTitle: String - let status: String? + let status: ReadStatus? let startDate: Date? let endDate: Date? let userNovelRating: Float - let attractivePoints: [String] + let attractivePoints: [AttractivePoint?] let keywords: [KeywordData] } @@ -26,12 +26,15 @@ extension NovelReviewResponse { let startDate = self.startDate.flatMap { dateFormatter.date(from: $0) } let endDate = self.endDate.flatMap { dateFormatter.date(from: $0) } + let readStatus = self.status.flatMap { ReadStatus(rawValue: $0) } + let attractivePoints = self.attractivePoints.map { AttractivePoint(rawValue: $0) } + return NovelReviewEntity(novelTitle: self.novelTitle, - status: self.status, + status: readStatus, startDate: startDate, endDate: endDate, userNovelRating: self.userNovelRating, - attractivePoints: self.attractivePoints, + attractivePoints: attractivePoints, keywords: self.keywords) } } @@ -39,41 +42,45 @@ extension NovelReviewResponse { struct PostNovelReviewEntity { let novelId: Int let userNovelRating: Float - let status: String + let status: ReadStatus let startDate: String? let endDate: String? - let attractivePoints: [String] + let attractivePoints: [AttractivePoint?] let keywordIds: [Int] } extension PostNovelReviewEntity { func toDTO() -> PostNovelReviewRequest { + let statusString = self.status.rawValue + let attractivePoints = self.attractivePoints.compactMap { $0?.rawValue } return PostNovelReviewRequest(novelId: self.novelId, userNovelRating: self.userNovelRating, - status: self.status, + status: statusString, startDate: self.startDate, endDate: self.endDate, - attractivePoints: self.attractivePoints, + attractivePoints: attractivePoints, keywordIds: self.keywordIds) } } struct PutNovelReviewEntity { let userNovelRating: Float - let status: String + let status: ReadStatus let startDate: String? let endDate: String? - let attractivePoints: [String] + let attractivePoints: [AttractivePoint?] let keywordIds: [Int] } extension PutNovelReviewEntity { func toDTO() -> PutNovelReviewRequest { + let statusString = self.status.rawValue + let attractivePoints = self.attractivePoints.compactMap { $0?.rawValue } return PutNovelReviewRequest(userNovelRating: self.userNovelRating, - status: self.status, + status: statusString, startDate: self.startDate, endDate: self.endDate, - attractivePoints: self.attractivePoints, + attractivePoints: attractivePoints, keywordIds: self.keywordIds) } } diff --git a/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewController/FeedEditViewController.swift b/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewController/FeedEditViewController.swift index a5f10261d..2217cf69c 100644 --- a/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewController/FeedEditViewController.swift +++ b/WSSiOS/WSSiOS/Source/Presentation/FeedEdit/FeedEditViewController/FeedEditViewController.swift @@ -141,7 +141,7 @@ final class FeedEditViewController: UIViewController { output.popViewController .subscribe(with: self, onNext: { owner, _ in - owner.navigationController?.popViewController(animated: true) + owner.popToLastViewController() }) .disposed(by: disposeBag) @@ -207,7 +207,7 @@ final class FeedEditViewController: UIViewController { } .subscribe(with: self, onNext: { owner, buttonType in if buttonType == .left { - owner.navigationController?.popViewController(animated: true) + owner.popToLastViewController() } }) .disposed(by: disposeBag) diff --git a/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewController/NovelReviewViewController.swift b/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewController/NovelReviewViewController.swift index 3753e194e..6eb4ba7b4 100644 --- a/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewController/NovelReviewViewController.swift +++ b/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewController/NovelReviewViewController.swift @@ -116,7 +116,7 @@ final class NovelReviewViewController: UIViewController { output.popViewController .subscribe(with: self, onNext: { owner, _ in - owner.navigationController?.popViewController(animated: true) + owner.popToLastViewController() }) .disposed(by: disposeBag) @@ -160,7 +160,7 @@ final class NovelReviewViewController: UIViewController { .bind(to: rootView.novelReviewAttractivePointView.attractivePointCollectionView.rx.items(cellIdentifier: NovelReviewAttractivePointCollectionViewCell.cellIdentifier, cellType: NovelReviewAttractivePointCollectionViewCell.self)) { item, element, cell in let indexPath = IndexPath(item: item, section: 0) - if self.novelReviewViewModel.selectedAttractivePointList.contains(element.rawValue) { + if self.novelReviewViewModel.selectedAttractivePointList.contains(element) { self.rootView.novelReviewAttractivePointView.attractivePointCollectionView.selectItem(at: indexPath, animated: false, scrollPosition: []) } else { self.rootView.novelReviewAttractivePointView.attractivePointCollectionView.deselectItem(at: indexPath, animated: false) @@ -208,7 +208,7 @@ final class NovelReviewViewController: UIViewController { } .subscribe(with: self, onNext: { owner, buttonType in if buttonType == .left { - owner.navigationController?.popViewController(animated: true) + owner.popToLastViewController() } }) .disposed(by: disposeBag) diff --git a/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelReviewViewModel.swift b/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelReviewViewModel.swift index 670cefc9b..154d3dfd2 100644 --- a/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelReviewViewModel.swift +++ b/WSSiOS/WSSiOS/Source/Presentation/NovelReview/NovelReviewViewModel/NovelReviewViewModel.swift @@ -26,7 +26,7 @@ final class NovelReviewViewModel: ViewModelType { private var startDate: Date? private var endDate: Date? - var selectedAttractivePointList: [String] = [] + var selectedAttractivePointList: [AttractivePoint?] = [] private let minStarRating: Float = 0.0 private let maxStarRating: Float = 5.0 @@ -123,7 +123,7 @@ final class NovelReviewViewModel: ViewModelType { if self.isNovelReviewExist { let novelReviewData = PutNovelReviewEntity( userNovelRating: self.starRating.value, - status: self.readStatus.rawValue, + status: self.readStatus, startDate: startDateString, endDate: endDateString, attractivePoints: self.selectedAttractivePointList, @@ -138,7 +138,7 @@ final class NovelReviewViewModel: ViewModelType { let novelReviewData = PostNovelReviewEntity( novelId: self.novelId, userNovelRating: self.starRating.value, - status: self.readStatus.rawValue, + status: self.readStatus, startDate: startDateString, endDate: endDateString, attractivePoints: self.selectedAttractivePointList, @@ -197,14 +197,14 @@ final class NovelReviewViewModel: ViewModelType { if owner.selectedAttractivePointList.count >= owner.attractivePointLimit { owner.isAttractivePointCountOverLimit.accept(indexPath) } else { - owner.selectedAttractivePointList.append(AttractivePoint.allCases[indexPath.item].rawValue) + owner.selectedAttractivePointList.append(AttractivePoint.allCases[indexPath.item]) } }) .disposed(by: disposeBag) input.attractivePointCollectionViewItemDeselected .subscribe(with: self, onNext: { owner, indexPath in - owner.selectedAttractivePointList.removeAll { $0 == AttractivePoint.allCases[indexPath.item].rawValue } + owner.selectedAttractivePointList.removeAll { $0 == AttractivePoint.allCases[indexPath.item] } }) .disposed(by: disposeBag)