diff --git a/LionHeart-iOS/LionHeart-iOS.xcodeproj/project.pbxproj b/LionHeart-iOS/LionHeart-iOS.xcodeproj/project.pbxproj index 3e9c32b6..10f9f422 100644 --- a/LionHeart-iOS/LionHeart-iOS.xcodeproj/project.pbxproj +++ b/LionHeart-iOS/LionHeart-iOS.xcodeproj/project.pbxproj @@ -17,6 +17,7 @@ 4A8980CE2A617F7100746C58 /* CollectionHeaderViewRegisterDequeueProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A8980CD2A617F7100746C58 /* CollectionHeaderViewRegisterDequeueProtocol.swift */; }; 4A8980D02A61850500746C58 /* MyPageAppSettingCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A8980CF2A61850500746C58 /* MyPageAppSettingCollectionViewCell.swift */; }; 4AD216402A69AC1E00C9F2F2 /* MyPageResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AD2163F2A69AC1E00C9F2F2 /* MyPageResponse.swift */; }; + 4AD6A34C2AB1AB6700977224 /* BookmarkAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AD6A34B2AB1AB6700977224 /* BookmarkAPI.swift */; }; 4AD6AE1A2A68436B00A3D745 /* ArticleListByCategoryResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AD6AE192A68436B00A3D745 /* ArticleListByCategoryResponse.swift */; }; 4AE19A172A65864F00C1DB7E /* BookmarkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AE19A162A65864F00C1DB7E /* BookmarkService.swift */; }; 4AE19A1A2A65886100C1DB7E /* BookmarkReponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AE19A192A65886100C1DB7E /* BookmarkReponse.swift */; }; @@ -231,6 +232,7 @@ 4A8980CD2A617F7100746C58 /* CollectionHeaderViewRegisterDequeueProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionHeaderViewRegisterDequeueProtocol.swift; sourceTree = ""; }; 4A8980CF2A61850500746C58 /* MyPageAppSettingCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyPageAppSettingCollectionViewCell.swift; sourceTree = ""; }; 4AD2163F2A69AC1E00C9F2F2 /* MyPageResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyPageResponse.swift; sourceTree = ""; }; + 4AD6A34B2AB1AB6700977224 /* BookmarkAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkAPI.swift; sourceTree = ""; }; 4AD6AE032A66F83E00A3D745 /* progressbar_2m.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = progressbar_2m.json; sourceTree = ""; }; 4AD6AE052A66F84300A3D745 /* progressbar_3m.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = progressbar_3m.json; sourceTree = ""; }; 4AD6AE072A66F84C00A3D745 /* progressbar_4m.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = progressbar_4m.json; sourceTree = ""; }; @@ -1251,6 +1253,7 @@ children = ( C0903D012AAAD86A0014786F /* AuthAPI.swift */, C004D4982AAD8F880087F044 /* MyPageAPI.swift */, + 4AD6A34B2AB1AB6700977224 /* BookmarkAPI.swift */, ); path = API; sourceTree = ""; @@ -1630,6 +1633,7 @@ C0DF03352A5A93530037F740 /* UIControl+.swift in Sources */, C0F029E22A5FAE2700E0D185 /* LHOnboardingErrorLabel.swift in Sources */, B57BEB702A6275F500D1727C /* ViewControllerServiceable.swift in Sources */, + 4AD6A34C2AB1AB6700977224 /* BookmarkAPI.swift in Sources */, C0DF032F2A5A92170037F740 /* NameSpace.swift in Sources */, B59893192A5D41F600CE1FEB /* KingfisherService.swift in Sources */, B59892EE2A5B9AF300CE1FEB /* NavigationBarLayoutManager.swift in Sources */, diff --git a/LionHeart-iOS/LionHeart-iOS/Global/Extensions/UIViewController+.swift b/LionHeart-iOS/LionHeart-iOS/Global/Extensions/UIViewController+.swift index 9347781e..68dc9806 100644 --- a/LionHeart-iOS/LionHeart-iOS/Global/Extensions/UIViewController+.swift +++ b/LionHeart-iOS/LionHeart-iOS/Global/Extensions/UIViewController+.swift @@ -89,7 +89,7 @@ extension UIViewController { extension UIViewController { func presentArticleDetailFullScreen(articleID: Int) { - let articleDetailViewController = ArticleDetailViewController() + let articleDetailViewController = ArticleDetailViewController(serviceProtocol: BookmarkService(bookmarkAPIProtocol: BookmarkAPI(apiService: APIService()))) articleDetailViewController.setArticleId(id: articleID) articleDetailViewController.isModalInPresentation = true articleDetailViewController.modalPresentationStyle = .fullScreen diff --git a/LionHeart-iOS/LionHeart-iOS/Network/API/BookmarkAPI.swift b/LionHeart-iOS/LionHeart-iOS/Network/API/BookmarkAPI.swift new file mode 100644 index 00000000..8823c42b --- /dev/null +++ b/LionHeart-iOS/LionHeart-iOS/Network/API/BookmarkAPI.swift @@ -0,0 +1,47 @@ +// +// BookmarkAPI.swift +// LionHeart-iOS +// +// Created by 황찬미 on 2023/09/13. +// + +import Foundation + +protocol BookmarkAPIProtocol { + func getBookmark() async throws -> BookmarkResponse? + func postBookmark(model: BookmarkRequest) async throws -> BookmarkResponse? +} + +final class BookmarkAPI: BookmarkAPIProtocol { + + private let apiService: Requestable + + init(apiService: Requestable) { + self.apiService = apiService + } + + func getBookmark() async throws -> BookmarkResponse? { + let request = try makeGetBookmarkUrlRequest() + return try await apiService.request(request) + } + + func postBookmark(model: BookmarkRequest) async throws -> BookmarkResponse? { + let request = try makePostBookmakrUrlRequest(model: model) + return try await apiService.request(request) + } +} + + +/// url request method +extension BookmarkAPI { + func makeGetBookmarkUrlRequest() throws -> URLRequest { + return try NetworkRequest(path: "/v1/article/bookmarks", httpMethod: .get).makeURLRequest(isLogined: true) + } + + func makePostBookmakrUrlRequest(model: BookmarkRequest) throws -> URLRequest { + let param = model.toDictionary() + let body = try JSONSerialization.data(withJSONObject: param) + + return try NetworkRequest(path: "/v1/article/bookmark", httpMethod: .post, body: body).makeURLRequest(isLogined: true) + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/DTO/Bookmark/Response/BookmarkReponse.swift b/LionHeart-iOS/LionHeart-iOS/Network/DTO/Bookmark/Response/BookmarkReponse.swift index 7857d0bc..bcf74e9c 100644 --- a/LionHeart-iOS/LionHeart-iOS/Network/DTO/Bookmark/Response/BookmarkReponse.swift +++ b/LionHeart-iOS/LionHeart-iOS/Network/DTO/Bookmark/Response/BookmarkReponse.swift @@ -19,3 +19,15 @@ struct ArticleSummaryDTO: DTO, Response { let isMarked: Bool let tags: [String] } + +extension BookmarkResponse { + func toAppData() -> BookmarkAppData { + return BookmarkAppData(nickName: self.babyNickname, + articleSummaries: self.articleSummaries.map { ArticleSummaries(title: $0.title, + articleID: $0.articleId, + articleImage: $0.mainImageUrl, + bookmarked: $0.isMarked, + tags: $0.tags) + }) + } +} diff --git a/LionHeart-iOS/LionHeart-iOS/Network/Services/BookmarkService.swift b/LionHeart-iOS/LionHeart-iOS/Network/Services/BookmarkService.swift index 8ae9da90..7817f5d5 100644 --- a/LionHeart-iOS/LionHeart-iOS/Network/Services/BookmarkService.swift +++ b/LionHeart-iOS/LionHeart-iOS/Network/Services/BookmarkService.swift @@ -7,33 +7,32 @@ import Foundation -final class BookmarkService: Serviceable { - static let shared = BookmarkService() - private init() {} +/// 내 북마크 +protocol BookmarkInOutServiceProtocol { + func postBookmark(model: BookmarkRequest) async throws + func getBookmark() async throws -> BookmarkAppData +} + +// 동뷰, 성뷰 +protocol BookmarkOutProtocol { + func postBookmark(model: BookmarkRequest) async throws +} + +final class BookmarkService: BookmarkInOutServiceProtocol, BookmarkOutProtocol { - func getBookmark() async throws -> BookmarkAppData { - let urlRequest = try NetworkRequest(path: "/v1/article/bookmarks", httpMethod: .get) - .makeURLRequest(isLogined: true) - - let (data, _) = try await URLSession.shared.data(for: urlRequest) - - let model = try dataDecodeAndhandleErrorCode(data: data, decodeType: BookmarkResponse.self) - - return BookmarkAppData(nickName: model?.babyNickname ?? "", - articleSummaries: model?.articleSummaries.map { - ArticleSummaries(title: $0.title, articleID: $0.articleId, articleImage: $0.mainImageUrl, - bookmarked: $0.isMarked, tags: $0.tags)} ?? []) + private let bookmarkAPIProtocol: BookmarkAPIProtocol + + init(bookmarkAPIProtocol: BookmarkAPIProtocol) { + self.bookmarkAPIProtocol = bookmarkAPIProtocol + } + + func postBookmark(model: BookmarkRequest) async throws { + guard let data = try await bookmarkAPIProtocol.postBookmark(model: model) else { return } + print(data) } - func postBookmark(_ model: BookmarkRequest) async throws { - let param = model.toDictionary() - let body = try JSONSerialization.data(withJSONObject: param) - - let urlRequest = try NetworkRequest(path: "/v1/article/bookmark", httpMethod: .post, body: body).makeURLRequest(isLogined: true) - - let (data, _) = try await URLSession.shared.data(for: urlRequest) - try dataDecodeAndhandleErrorCode(data: data, decodeType: String.self) - - return + func getBookmark() async throws -> BookmarkAppData { + guard let data = try await bookmarkAPIProtocol.getBookmark() else { return BookmarkAppData(nickName: "", articleSummaries: [])} + return data.toAppData() } } diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleCategory/ViewControllers/ArticleCategoryViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleCategory/ViewControllers/ArticleCategoryViewController.swift index c34e9b51..0e23f331 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleCategory/ViewControllers/ArticleCategoryViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleCategory/ViewControllers/ArticleCategoryViewController.swift @@ -6,8 +6,6 @@ // Copyright (c) 2023 ArticleCategory. All rights reserved. // - - import UIKit import SnapKit @@ -99,7 +97,7 @@ private extension ArticleCategoryViewController { func setAddTarget() { navigationBar.rightFirstBarItemAction { - let bookmarkViewController = BookmarkViewController() + let bookmarkViewController = BookmarkViewController(serviceProtocol: BookmarkService(bookmarkAPIProtocol: BookmarkAPI(apiService: APIService()))) self.navigationController?.pushViewController(bookmarkViewController, animated: true) } @@ -136,7 +134,7 @@ extension ArticleCategoryViewController: UICollectionViewDataSource { } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - let ArticleListByCategoryVC = ArticleListByCategoryViewController() + let ArticleListByCategoryVC = ArticleListByCategoryViewController(serviceProcotol: BookmarkService(bookmarkAPIProtocol: BookmarkAPI(apiService: APIService()))) ArticleListByCategoryVC.categoryString = dummyCase[indexPath.item].categoryString self.navigationController?.pushViewController(ArticleListByCategoryVC, animated: true) } diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleDetail/ViewControllers/ArticleDetailViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleDetail/ViewControllers/ArticleDetailViewController.swift index 0331c1ae..1d63310b 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleDetail/ViewControllers/ArticleDetailViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleDetail/ViewControllers/ArticleDetailViewController.swift @@ -13,6 +13,9 @@ import SnapKit final class ArticleDetailViewController: UIViewController { // MARK: - UI Components + + private let serviceProtocol: BookmarkOutProtocol + private lazy var navigationBar = LHNavigationBarView(type: .articleMain, viewController: self) private var progressBar = LHProgressView() @@ -30,7 +33,17 @@ final class ArticleDetailViewController: UIViewController { button.isHidden = true return button }() - + + init(serviceProtocol: BookmarkOutProtocol) { + self.serviceProtocol = serviceProtocol + /// 이 코드는 왜 있어야 하지? + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + // MARK: - Properties private var isBookMarked: Bool? { @@ -93,7 +106,7 @@ extension ArticleDetailViewController { Task { do { let bookmarkRequest = BookmarkRequest(articleId: articleId, bookmarkRequestStatus: isSelected) - try await BookmarkService.shared.postBookmark(bookmarkRequest) + try await serviceProtocol.postBookmark(model: bookmarkRequest) isBookMarked = isSelected } catch { diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleListByCategory/ViewControllers/ArticleListByCategoryViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleListByCategory/ViewControllers/ArticleListByCategoryViewController.swift index 97189a43..17b87682 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleListByCategory/ViewControllers/ArticleListByCategoryViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Article/ArticleListByCategory/ViewControllers/ArticleListByCategoryViewController.swift @@ -9,9 +9,10 @@ import UIKit import SnapKit - final class ArticleListByCategoryViewController: UIViewController { + private let serviceProcotol: BookmarkOutProtocol + var categoryString = String() var articleListData: [ArticleDataByWeek] = [] { didSet { @@ -35,6 +36,16 @@ final class ArticleListByCategoryViewController: UIViewController { return tableView }() + init(serviceProcotol: BookmarkOutProtocol) { + self.serviceProcotol = serviceProcotol + + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + public override func viewDidLoad() { super.viewDidLoad() setUI() @@ -149,7 +160,7 @@ extension ArticleListByCategoryViewController: UITableViewDataSource { Task { do { - try await BookmarkService.shared.postBookmark(BookmarkRequest(articleId: self.articleListData[indexPath.row].articleId, + try await self.serviceProcotol.postBookmark(model: BookmarkRequest(articleId: self.articleListData[indexPath.row].articleId, bookmarkRequestStatus: isSelected)) print(self.articleListData[indexPath.row].articleId) isSelected ? LHToast.show(message: "북마크에 추가되었습니다", isTabBar: true) : LHToast.show(message: "북마크에 해제되었습니다", isTabBar: true) diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/BookMark/ViewControllers/BookmarkViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/BookMark/ViewControllers/BookmarkViewController.swift index 40c1378b..a23a25b3 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/BookMark/ViewControllers/BookmarkViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/BookMark/ViewControllers/BookmarkViewController.swift @@ -12,6 +12,8 @@ import SnapKit final class BookmarkViewController: UIViewController { + private let serviceProtocol: BookmarkInOutServiceProtocol + private var bookmarkAppData = BookmarkAppData(nickName: "", articleSummaries: [ArticleSummaries]()) private var bookmarkList = [ArticleSummaries]() @@ -23,7 +25,17 @@ final class BookmarkViewController: UIViewController { collectionView.showsVerticalScrollIndicator = false return collectionView }() + + init(serviceProtocol: BookmarkInOutServiceProtocol) { + self.serviceProtocol = serviceProtocol + + super.init(nibName: nil, bundle: nil) + } + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + public override func viewDidLoad() { super.viewDidLoad() setUI() @@ -39,7 +51,7 @@ final class BookmarkViewController: UIViewController { showLoading() Task { do { - self.bookmarkAppData = try await BookmarkService.shared.getBookmark() + self.bookmarkAppData = try await serviceProtocol.getBookmark() self.bookmarkList = bookmarkAppData.articleSummaries hideLoading() bookmarkCollectionView.reloadData() @@ -146,11 +158,12 @@ extension BookmarkViewController: UICollectionViewDataSource { cell.bookmarkButtonClosure = { indexPath in Task { do { - try await BookmarkService.shared.postBookmark(BookmarkRequest(articleId: self.bookmarkList[indexPath.item].articleID, - bookmarkRequestStatus: !self.bookmarkList[indexPath.item].bookmarked)) + try await self.serviceProtocol.postBookmark(model: BookmarkRequest(articleId: self.bookmarkList[indexPath.item].articleID, + bookmarkRequestStatus: !self.bookmarkList[indexPath.item].bookmarked)) self.bookmarkList.remove(at: indexPath.item) collectionView.deleteItems(at: [indexPath]) LHToast.show(message: "북마크가 해제되었습니다") + } catch { guard let error = error as? NetworkError else { return } self.handleError(error) diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Challenge/ViewController/ChallengeViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Challenge/ViewController/ChallengeViewController.swift index dd999e0c..d5516f30 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Challenge/ViewController/ChallengeViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Challenge/ViewController/ChallengeViewController.swift @@ -249,7 +249,7 @@ private extension ChallengeViewController { func setAddTarget() { navigationBar.rightFirstBarItemAction { - let bookmarkViewController = BookmarkViewController() + let bookmarkViewController = BookmarkViewController(serviceProtocol: BookmarkService(bookmarkAPIProtocol: BookmarkAPI(apiService: APIService()))) self.navigationController?.pushViewController(bookmarkViewController, animated: true) } diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumListByWeekViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumListByWeekViewController.swift index 2f9713ac..14ecdb85 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumListByWeekViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumListByWeekViewController.swift @@ -11,6 +11,18 @@ import UIKit import SnapKit final class CurriculumListByWeekViewController: UIViewController { + + private let serviceProtocol: BookmarkOutProtocol + + init(serviceProtocol: BookmarkOutProtocol) { + self.serviceProtocol = serviceProtocol + /// 이 코드는 왜 있어야 하지? + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } private let pregnancy = 37 @@ -166,9 +178,10 @@ private extension CurriculumListByWeekViewController { print(indexPath) print(buttonSelected) - try await BookmarkService.shared.postBookmark( - BookmarkRequest(articleId: listByWeekDatas.articleData[indexPath].articleId, - bookmarkRequestStatus: buttonSelected)) + + try await + serviceProtocol.postBookmark(model: BookmarkRequest(articleId: listByWeekDatas.articleData[indexPath].articleId, + bookmarkRequestStatus: buttonSelected)) hideLoading() buttonSelected ? LHToast.show(message: "북마크가 추가되었습니다", isTabBar: true) : LHToast.show(message: "북마크가 해제되었습니다", isTabBar: true) } catch { diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumViewController.swift index 57479247..8b1a1627 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumViewController.swift @@ -166,7 +166,7 @@ private extension CurriculumViewController { func setAddTarget() { navigationBar.rightFirstBarItemAction { - let bookmarkViewController = BookmarkViewController() + let bookmarkViewController = BookmarkViewController(serviceProtocol: BookmarkService(bookmarkAPIProtocol: BookmarkAPI(apiService: APIService()))) self.navigationController?.pushViewController(bookmarkViewController, animated: true) } @@ -268,7 +268,7 @@ extension CurriculumViewController: UITableViewDataSource { } - let listByWeekVC = CurriculumListByWeekViewController() + let listByWeekVC = CurriculumListByWeekViewController(serviceProtocol: BookmarkService(bookmarkAPIProtocol: BookmarkAPI(apiService: APIService()))) listByWeekVC.weekToIndexPathItem = (indexPath.section * 4) + indexPath.row self.navigationController?.pushViewController(listByWeekVC, animated: true) diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Today/ViewControllers/TodayViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Today/ViewControllers/TodayViewController.swift index a029e823..97ba1eac 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Today/ViewControllers/TodayViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Today/ViewControllers/TodayViewController.swift @@ -125,7 +125,7 @@ private extension TodayViewController { func setButtonAction() { todayNavigationBar.rightFirstBarItemAction { - let bookmarkViewController = BookmarkViewController() + let bookmarkViewController = BookmarkViewController(serviceProtocol: BookmarkService(bookmarkAPIProtocol: BookmarkAPI(apiService: APIService()))) self.navigationController?.pushViewController(bookmarkViewController, animated: true) }