From a9721d492073e1a8ca9626b10c46c800a6bd73c5 Mon Sep 17 00:00:00 2001 From: Jeon Seoung Hun Date: Wed, 11 Oct 2023 17:28:05 +0900 Subject: [PATCH 1/4] =?UTF-8?q?[feat]:=20Realm=20DB=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=20&=20marker=20manager=20=EC=83=9D=EC=84=B1=20(fetch=20data?= =?UTF-8?q?=EB=A7=8C=20=EA=B5=AC=ED=98=84)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .swiftlint.yml | 1 + AVIRO.xcodeproj/project.pbxproj | 14 ++-- AVIRO/Custom/Constants/Enum+.swift | 1 + .../FacadeManager/MarkerModelManager.swift | 72 ++++++++++++++++ AVIRO/Model/HomeViewModel/MarkerModel.swift | 5 +- .../Model/LocalDataModel/LocalDBMarker.swift | 50 +++++++++++ ...arkerData.swift => MarkerModelCache.swift} | 6 +- .../Presenter/Home/HomeViewPresenter.swift | 82 +++++++++++-------- .../Mypage/MyPageViewPresenter.swift | 4 +- .../Mypage/NickNameChangeblePresenter.swift | 4 +- README.md | 1 + 11 files changed, 193 insertions(+), 47 deletions(-) create mode 100644 AVIRO/Model/LocalDataModel/LocalDBMarker.swift rename AVIRO/Model/LocalDataModel/{LocalMarkerData.swift => MarkerModelCache.swift} (97%) diff --git a/.swiftlint.yml b/.swiftlint.yml index 605da661..8fa1aaf0 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -1,6 +1,7 @@ disabled_rules: - trailing_whitespace - identifier_name +- force_try function_parameter_count: - 8 diff --git a/AVIRO.xcodeproj/project.pbxproj b/AVIRO.xcodeproj/project.pbxproj index b6d50cca..3940faeb 100644 --- a/AVIRO.xcodeproj/project.pbxproj +++ b/AVIRO.xcodeproj/project.pbxproj @@ -58,7 +58,7 @@ C51AED1F2A8B2BC80015FBC2 /* HomeTopButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C51AED1E2A8B2BC80015FBC2 /* HomeTopButton.swift */; }; C51AED212A8B2BDB0015FBC2 /* HomeMapReferButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C51AED202A8B2BDB0015FBC2 /* HomeMapReferButton.swift */; }; C51AED232A8B7B000015FBC2 /* UIViewController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C51AED222A8B7B000015FBC2 /* UIViewController+Extension.swift */; }; - C51B09B82A82155200916BBD /* LocalMarkerData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C51B09B72A82155200916BBD /* LocalMarkerData.swift */; }; + C51B09B82A82155200916BBD /* MarkerModelCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = C51B09B72A82155200916BBD /* MarkerModelCache.swift */; }; C51B09BA2A8215D800916BBD /* MarkerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C51B09B92A8215D800916BBD /* MarkerModel.swift */; }; C51B09BC2A82397800916BBD /* Marker+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C51B09BB2A82397800916BBD /* Marker+Extension.swift */; }; C51BBAD52A78D53D00BF5B7C /* AVIROCheckPlace+DTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C51BBAD42A78D53D00BF5B7C /* AVIROCheckPlace+DTO.swift */; }; @@ -93,6 +93,7 @@ C5351B7A2A1B439000116D50 /* KakaoCoordinateSearchDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5351B792A1B439000116D50 /* KakaoCoordinateSearchDTO.swift */; }; C53856B12ABC13ED00D52DEC /* AVIROMyContributionCount+DTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C53856B02ABC13ED00D52DEC /* AVIROMyContributionCount+DTO.swift */; }; C53893162A5EC0C500CB9A54 /* GenderButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C53893152A5EC0C500CB9A54 /* GenderButton.swift */; }; + C53C54D22AD67E8800C3662A /* LocalDBMarker.swift in Sources */ = {isa = PBXBuildFile; fileRef = C53C54D12AD67E8800C3662A /* LocalDBMarker.swift */; }; C541521D2AC125E100F39826 /* TutorialTopLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C541521C2AC125E100F39826 /* TutorialTopLabel.swift */; }; C54657882ABF2DBA003A0BCB /* API.plist in Resources */ = {isa = PBXBuildFile; fileRef = C54657872ABF2DBA003A0BCB /* API.plist */; }; C547A8BA2A17D8D4004D1339 /* KakaoAPIManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C547A8B92A17D8D4004D1339 /* KakaoAPIManager.swift */; }; @@ -261,7 +262,7 @@ C51AED1E2A8B2BC80015FBC2 /* HomeTopButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTopButton.swift; sourceTree = ""; }; C51AED202A8B2BDB0015FBC2 /* HomeMapReferButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeMapReferButton.swift; sourceTree = ""; }; C51AED222A8B7B000015FBC2 /* UIViewController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Extension.swift"; sourceTree = ""; }; - C51B09B72A82155200916BBD /* LocalMarkerData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalMarkerData.swift; sourceTree = ""; }; + C51B09B72A82155200916BBD /* MarkerModelCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkerModelCache.swift; sourceTree = ""; }; C51B09B92A8215D800916BBD /* MarkerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkerModel.swift; sourceTree = ""; }; C51B09BB2A82397800916BBD /* Marker+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Marker+Extension.swift"; sourceTree = ""; }; C51BBAD42A78D53D00BF5B7C /* AVIROCheckPlace+DTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AVIROCheckPlace+DTO.swift"; sourceTree = ""; }; @@ -298,6 +299,7 @@ C5351B792A1B439000116D50 /* KakaoCoordinateSearchDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KakaoCoordinateSearchDTO.swift; sourceTree = ""; }; C53856B02ABC13ED00D52DEC /* AVIROMyContributionCount+DTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AVIROMyContributionCount+DTO.swift"; sourceTree = ""; }; C53893152A5EC0C500CB9A54 /* GenderButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenderButton.swift; sourceTree = ""; }; + C53C54D12AD67E8800C3662A /* LocalDBMarker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalDBMarker.swift; sourceTree = ""; }; C541521C2AC125E100F39826 /* TutorialTopLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TutorialTopLabel.swift; sourceTree = ""; }; C54657862ABF2D82003A0BCB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; C54657872ABF2DBA003A0BCB /* API.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; name = API.plist; path = AVIRO/Utils/API.plist; sourceTree = SOURCE_ROOT; }; @@ -691,7 +693,8 @@ C51B09B62A82046000916BBD /* LocalDataModel */ = { isa = PBXGroup; children = ( - C51B09B72A82155200916BBD /* LocalMarkerData.swift */, + C51B09B72A82155200916BBD /* MarkerModelCache.swift */, + C53C54D12AD67E8800C3662A /* LocalDBMarker.swift */, C5A9899A2A95A6B50021B7C3 /* LocalBookmarkData.swift */, ); path = LocalDataModel; @@ -1114,9 +1117,9 @@ C5A9899C2A95A7820021B7C3 /* FacadeManager */ = { isa = PBXGroup; children = ( + C510005B2AB9C39500F65C1F /* MarkerModelManager.swift */, C520662C2A7CE1CC0038ECCD /* SearchHistoryManager.swift */, C5A9899D2A95A7940021B7C3 /* BookmarkManager.swift */, - C510005B2AB9C39500F65C1F /* MarkerModelManager.swift */, ); path = FacadeManager; sourceTree = ""; @@ -1717,7 +1720,7 @@ C552D5342ABE8CA500933D8A /* AVIRODeleteAPI.swift in Sources */, C510005E2ABAA3C700F65C1F /* Enum+.swift in Sources */, C58FBF942AC2DB6D00AB6EFC /* KakaoKeywordResultDTO.swift in Sources */, - C51B09B82A82155200916BBD /* LocalMarkerData.swift in Sources */, + C51B09B82A82155200916BBD /* MarkerModelCache.swift in Sources */, C5A9899B2A95A6B50021B7C3 /* LocalBookmarkData.swift in Sources */, C520662D2A7CE1CC0038ECCD /* SearchHistoryManager.swift in Sources */, C51AED232A8B7B000015FBC2 /* UIViewController+Extension.swift in Sources */, @@ -1751,6 +1754,7 @@ C5A201B42A986EC300A54381 /* EditPlaceInfoViewController.swift in Sources */, C51AED1D2A8A192D0015FBC2 /* ChangedViewAction.swift in Sources */, C51B09BC2A82397800916BBD /* Marker+Extension.swift in Sources */, + C53C54D22AD67E8800C3662A /* LocalDBMarker.swift in Sources */, C58FBF922AC2D87300AB6EFC /* KakaoAPIManagerProtocol.swift in Sources */, C528E4BE2A5FB816002BD72E /* TermsTableCell.swift in Sources */, C53856B12ABC13ED00D52DEC /* AVIROMyContributionCount+DTO.swift in Sources */, diff --git a/AVIRO/Custom/Constants/Enum+.swift b/AVIRO/Custom/Constants/Enum+.swift index 709bc6e5..cda728e5 100644 --- a/AVIRO/Custom/Constants/Enum+.swift +++ b/AVIRO/Custom/Constants/Enum+.swift @@ -16,6 +16,7 @@ enum APP: String { // MARK: UserDefaults Key enum UDKey: String { case tutorial + case loadOnce } // MARK: NotificationCenter Name diff --git a/AVIRO/Manager/FacadeManager/MarkerModelManager.swift b/AVIRO/Manager/FacadeManager/MarkerModelManager.swift index cec45908..b27ef27e 100644 --- a/AVIRO/Manager/FacadeManager/MarkerModelManager.swift +++ b/AVIRO/Manager/FacadeManager/MarkerModelManager.swift @@ -8,6 +8,8 @@ import Foundation import NMapsMap +// realm 생성 및 기타 활동을 실행할때는 동일 쓰레드에서 진행해야함 +import RealmSwift protocol MarkerModelManagerProtocol { func getAllMarkerData() -> [MarkerModel] @@ -15,6 +17,76 @@ protocol MarkerModelManagerProtocol { } +// TODO: Time Data HomeViewPresenter에서 옮기기 final class MarkerModelManager { + private var didLoadOnce: Bool { + get { + return UserDefaults.standard.bool(forKey: UDKey.loadOnce.rawValue) + } + set { + UserDefaults.standard.set(newValue, forKey: UDKey.loadOnce.rawValue) + } + } + func fetchAllData( + completionHandler: @escaping (Result<[AVIROMarkerModel], APIError>) -> Void + ) { + if didLoadOnce { + fetchAllDataFromRealm(completionHandler: completionHandler) + } else { + fetchAllDataFromServer(completionHandler: completionHandler) + } + } + + private func fetchAllDataFromRealm( + completionHandler: @escaping (Result<[AVIROMarkerModel], APIError>) -> Void + ) { + let realm = try! Realm() + let realmResults = realm.objects(MarkerModelFromRealm.self) + + let markerModels = Array(realmResults).map { + $0.toAVIROMarkerModel() + } + + completionHandler(.success(markerModels)) + } + + private func fetchAllDataFromServer( + completionHandler: @escaping (Result<[AVIROMarkerModel], APIError>) -> Void + ) { + let model = AVIROMapModelDTO(longitude: "0.0", latitude: "0.0", wide: "0.0", time: nil) + + AVIROAPIManager().loadNerbyPlaceModels(with: model) { [weak self] result in + switch result { + case .success(let success): + if success.statusCode == 200 { + if let models = success.data.updatedPlace { + let realmModels = models.map { model -> MarkerModelFromRealm in + return MarkerModelFromRealm( + placeId: model.placeId, + latitude: model.y, + longitude: model.x, + isAll: model.allVegan, + isSome: model.someMenuVegan, + isRequest: model.ifRequestVegan) + } + + let realm = try! Realm() + + try! realm.write { + realm.add(realmModels, update: .modified) + } + + self?.didLoadOnce = true + + completionHandler(.success(models)) + } + } else { + completionHandler(.failure(.badRequest)) + } + case .failure(let error): + completionHandler(.failure(error)) + } + } + } } diff --git a/AVIRO/Model/HomeViewModel/MarkerModel.swift b/AVIRO/Model/HomeViewModel/MarkerModel.swift index cfec57b5..a48c8641 100644 --- a/AVIRO/Model/HomeViewModel/MarkerModel.swift +++ b/AVIRO/Model/HomeViewModel/MarkerModel.swift @@ -13,7 +13,9 @@ import NMapsMap struct MarkerModel: Equatable { let placeId: String var marker: NMFMarker - // MARK: 수정 중 일때만 Map Place 변경 가능 + + // MARK: 수정 중 일때만 Map Place 변경 가능 + // 해당 변수는 지도에 표시될 마커 구분을 위한 변수 var mapPlace: MapPlace { didSet { if isStar { @@ -44,6 +46,7 @@ struct MarkerModel: Equatable { } } + // edit할때 isSome, isRequest 중복이 있을 수 있으니 변수 생성 var isAll = false var isSome = false var isRequest = false diff --git a/AVIRO/Model/LocalDataModel/LocalDBMarker.swift b/AVIRO/Model/LocalDataModel/LocalDBMarker.swift new file mode 100644 index 00000000..d56e265e --- /dev/null +++ b/AVIRO/Model/LocalDataModel/LocalDBMarker.swift @@ -0,0 +1,50 @@ +// +// LocalDBMarker.swift +// AVIRO +// +// Created by 전성훈 on 2023/10/11. +// + +import Foundation + +import RealmSwift + +final class MarkerModelFromRealm: Object { + @Persisted(primaryKey: true) var placeId: String + @Persisted var latitude: Double + @Persisted var longitude: Double + + @Persisted var isAll: Bool + @Persisted var isSome: Bool + @Persisted var isRequest: Bool + + // primary key 설정으로 convenince init 설정 + convenience init( + placeId: String, + latitude: Double, + longitude: Double, + isAll: Bool, + isSome: Bool, + isRequest: Bool + ) { + self.init() + + self.placeId = placeId + self.latitude = latitude + self.longitude = longitude + self.isAll = isAll + self.isSome = isSome + self.isRequest = isRequest + } + + func toAVIROMarkerModel() -> AVIROMarkerModel { + return AVIROMarkerModel( + placeId: placeId, + x: longitude, + y: latitude, + allVegan: isAll, + someMenuVegan: isSome, + ifRequestVegan: isRequest + ) + } +} diff --git a/AVIRO/Model/LocalDataModel/LocalMarkerData.swift b/AVIRO/Model/LocalDataModel/MarkerModelCache.swift similarity index 97% rename from AVIRO/Model/LocalDataModel/LocalMarkerData.swift rename to AVIRO/Model/LocalDataModel/MarkerModelCache.swift index e5736a88..91abdef8 100644 --- a/AVIRO/Model/LocalDataModel/LocalMarkerData.swift +++ b/AVIRO/Model/LocalDataModel/MarkerModelCache.swift @@ -10,7 +10,7 @@ import UIKit import NMapsMap // MARK: 아래 함수들 존재 유무 확인 필요 -protocol LocalMarkerDataProtocol { +protocol MarkerModelCacheProtocol { func getMarkers() -> [NMFMarker] func getMarkerModels() -> [MarkerModel] func getOnlyStarMarkerModels() -> [MarkerModel] @@ -26,8 +26,8 @@ protocol LocalMarkerDataProtocol { func deleteAllMarkerModel() } -final class LocalMarkerData: LocalMarkerDataProtocol { - static let shared = LocalMarkerData() +final class MarkerModelCache: MarkerModelCacheProtocol { + static let shared = MarkerModelCache() private var markers: [MarkerModel] = [] diff --git a/AVIRO/Scene/Presenter/Home/HomeViewPresenter.swift b/AVIRO/Scene/Presenter/Home/HomeViewPresenter.swift index 4b47aec9..d3867db0 100644 --- a/AVIRO/Scene/Presenter/Home/HomeViewPresenter.swift +++ b/AVIRO/Scene/Presenter/Home/HomeViewPresenter.swift @@ -211,6 +211,7 @@ final class HomeViewPresenter: NSObject { } // MARK: vegan Data 불러오기 + // TODO: Marker Manager 생성시 코드 수정 요망 func loadVeganData() { let mapModel = AVIROMapModelDTO( longitude: MyCoordinate.shared.longitudeString, @@ -218,24 +219,35 @@ final class HomeViewPresenter: NSObject { wide: "0.0", time: nil ) - - AVIROAPIManager().loadNerbyPlaceModels(with: mapModel) { [weak self] result in - switch result { - case .success(let mapDatas): - if mapDatas.statusCode == 200 { - self?.saveMarkers(mapDatas.data.updatedPlace) - } else { - self?.viewController?.showErrorAlertWhenLoadMarker() - } - - case .failure(_): - self?.viewController?.showErrorAlertWhenLoadMarker() + + MarkerModelManager().fetchAllData { resu in + switch resu { + case .success(let success): + return + case .failure(let failure): + return } } - bookmarkManager.fetchAllData { [weak self] error in - self?.viewController?.showErrorAlert(with: error, title: nil) - } + + +// AVIROAPIManager().loadNerbyPlaceModels(with: mapModel) { [weak self] result in +// switch result { +// case .success(let mapDatas): +// if mapDatas.statusCode == 200 { +// self?.saveMarkers(mapDatas.data.updatedPlace) +// } else { +// self?.viewController?.showErrorAlertWhenLoadMarker() +// } +// +// case .failure(_): +// self?.viewController?.showErrorAlertWhenLoadMarker() +// } +// } +// +// bookmarkManager.fetchAllData { [weak self] error in +// self?.viewController?.showErrorAlert(with: error, title: nil) +// } } private func saveMarkers(_ mapData: [AVIROMarkerModel]?) { @@ -248,10 +260,10 @@ final class HomeViewPresenter: NSObject { markerModels.append(markerModel) } - LocalMarkerData.shared.setMarkerModel(markerModels) + MarkerModelCache.shared.setMarkerModel(markerModels) DispatchQueue.main.async { [weak self] in - let markers = LocalMarkerData.shared.getMarkers() + let markers = MarkerModelCache.shared.getMarkers() self?.viewController?.loadMarkers(with: markers) } } @@ -291,11 +303,11 @@ final class HomeViewPresenter: NSObject { uniqueMapData.forEach { data in let markerModel = createMarkerModel(from: data) - LocalMarkerData.shared.updateMarkerModel(markerModel) + MarkerModelCache.shared.updateMarkerModel(markerModel) } DispatchQueue.main.async { [weak self] in - let markers = LocalMarkerData.shared.getUpdatedMarkers() + let markers = MarkerModelCache.shared.getUpdatedMarkers() self?.viewController?.loadMarkers(with: markers) self?.nowDateTime = TimeUtility.nowDateAndTime() @@ -310,7 +322,7 @@ final class HomeViewPresenter: NSObject { private func deleteMarkers(_ placeId: [String]) { DispatchQueue.main.async { placeId.forEach { - LocalMarkerData.shared.deleteMarkerModel(with: $0) + MarkerModelCache.shared.deleteMarkerModel(with: $0) } } } @@ -320,7 +332,7 @@ final class HomeViewPresenter: NSObject { let lng = CenterCoordinate.shared.longitude else { return } - let (markerModel, index) = LocalMarkerData.shared.getMarkerWhenEnrollAfter(x: lat, y: lng) + let (markerModel, index) = MarkerModelCache.shared.getMarkerWhenEnrollAfter(x: lat, y: lng) guard var markerModel = markerModel else { return } guard let index = index else { return } @@ -335,7 +347,7 @@ final class HomeViewPresenter: NSObject { selectedMarkerModel = markerModel selectedMarkerModel?.isClicked = true - LocalMarkerData.shared.updateWhenClickedMarker(selectedMarkerModel!) + MarkerModelCache.shared.updateWhenClickedMarker(selectedMarkerModel!) viewController?.moveToCameraWhenHasAVIRO(markerModel) @@ -363,7 +375,7 @@ final class HomeViewPresenter: NSObject { return true } - let test = MarkerModel( + let markerModel = MarkerModel( placeId: placeId, marker: marker, mapPlace: place, @@ -372,7 +384,7 @@ final class HomeViewPresenter: NSObject { isRequest: data.ifRequestVegan ) - return test + return markerModel } // MARK: Marker Touched Method @@ -391,7 +403,7 @@ final class HomeViewPresenter: NSObject { if hasTouchedMarkerBefore { if var selectedMarkerModel = selectedMarkerModel { selectedMarkerModel.isClicked = false - LocalMarkerData.shared.updateWhenClickedMarker(selectedMarkerModel) + MarkerModelCache.shared.updateWhenClickedMarker(selectedMarkerModel) } selectedMarkerModel = nil @@ -406,7 +418,7 @@ final class HomeViewPresenter: NSObject { /// 클릭한 마커 저장 후 viewController에 알리기 private func setMarkerToTouchedState(_ marker: NMFMarker) { - let (markerModel, index) = LocalMarkerData.shared.getMarkerFromMarker(marker) + let (markerModel, index) = MarkerModelCache.shared.getMarkerFromMarker(marker) guard let validMarkerModel = markerModel else { return } @@ -421,7 +433,7 @@ final class HomeViewPresenter: NSObject { hasTouchedMarkerBefore = true - LocalMarkerData.shared.updateWhenClickedMarker(selectedMarkerModel!) + MarkerModelCache.shared.updateWhenClickedMarker(selectedMarkerModel!) viewController?.moveToCameraWhenHasAVIRO(validMarkerModel) } @@ -507,7 +519,7 @@ final class HomeViewPresenter: NSObject { ) } else { // AVIRO에 데이터가 있을 때 - let (markerModel, index) = LocalMarkerData.shared.getMarkerWhenSearchAfter(afterSearchModel) + let (markerModel, index) = MarkerModelCache.shared.getMarkerWhenSearchAfter(afterSearchModel) guard let markerModel = markerModel else { return } guard let index = index else { return } @@ -520,7 +532,7 @@ final class HomeViewPresenter: NSObject { selectedMarkerModel = markerModel selectedMarkerModel?.isClicked = true - LocalMarkerData.shared.updateWhenClickedMarker(selectedMarkerModel!) + MarkerModelCache.shared.updateWhenClickedMarker(selectedMarkerModel!) hasTouchedMarkerBefore = true @@ -538,7 +550,7 @@ final class HomeViewPresenter: NSObject { } private func whenAfterLoadStarButtonTapped() { - let markersModel = LocalMarkerData.shared.getMarkerModels() + let markersModel = MarkerModelCache.shared.getMarkerModels() let bookmarks = bookmarkManager.loadAllData() @@ -555,20 +567,20 @@ final class HomeViewPresenter: NSObject { } } - LocalMarkerData.shared.updateWhenStarButton(starMarkersModel) + MarkerModelCache.shared.updateWhenStarButton(starMarkersModel) viewController?.afterLoadStarButton(with: noMarkers) } private func whenAfterLoadNotStarButtonTapped() { - var starMarkersModel = LocalMarkerData.shared.getOnlyStarMarkerModels() + var starMarkersModel = MarkerModelCache.shared.getOnlyStarMarkerModels() for index in 0.. Date: Thu, 12 Oct 2023 13:39:51 +0900 Subject: [PATCH 2/4] =?UTF-8?q?[feat]:=20=EC=9D=98=EC=A1=B4=EC=84=B1=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FacadeManager/BookmarkManager.swift | 68 +++++++++++++------ .../FacadeManager/MarkerModelManager.swift | 5 +- .../LocalDataModel/LocalBookmarkData.swift | 19 ++++-- .../CenterCoordinate.swift | 13 +--- .../Model/SingletonModel/MyData/MyData.swift | 2 + .../EditPlaceInfoPresenter.swift | 2 + .../Presenter/Home/HomeViewPresenter.swift | 66 +++++++++--------- .../Mypage/MyPageViewPresenter.swift | 9 +-- .../EditPlaceInfoViewController.swift | 1 - 9 files changed, 109 insertions(+), 76 deletions(-) diff --git a/AVIRO/Manager/FacadeManager/BookmarkManager.swift b/AVIRO/Manager/FacadeManager/BookmarkManager.swift index 10e84e46..a4e70803 100644 --- a/AVIRO/Manager/FacadeManager/BookmarkManager.swift +++ b/AVIRO/Manager/FacadeManager/BookmarkManager.swift @@ -7,16 +7,29 @@ import Foundation -final class BookmarkFacadeManager { - private let bookmarkArray = LocalBookmarkData.shared +protocol BookmarkFacadeProtocol { + func fetchAllData(completionHandler: @escaping ((String) -> Void)) + func loadAllData() -> [String] + func checkData(with placeId: String) -> Bool + func updateData(with placeId: String, completionHandler: @escaping ((String) -> Void)) + func deleteData(with placeId: String, completionHandler: @escaping ((String) -> Void)) + func deleteAllData() +} + +final class BookmarkFacadeManager: BookmarkFacadeProtocol { + private let bookmarkArray: BookmarkDataProtocol + init(bookmarkArray: BookmarkDataProtocol = LocalBookmarkData.shared) { + self.bookmarkArray = bookmarkArray + } + func fetchAllData(completionHandler: @escaping ((String) -> Void)) { AVIROAPIManager().loadBookmarkModels(with: MyData.my.id) { [weak self] result in switch result { case .success(let success): if success.statusCode == 200 { let dataArray = success.bookmarks - self?.bookmarkArray.updateAllData(dataArray) + self?.bookmarkArray.updateAllData(with: dataArray) } else { if let error = APIError.badRequest.errorDescription { completionHandler(error) @@ -34,10 +47,39 @@ final class BookmarkFacadeManager { bookmarkArray.loadAllData() } - func updateBookmark(_ placeId: String, completionHandler: @escaping ((String) -> Void)) { + func checkData(with placeId: String) -> Bool { + bookmarkArray.checkData(with: placeId) + } + + func updateData( + with placeId: String, + completionHandler: @escaping ((String) -> Void) + ) { + self.bookmarkArray.updateData(with: placeId) + self.updateBookmark( + with: placeId, + completionHandler: completionHandler + ) + } + + func deleteData( + with placeId: String, + completionHandler: @escaping ((String) -> Void) + ) { + self.bookmarkArray.deleteData(with: placeId) + self.updateBookmark( + with: placeId, + completionHandler: completionHandler + ) + } + + private func updateBookmark(with placeId: String, completionHandler: @escaping ((String) -> Void)) { let bookmarks = bookmarkArray.loadAllData() - let postModel = AVIROUpdateBookmarkDTO(placeList: bookmarks, userId: MyData.my.id) + let postModel = AVIROUpdateBookmarkDTO( + placeList: bookmarks, + userId: MyData.my.id + ) AVIROAPIManager().createBookmarkModel(with: postModel) { result in switch result { @@ -56,21 +98,7 @@ final class BookmarkFacadeManager { } } } - - func checkData(_ placeId: String) -> Bool { - bookmarkArray.checkData(placeId) - } - - func updateData(_ placeId: String, completionHandler: @escaping ((String) -> Void)) { - self.bookmarkArray.updateData(placeId) - self.updateBookmark(placeId, completionHandler: completionHandler) - } - - func deleteData(_ placeId: String, completionHandler: @escaping ((String) -> Void)) { - self.bookmarkArray.deleteData(placeId) - self.updateBookmark(placeId, completionHandler: completionHandler) - } - + func deleteAllData() { bookmarkArray.deleteAllBookmark() } diff --git a/AVIRO/Manager/FacadeManager/MarkerModelManager.swift b/AVIRO/Manager/FacadeManager/MarkerModelManager.swift index b27ef27e..912265f3 100644 --- a/AVIRO/Manager/FacadeManager/MarkerModelManager.swift +++ b/AVIRO/Manager/FacadeManager/MarkerModelManager.swift @@ -12,13 +12,12 @@ import NMapsMap import RealmSwift protocol MarkerModelManagerProtocol { - func getAllMarkerData() -> [MarkerModel] - func getMarkerData() + func fetchAllData(completionHandler: @escaping (Result<[AVIROMarkerModel], APIError>) -> Void) } // TODO: Time Data HomeViewPresenter에서 옮기기 -final class MarkerModelManager { +final class MarkerModelManager: MarkerModelManagerProtocol { private var didLoadOnce: Bool { get { return UserDefaults.standard.bool(forKey: UDKey.loadOnce.rawValue) diff --git a/AVIRO/Model/LocalDataModel/LocalBookmarkData.swift b/AVIRO/Model/LocalDataModel/LocalBookmarkData.swift index a1b65ccb..9c8ee4f4 100644 --- a/AVIRO/Model/LocalDataModel/LocalBookmarkData.swift +++ b/AVIRO/Model/LocalDataModel/LocalBookmarkData.swift @@ -7,14 +7,23 @@ import Foundation -final class LocalBookmarkData { +protocol BookmarkDataProtocol { + func updateAllData(with list: [String]) + func loadAllData() -> [String] + func checkData(with placeId: String) -> Bool + func updateData(with placeId: String) + func deleteData(with placeId: String) + func deleteAllBookmark() +} + +final class LocalBookmarkData: BookmarkDataProtocol { static let shared = LocalBookmarkData() private var bookmarkList: [String] = [] private init() { } - func updateAllData(_ list: [String]) { + func updateAllData(with list: [String]) { self.bookmarkList = list } @@ -22,17 +31,17 @@ final class LocalBookmarkData { bookmarkList } - func checkData(_ placeId: String) -> Bool { + func checkData(with placeId: String) -> Bool { bookmarkList.contains(placeId) } - func updateData(_ placeId: String) { + func updateData(with placeId: String) { if !bookmarkList.contains(placeId) { bookmarkList.append(placeId) } } - func deleteData(_ placeId: String) { + func deleteData(with placeId: String) { if let index = bookmarkList.firstIndex(of: placeId) { bookmarkList.remove(at: index) } diff --git a/AVIRO/Model/SingletonModel/CoordinateSingleton/CenterCoordinate.swift b/AVIRO/Model/SingletonModel/CoordinateSingleton/CenterCoordinate.swift index 3571df93..da77b2fd 100644 --- a/AVIRO/Model/SingletonModel/CoordinateSingleton/CenterCoordinate.swift +++ b/AVIRO/Model/SingletonModel/CoordinateSingleton/CenterCoordinate.swift @@ -16,15 +16,6 @@ final class CenterCoordinate { var longitude: Double? var isChangedFromEnrollView = false - -// var isChangedFromEnrollView = false { -// didSet { -// if isChangedFromEnrollView { -// afterEnrollPlace?() -// isChangedFromEnrollView.toggle() -// } -// } -// } var latitudeString: String { return String(format: "%.5f", latitude ?? "") @@ -33,9 +24,7 @@ final class CenterCoordinate { var longitudeString: String { return String(format: "%.5f", longitude ?? "") } - -// var afterEnrollPlace: (() -> Void)? - + private init(latitude: Double? = nil, longitude: Double? = nil ) { diff --git a/AVIRO/Model/SingletonModel/MyData/MyData.swift b/AVIRO/Model/SingletonModel/MyData/MyData.swift index 124dfdf8..0ecbc2ed 100644 --- a/AVIRO/Model/SingletonModel/MyData/MyData.swift +++ b/AVIRO/Model/SingletonModel/MyData/MyData.swift @@ -63,5 +63,7 @@ final class MyData: MyDataProtocol { self.email = "" self.nickname = "" self.marketingAgree = 0 + + AmplitudeUtility.logout() } } diff --git a/AVIRO/Scene/Presenter/Home/EditPresenter/EditPlaceInfoPresenter.swift b/AVIRO/Scene/Presenter/Home/EditPresenter/EditPlaceInfoPresenter.swift index 1ce33a51..30bcdae0 100644 --- a/AVIRO/Scene/Presenter/Home/EditPresenter/EditPlaceInfoPresenter.swift +++ b/AVIRO/Scene/Presenter/Home/EditPresenter/EditPlaceInfoPresenter.swift @@ -536,6 +536,8 @@ extension EditPlaceInfoPresenter { AmplitudeUtility.requestEditPlace(with: placeTitle) self?.viewController?.popViewController() self?.afterReportShowAlert?() + } else { + } } } diff --git a/AVIRO/Scene/Presenter/Home/HomeViewPresenter.swift b/AVIRO/Scene/Presenter/Home/HomeViewPresenter.swift index d3867db0..d3ca22f9 100644 --- a/AVIRO/Scene/Presenter/Home/HomeViewPresenter.swift +++ b/AVIRO/Scene/Presenter/Home/HomeViewPresenter.swift @@ -63,9 +63,10 @@ protocol HomeViewProtocol: NSObject { final class HomeViewPresenter: NSObject { weak var viewController: HomeViewProtocol? - private let locationManager = CLLocationManager() + private let markerModelManager: MarkerModelManagerProtocol private let bookmarkManager = BookmarkFacadeManager() - + private let locationManager = CLLocationManager() + var homeMapData: [AVIROMarkerModel]? private var hasTouchedMarkerBefore = false @@ -84,8 +85,11 @@ final class HomeViewPresenter: NSObject { private var nowDateTime = TimeUtility.nowDateAndTime() - init(viewController: HomeViewProtocol) { + init(viewController: HomeViewProtocol, + markerManager: MarkerModelManagerProtocol = MarkerModelManager() + ) { self.viewController = viewController + self.markerModelManager = markerManager } deinit { @@ -220,34 +224,34 @@ final class HomeViewPresenter: NSObject { time: nil ) - MarkerModelManager().fetchAllData { resu in - switch resu { - case .success(let success): - return - case .failure(let failure): - return - } - } +// MarkerModelManager().fetchAllData { resu in +// switch resu { +// case .success(let success): +// return +// case .failure(let failure): +// return +// } +// } -// AVIROAPIManager().loadNerbyPlaceModels(with: mapModel) { [weak self] result in -// switch result { -// case .success(let mapDatas): -// if mapDatas.statusCode == 200 { -// self?.saveMarkers(mapDatas.data.updatedPlace) -// } else { -// self?.viewController?.showErrorAlertWhenLoadMarker() -// } -// -// case .failure(_): -// self?.viewController?.showErrorAlertWhenLoadMarker() -// } -// } -// -// bookmarkManager.fetchAllData { [weak self] error in -// self?.viewController?.showErrorAlert(with: error, title: nil) -// } + AVIROAPIManager().loadNerbyPlaceModels(with: mapModel) { [weak self] result in + switch result { + case .success(let mapDatas): + if mapDatas.statusCode == 200 { + self?.saveMarkers(mapDatas.data.updatedPlace) + } else { + self?.viewController?.showErrorAlertWhenLoadMarker() + } + + case .failure(_): + self?.viewController?.showErrorAlertWhenLoadMarker() + } + } + + bookmarkManager.fetchAllData { [weak self] error in + self?.viewController?.showErrorAlert(with: error, title: nil) + } } private func saveMarkers(_ mapData: [AVIROMarkerModel]?) { @@ -473,7 +477,7 @@ final class HomeViewPresenter: NSObject { AmplitudeUtility.popupPlace(with: place.title) DispatchQueue.main.async { - let isStar = self?.bookmarkManager.checkData(placeId) + let isStar = self?.bookmarkManager.checkData(with: placeId) self?.viewController?.afterClickedMarker( placeModel: placeTopModel, @@ -590,11 +594,11 @@ final class HomeViewPresenter: NSObject { guard let placeId = selectedPlaceId else { return } if isSelected { - bookmarkManager.updateData(placeId) { [weak self] error in + bookmarkManager.updateData(with: placeId) { [weak self] error in self?.viewController?.showToastAlert(error) } } else { - bookmarkManager.deleteData(placeId) { [weak self] error in + bookmarkManager.deleteData(with: placeId) { [weak self] error in self?.viewController?.showToastAlert(error) } } diff --git a/AVIRO/Scene/Presenter/Mypage/MyPageViewPresenter.swift b/AVIRO/Scene/Presenter/Mypage/MyPageViewPresenter.swift index 0c57b2fb..4c126ab2 100644 --- a/AVIRO/Scene/Presenter/Mypage/MyPageViewPresenter.swift +++ b/AVIRO/Scene/Presenter/Mypage/MyPageViewPresenter.swift @@ -26,7 +26,7 @@ protocol MyPageViewProtocol: NSObject { final class MyPageViewPresenter { weak var viewController: MyPageViewProtocol? - private let bookmarkManager = BookmarkFacadeManager() + private let bookmarkManager: BookmarkFacadeManager private let keychain = KeychainSwift() private var myDataModel: MyDataModel? { @@ -38,8 +38,11 @@ final class MyPageViewPresenter { } } - init(viewController: MyPageViewProtocol) { + init(viewController: MyPageViewProtocol, + bookmarkManager: BookmarkFacadeManager = BookmarkFacadeManager() + ) { self.viewController = viewController + self.bookmarkManager = bookmarkManager } func viewDidLoad() { @@ -91,8 +94,6 @@ final class MyPageViewPresenter { MyData.my.whenLogout() MyCoordinate.shared.isFirstLoadLocation = false - - AmplitudeUtility.logout() self.keychain.delete(KeychainKey.appleRefreshToken.rawValue) diff --git a/AVIRO/Scene/View/TabBar/Home/Edit/EditPlaceInfo/EditPlaceInfoViewController.swift b/AVIRO/Scene/View/TabBar/Home/Edit/EditPlaceInfo/EditPlaceInfoViewController.swift index e9f3f02b..0a1acf8b 100644 --- a/AVIRO/Scene/View/TabBar/Home/Edit/EditPlaceInfo/EditPlaceInfoViewController.swift +++ b/AVIRO/Scene/View/TabBar/Home/Edit/EditPlaceInfo/EditPlaceInfoViewController.swift @@ -345,7 +345,6 @@ extension EditPlaceInfoViewController: EditPlaceInfoProtocol { @objc private func editStoreButtonTapped() { presenter.afterEditButtonTapped() - self.view.isUserInteractionEnabled = false } @objc private func swipeGestureActive(_ gesture: UISwipeGestureRecognizer) { From 138d096e7950d2a4e972a7bc403e2729598da4bc Mon Sep 17 00:00:00 2001 From: Jeon Seoung Hun Date: Thu, 12 Oct 2023 22:42:24 +0900 Subject: [PATCH 3/4] =?UTF-8?q?README=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 87b77bc6..93eed312 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ - SwiftLint - NaverMap SDK - Amplitude SDK +- Realm ## 기타 외부 라이브러리 - Lottie - Toast-Swift From 8e8b931f6fc316558e658d971c5c2a45712635c1 Mon Sep 17 00:00:00 2001 From: Jeon Seoung Hun Date: Thu, 12 Oct 2023 22:43:49 +0900 Subject: [PATCH 4/4] =?UTF-8?q?[fix]:=20=ED=99=88=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EC=8B=A4?= =?UTF-8?q?=ED=8C=A8=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AVIRO/Manager/APIManager/AVIROManager/AVIROAPIManager.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AVIRO/Manager/APIManager/AVIROManager/AVIROAPIManager.swift b/AVIRO/Manager/APIManager/AVIROManager/AVIROAPIManager.swift index 5f0ccf38..adcabb63 100644 --- a/AVIRO/Manager/APIManager/AVIROManager/AVIROAPIManager.swift +++ b/AVIRO/Manager/APIManager/AVIROManager/AVIROAPIManager.swift @@ -316,7 +316,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol { } func editPlaceURL( - with url: AVIROEditURLDTO, + with urlData: AVIROEditURLDTO, completionHandler: @escaping (Result) -> Void ) { guard let url = postAPI.editPlaceURL().url else { @@ -324,7 +324,7 @@ final class AVIROAPIManager: AVIROAPIMangerProtocol { return } - guard let jsonData = try? JSONEncoder().encode(url) else { + guard let jsonData = try? JSONEncoder().encode(urlData) else { completionHandler(.failure(.encodingError)) return }