From cb39a8c0de6850ac2524a78e6356f4dc92db0314 Mon Sep 17 00:00:00 2001 From: Song Lee Date: Sat, 2 Oct 2021 19:50:44 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20[#196]=20Storage=EC=9D=98=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=EC=9D=84=20=EA=B0=81=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=86=A0=EC=BD=9C=EB=A1=9C=20=EB=B6=84=EB=A6=AC=ED=95=98?= =?UTF-8?q?=EC=97=AC=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Force Cast의 SwiftLint 제약으로 인해 빌드 실패하는 상황 - 상황 공유를 위해 우선 커밋 --- .../project.pbxproj | 12 +-- .../AppCycle/AppDelegate.swift | 6 +- .../Service/Storage/Storage.swift | 81 ++++++++++--------- ...orageType.swift => StorageProtocols.swift} | 39 ++++----- .../ViewModel/AdViewModel.swift | 8 -- .../ViewModel/CommonViewModel.swift | 4 +- .../ViewModel/GameOverViewModel.swift | 6 +- .../ViewModel/GameViewModel.swift | 13 ++- .../ViewModel/HowToPlayViewModel.swift | 4 +- .../ViewModel/ItemViewModel.swift | 7 +- .../ViewModel/MainViewModel.swift | 26 +++--- .../ViewModel/PauseViewModel.swift | 4 +- .../ViewModel/RankViewModel.swift | 4 +- .../ViewModel/ShopViewModel.swift | 8 +- .../ViewModel/StoryViewModel.swift | 6 +- FullStackCodingBot/Podfile.lock | 2 +- 16 files changed, 124 insertions(+), 106 deletions(-) rename FullStackCodingBot/FullStackCodingBot/Service/Storage/{StorageType.swift => StorageProtocols.swift} (62%) delete mode 100644 FullStackCodingBot/FullStackCodingBot/ViewModel/AdViewModel.swift diff --git a/FullStackCodingBot/FullStackCodingBot.xcodeproj/project.pbxproj b/FullStackCodingBot/FullStackCodingBot.xcodeproj/project.pbxproj index 64a2b49..ac2f23b 100644 --- a/FullStackCodingBot/FullStackCodingBot.xcodeproj/project.pbxproj +++ b/FullStackCodingBot/FullStackCodingBot.xcodeproj/project.pbxproj @@ -89,7 +89,7 @@ E4336F6326F083C30049A5D8 /* CoreDataManagerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4336F6226F083C30049A5D8 /* CoreDataManagerType.swift */; }; E4336F6826F1AB8B0049A5D8 /* CoreDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4336F6726F1AB8B0049A5D8 /* CoreDataManager.swift */; }; E4336F6A26F1B7500049A5D8 /* GameStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4336F6926F1B7500049A5D8 /* GameStorage.swift */; }; - E4336F6C26F1BC1A0049A5D8 /* StorageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4336F6B26F1BC1A0049A5D8 /* StorageType.swift */; }; + E4336F6C26F1BC1A0049A5D8 /* StorageProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4336F6B26F1BC1A0049A5D8 /* StorageProtocols.swift */; }; E43B64A226ABD81C001D9896 /* GameBackgroundView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E43B64A126ABD81C001D9896 /* GameBackgroundView.swift */; }; E43B64A426AC2384001D9896 /* TimeBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E43B64A326AC2384001D9896 /* TimeBarView.swift */; }; E45B0AB82692929F006FDE3D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E45B0AB72692929F006FDE3D /* Assets.xcassets */; }; @@ -143,7 +143,6 @@ E4DD682126A138D900B9F9CE /* GameKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4DD682026A138D900B9F9CE /* GameKit.framework */; }; E4DF613B26A845670061F6E9 /* AdStorageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4DF613A26A845670061F6E9 /* AdStorageType.swift */; }; E4DF613D26A845DA0061F6E9 /* AdStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4DF613C26A845DA0061F6E9 /* AdStorage.swift */; }; - E4DF613F26A847330061F6E9 /* AdViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4DF613E26A847330061F6E9 /* AdViewModel.swift */; }; E4DF614126A92CE00061F6E9 /* ShopItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4DF614026A92CE00061F6E9 /* ShopItem.swift */; }; E4DF614326A93FFB0061F6E9 /* ShopCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4DF614226A93FFB0061F6E9 /* ShopCell.swift */; }; E4F4304226C37A9B00F046E9 /* GameOverDialogView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F4304126C37A9B00F046E9 /* GameOverDialogView.swift */; }; @@ -248,7 +247,7 @@ E4336F6226F083C30049A5D8 /* CoreDataManagerType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataManagerType.swift; sourceTree = ""; }; E4336F6726F1AB8B0049A5D8 /* CoreDataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataManager.swift; sourceTree = ""; }; E4336F6926F1B7500049A5D8 /* GameStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameStorage.swift; sourceTree = ""; }; - E4336F6B26F1BC1A0049A5D8 /* StorageType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorageType.swift; sourceTree = ""; }; + E4336F6B26F1BC1A0049A5D8 /* StorageProtocols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorageProtocols.swift; sourceTree = ""; }; E43B64A126ABD81C001D9896 /* GameBackgroundView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameBackgroundView.swift; sourceTree = ""; }; E43B64A326AC2384001D9896 /* TimeBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeBarView.swift; sourceTree = ""; }; E45B0AAB2692929D006FDE3D /* Full Stack.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Full Stack.app"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -300,7 +299,6 @@ E4DD682026A138D900B9F9CE /* GameKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System/Library/Frameworks/GameKit.framework; sourceTree = SDKROOT; }; E4DF613A26A845670061F6E9 /* AdStorageType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdStorageType.swift; sourceTree = ""; }; E4DF613C26A845DA0061F6E9 /* AdStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdStorage.swift; sourceTree = ""; }; - E4DF613E26A847330061F6E9 /* AdViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdViewModel.swift; sourceTree = ""; }; E4DF614026A92CE00061F6E9 /* ShopItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShopItem.swift; sourceTree = ""; }; E4DF614226A93FFB0061F6E9 /* ShopCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShopCell.swift; sourceTree = ""; }; E4F4304126C37A9B00F046E9 /* GameOverDialogView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameOverDialogView.swift; sourceTree = ""; }; @@ -488,7 +486,6 @@ E4779C6826983F8000B92D24 /* GameOverViewModel.swift */, E41C85DC269C50F0008F2E91 /* PauseViewModel.swift */, 71DF65542692FD1400557693 /* CommonViewModel.swift */, - E4DF613E26A847330061F6E9 /* AdViewModel.swift */, 715C1C9726BD09950025C681 /* StoryViewModel.swift */, 7166B23C26C253A800E098BE /* HowToPlayViewModel.swift */, ); @@ -649,7 +646,7 @@ isa = PBXGroup; children = ( E4336F5A26F0638A0049A5D8 /* Storage.swift */, - E4336F6B26F1BC1A0049A5D8 /* StorageType.swift */, + E4336F6B26F1BC1A0049A5D8 /* StorageProtocols.swift */, E4336F6526F08AD80049A5D8 /* RealDataStorage */, E4336F6626F08AF10049A5D8 /* BackUpManager */, ); @@ -1098,7 +1095,7 @@ E4150EA426BE9A540041DD32 /* Line.swift in Sources */, E4BF710926B00EF600E8645F /* FeverTimeBarView.swift in Sources */, E4DF614326A93FFB0061F6E9 /* ShopCell.swift in Sources */, - E4336F6C26F1BC1A0049A5D8 /* StorageType.swift in Sources */, + E4336F6C26F1BC1A0049A5D8 /* StorageProtocols.swift in Sources */, E41C85DD269C50F0008F2E91 /* PauseViewModel.swift in Sources */, E41C85DF269C5149008F2E91 /* PauseButtonController.swift in Sources */, E418F36F26DC8D4800F35AFB /* UnitInfo - keyColor.swift in Sources */, @@ -1115,7 +1112,6 @@ 719AB9DE26B7ADF2001B5913 /* SettingViewController.swift in Sources */, 71DF65552692FD1400557693 /* CommonViewModel.swift in Sources */, 715C1C9826BD09950025C681 /* StoryViewModel.swift in Sources */, - E4DF613F26A847330061F6E9 /* AdViewModel.swift in Sources */, 710D0D442693EA6900244A16 /* GameViewModel.swift in Sources */, 71DF65492692F97900557693 /* ItemViewModel.swift in Sources */, E4C2C34F26A292BB007BDF81 /* ReplicateAnimationView.swift in Sources */, diff --git a/FullStackCodingBot/FullStackCodingBot/AppCycle/AppDelegate.swift b/FullStackCodingBot/FullStackCodingBot/AppCycle/AppDelegate.swift index 4a11c32..03b9e4d 100644 --- a/FullStackCodingBot/FullStackCodingBot/AppCycle/AppDelegate.swift +++ b/FullStackCodingBot/FullStackCodingBot/AppCycle/AppDelegate.swift @@ -58,12 +58,14 @@ private extension AppDelegate { switch hasLaunchedOnce { case true: - let mainViewModel = MainViewModel(sceneCoordinator: sceneCoordinator, storage: storage!, settings: settings) + let mainViewModel = MainViewModel(sceneCoordinator: sceneCoordinator, + storage: storage! as (RewardManagable & GameDataManagable), + settings: settings) let mainScene = MainScene.main(mainViewModel) return mainScene case false: - let storyViewModel = StoryViewModel(sceneCoordinator: sceneCoordinator, storage: storage!, settings: settings) + let storyViewModel = StoryViewModel(sceneCoordinator: sceneCoordinator, settings: settings) let storyScene = GameHelperScene.story(storyViewModel) return storyScene diff --git a/FullStackCodingBot/FullStackCodingBot/Service/Storage/Storage.swift b/FullStackCodingBot/FullStackCodingBot/Service/Storage/Storage.swift index 482647a..62fadbe 100644 --- a/FullStackCodingBot/FullStackCodingBot/Service/Storage/Storage.swift +++ b/FullStackCodingBot/FullStackCodingBot/Service/Storage/Storage.swift @@ -3,7 +3,6 @@ import RxSwift import GoogleMobileAds final class Storage { - private var gameStorage: GameStorageType private var adStorage: AdStorageType private var backUpCenter: BackUpCenterType @@ -16,7 +15,9 @@ final class Storage { self.adStorage = adStorage self.backUpCenter = backUpCenter } - +} + +extension Storage: GameDataManagable { func initializeData(using uuid: String?, isFirstLaunched: Bool) -> Observable { Observable.create { [unowned self] observer in self.backUpCenter.load(with: uuid, isFirstLaunched) @@ -34,33 +35,18 @@ final class Storage { return Disposables.create() } } -} - -extension Storage: StorageType { - func availableRewards() -> Observable<[ShopItem]> { - return adStorage.availableItems() - } - func availableMoney() -> Observable { - return gameStorage.availableMoney() - } - - func setNewRewardsIfPossible() -> Observable { - return adStorage.setNewRewardsIfPossible(with: .none) - } - - func rewardNeedsToBeGiven(with finishedAd: GADRewardedAd?) -> Int { - if let finishedAd = finishedAd { - adStorage.adDidFinished(finishedAd) - } else { - adStorage.giftTaken() - } - let reward = ShopSetting.reward() - gameStorage.raiseMoney(by: reward) - backUpCenter.save(gameData: .none, gameStorage.myMoney(), .none) - return reward + func save() { + let currentData = NetworkDTO(units: gameStorage.itemList(), + money: gameStorage.myMoney(), + score: gameStorage.myHighScore(), + ads: adStorage.currentInformation(), + date: Date()) + backUpCenter.save(gameData: currentData) } - +} + +extension Storage: GameItemManagable { func itemList() -> [Unit] { return gameStorage.itemList() } @@ -70,28 +56,49 @@ extension Storage: StorageType { backUpCenter.save(gameData: newUnit, gameStorage.myMoney(), .none) return newUnit } - - func myHighScore() -> Int { - return gameStorage.myHighScore() +} + +extension Storage: GameMoneyManagable { + func availableMoney() -> Observable { + return gameStorage.availableMoney() } func raiseMoney(by amount: Int) { gameStorage.raiseMoney(by: amount) backUpCenter.save(gameData: .none, gameStorage.myMoney(), .none) } +} + +extension Storage: HighScoreManagable { + func myHighScore() -> Int { + return gameStorage.myHighScore() + } func updateHighScore(new score: Int) -> Bool { let isUpdatable = gameStorage.updateHighScore(new: score) if isUpdatable { backUpCenter.save(gameData: .none, .none, score) } return isUpdatable } +} + +extension Storage: RewardManagable { + func availableRewards() -> Observable<[ShopItem]> { + return adStorage.availableItems() + } - func save() { - let currentData = NetworkDTO(units: gameStorage.itemList(), - money: gameStorage.myMoney(), - score: gameStorage.myHighScore(), - ads: adStorage.currentInformation(), - date: Date()) - backUpCenter.save(gameData: currentData) + func setNewRewardsIfPossible() -> Observable { + return adStorage.setNewRewardsIfPossible(with: .none) + } + + func rewardNeedsToBeGiven(with finishedAd: GADRewardedAd?) -> Int { + if let finishedAd = finishedAd { + adStorage.adDidFinished(finishedAd) + } else { + adStorage.giftTaken() + } + let reward = ShopSetting.reward() + gameStorage.raiseMoney(by: reward) + backUpCenter.save(gameData: .none, gameStorage.myMoney(), .none) + return reward } } diff --git a/FullStackCodingBot/FullStackCodingBot/Service/Storage/StorageType.swift b/FullStackCodingBot/FullStackCodingBot/Service/Storage/StorageProtocols.swift similarity index 62% rename from FullStackCodingBot/FullStackCodingBot/Service/Storage/StorageType.swift rename to FullStackCodingBot/FullStackCodingBot/Service/Storage/StorageProtocols.swift index 235f35d..0698945 100644 --- a/FullStackCodingBot/FullStackCodingBot/Service/Storage/StorageType.swift +++ b/FullStackCodingBot/FullStackCodingBot/Service/Storage/StorageProtocols.swift @@ -2,27 +2,30 @@ import Foundation import RxSwift import GoogleMobileAds -protocol StorageType { - +typealias StorageType = GameDataManagable & GameItemManagable & GameMoneyManagable & HighScoreManagable & RewardManagable + +protocol GameDataManagable { func initializeData(using uuid: String?, isFirstLaunched: Bool) -> Observable - - // Shop - func availableRewards() -> Observable<[ShopItem]> - func availableMoney() -> Observable // + Item - func setNewRewardsIfPossible() -> Observable - func rewardNeedsToBeGiven(with finishedAd: GADRewardedAd?) -> Int - - // Item + func save() +} + +protocol GameItemManagable { func itemList() -> [Unit] func raiseLevel(of unit: Unit, using money: Int) -> Unit - - // Game - func myHighScore() -> Int - - // GameOver +} + +protocol GameMoneyManagable { + func availableMoney() -> Observable func raiseMoney(by amount: Int) +} + +protocol HighScoreManagable { + func myHighScore() -> Int func updateHighScore(new score: Int) -> Bool - - // Background - func save() +} + +protocol RewardManagable { + func availableRewards() -> Observable<[ShopItem]> + func setNewRewardsIfPossible() -> Observable + func rewardNeedsToBeGiven(with finishedAd: GADRewardedAd?) -> Int } diff --git a/FullStackCodingBot/FullStackCodingBot/ViewModel/AdViewModel.swift b/FullStackCodingBot/FullStackCodingBot/ViewModel/AdViewModel.swift deleted file mode 100644 index 5c38f66..0000000 --- a/FullStackCodingBot/FullStackCodingBot/ViewModel/AdViewModel.swift +++ /dev/null @@ -1,8 +0,0 @@ -import Foundation - -// Ad 부분 인터페이스를 나누는 게 나을까? -class AdViewModel: CommonViewModel { - override init(sceneCoordinator: SceneCoordinatorType, storage: StorageType) { - super.init(sceneCoordinator: sceneCoordinator, storage: storage) - } -} diff --git a/FullStackCodingBot/FullStackCodingBot/ViewModel/CommonViewModel.swift b/FullStackCodingBot/FullStackCodingBot/ViewModel/CommonViewModel.swift index 0a38487..43de40f 100644 --- a/FullStackCodingBot/FullStackCodingBot/ViewModel/CommonViewModel.swift +++ b/FullStackCodingBot/FullStackCodingBot/ViewModel/CommonViewModel.swift @@ -3,10 +3,8 @@ import Foundation class CommonViewModel: NSObject { let sceneCoordinator: SceneCoordinatorType - let storage: StorageType - init(sceneCoordinator: SceneCoordinatorType, storage: StorageType) { + init(sceneCoordinator: SceneCoordinatorType) { self.sceneCoordinator = sceneCoordinator - self.storage = storage } } diff --git a/FullStackCodingBot/FullStackCodingBot/ViewModel/GameOverViewModel.swift b/FullStackCodingBot/FullStackCodingBot/ViewModel/GameOverViewModel.swift index 840cfd5..fdc23b2 100644 --- a/FullStackCodingBot/FullStackCodingBot/ViewModel/GameOverViewModel.swift +++ b/FullStackCodingBot/FullStackCodingBot/ViewModel/GameOverViewModel.swift @@ -5,6 +5,7 @@ import GameKit final class GameOverViewModel: CommonViewModel { + private let storage: HighScoreManagable & GameMoneyManagable private var gameStoryManager: GameStoryManager private(set) var newScript = BehaviorRelay(value: nil) private(set) var rankInfo = BehaviorRelay(value: "") @@ -27,15 +28,16 @@ final class GameOverViewModel: CommonViewModel { }() init(sceneCoordinator: SceneCoordinatorType, - storage: StorageType, + storage: HighScoreManagable & GameMoneyManagable, finalScore: Int, newGameStatus: BehaviorRelay, gameStoryManager: GameStoryManager = GameStoryManager()) { + self.storage = storage self.scoreInfo.accept(finalScore) self.moneyInfo.accept(finalScore/10) self.newGameStatus = newGameStatus self.gameStoryManager = gameStoryManager - super.init(sceneCoordinator: sceneCoordinator, storage: storage) + super.init(sceneCoordinator: sceneCoordinator) } func execute() { diff --git a/FullStackCodingBot/FullStackCodingBot/ViewModel/GameViewModel.swift b/FullStackCodingBot/FullStackCodingBot/ViewModel/GameViewModel.swift index 40a9ff9..24a44e2 100644 --- a/FullStackCodingBot/FullStackCodingBot/ViewModel/GameViewModel.swift +++ b/FullStackCodingBot/FullStackCodingBot/ViewModel/GameViewModel.swift @@ -6,6 +6,7 @@ import Action final class GameViewModel: CommonViewModel { // Helper Objects + private let storage: HighScoreManagable & GameItemManagable private var gameSoundStation: GameSoundEffectStation private var gameUnitManager: GameUnitManagerType private var timeManager: TimeManagerType @@ -33,15 +34,16 @@ final class GameViewModel: CommonViewModel { } init(sceneCoordinator: SceneCoordinatorType, - storage: StorageType, + storage: HighScoreManagable & GameItemManagable, pauseAction: CocoaAction? = nil, gameUnitManager: GameUnitManagerType, timeManager: TimeManagerType = TimeManager(), gameSoundStation: GameSoundEffectStation = GameSoundEffectStation()) { + self.storage = storage self.gameUnitManager = gameUnitManager self.timeManager = timeManager self.gameSoundStation = gameSoundStation - super.init(sceneCoordinator: sceneCoordinator, storage: storage) + super.init(sceneCoordinator: sceneCoordinator) } } @@ -204,7 +206,10 @@ private extension GameViewModel { @discardableResult private func toGameOverScene() -> Completable { let currentScore = try? currentScore.value() - let gameOverViewModel = GameOverViewModel(sceneCoordinator: sceneCoordinator, storage: storage, finalScore: currentScore ?? 0, newGameStatus: newGameStatus) + let gameOverViewModel = GameOverViewModel(sceneCoordinator: sceneCoordinator, + storage: storage as! (GameMoneyManagable & HighScoreManagable), + finalScore: currentScore ?? 0, + newGameStatus: newGameStatus) let gameOverScene = GameScene.gameOver(gameOverViewModel) return self.sceneCoordinator.transition(to: gameOverScene, using: .pop, with: StoryboardType.game, animated: true) } @@ -212,7 +217,7 @@ private extension GameViewModel { @discardableResult private func toPauseScene() -> Completable { let currentScore = try? currentScore.value() - let pauseViewModel = PauseViewModel(sceneCoordinator: sceneCoordinator, storage: storage, currentScore: currentScore ?? 0, newGameStatus: newGameStatus) + let pauseViewModel = PauseViewModel(sceneCoordinator: sceneCoordinator, currentScore: currentScore ?? 0, newGameStatus: newGameStatus) let pauseScene = GameScene.pause(pauseViewModel) return self.sceneCoordinator.transition(to: pauseScene, using: .fullScreen, with: StoryboardType.game, animated: false) } diff --git a/FullStackCodingBot/FullStackCodingBot/ViewModel/HowToPlayViewModel.swift b/FullStackCodingBot/FullStackCodingBot/ViewModel/HowToPlayViewModel.swift index ecfca50..112a998 100644 --- a/FullStackCodingBot/FullStackCodingBot/ViewModel/HowToPlayViewModel.swift +++ b/FullStackCodingBot/FullStackCodingBot/ViewModel/HowToPlayViewModel.swift @@ -9,14 +9,14 @@ final class HowToPlayViewModel: CommonViewModel { let currentPage = BehaviorRelay(value: 0) let currentManual = BehaviorRelay(value: Manual.all[0]) - init(sceneCoordinator: SceneCoordinatorType, storage: StorageType, cancelAction: CocoaAction? = nil) { + init(sceneCoordinator: SceneCoordinatorType, cancelAction: CocoaAction? = nil) { self.cancelAction = CocoaAction { if let action = cancelAction { action.execute(()) } return sceneCoordinator.close(animated: true).asObservable().map { _ in } } - super.init(sceneCoordinator: sceneCoordinator, storage: storage) + super.init(sceneCoordinator: sceneCoordinator) } func moveToPage(from direction: DirectionType) { diff --git a/FullStackCodingBot/FullStackCodingBot/ViewModel/ItemViewModel.swift b/FullStackCodingBot/FullStackCodingBot/ViewModel/ItemViewModel.swift index e8ec06b..08965d4 100644 --- a/FullStackCodingBot/FullStackCodingBot/ViewModel/ItemViewModel.swift +++ b/FullStackCodingBot/FullStackCodingBot/ViewModel/ItemViewModel.swift @@ -5,6 +5,8 @@ import Action final class ItemViewModel: CommonViewModel { + private let storage: GameItemManagable & GameMoneyManagable + var defaultUnit: Unit { return storage.itemList().first! } @@ -25,9 +27,10 @@ final class ItemViewModel: CommonViewModel { private let soundEffectStation: SingleSoundEffectStation init(sceneCoordinator: SceneCoordinatorType, - storage: StorageType, + storage: GameItemManagable & GameMoneyManagable, cancelAction: CocoaAction? = nil, soundEffectType: MainSoundEffect = .upgrade) { + self.storage = storage self.cancelAction = CocoaAction { if let action = cancelAction { action.execute(()) @@ -35,7 +38,7 @@ final class ItemViewModel: CommonViewModel { return sceneCoordinator.close(animated: true).asObservable().map { _ in } } self.soundEffectStation = SingleSoundEffectStation(soundEffectType: soundEffectType) - super.init(sceneCoordinator: sceneCoordinator, storage: storage) + super.init(sceneCoordinator: sceneCoordinator) } func checkLevelUpPrice() { diff --git a/FullStackCodingBot/FullStackCodingBot/ViewModel/MainViewModel.swift b/FullStackCodingBot/FullStackCodingBot/ViewModel/MainViewModel.swift index 92c723c..d77fb36 100644 --- a/FullStackCodingBot/FullStackCodingBot/ViewModel/MainViewModel.swift +++ b/FullStackCodingBot/FullStackCodingBot/ViewModel/MainViewModel.swift @@ -5,8 +5,9 @@ import Firebase import FirebaseAuth import GameKit -final class MainViewModel: AdViewModel { +final class MainViewModel: CommonViewModel { + private let storage: GameDataManagable & RewardManagable private var settingInfo: SettingInformation private let userDefaults = UserDefaults.standard @@ -14,9 +15,10 @@ final class MainViewModel: AdViewModel { let storageDidSetup = BehaviorRelay(value: false) private(set) var rewardAvailable = BehaviorRelay(value: false) - init(sceneCoordinator: SceneCoordinatorType, storage: StorageType, settings: SettingInformation) { + init(sceneCoordinator: SceneCoordinatorType, storage: GameDataManagable & RewardManagable, settings: SettingInformation) { self.settingInfo = settings - super.init(sceneCoordinator: sceneCoordinator, storage: storage) + self.storage = storage + super.init(sceneCoordinator: sceneCoordinator) bindRewardStates() setupAppleGameCenterLogin() @@ -35,23 +37,27 @@ final class MainViewModel: AdViewModel { switch viewController { case .giftVC: - let shopViewModel = ShopViewModel(sceneCoordinator: self.sceneCoordinator, storage: self.storage) + let shopViewModel = ShopViewModel(sceneCoordinator: sceneCoordinator, + storage: storage as! (GameMoneyManagable & RewardManagable)) let shopScene = MainScene.shop(shopViewModel) self.sceneCoordinator.transition(to: shopScene, using: .fullScreen, with: StoryboardType.main, animated: true) case .rankVC: - let rankViewModel = RankViewModel(sceneCoordinator: self.sceneCoordinator, storage: self.storage) + let rankViewModel = RankViewModel(sceneCoordinator: sceneCoordinator) let rankScene = MainScene.rank(rankViewModel) self.sceneCoordinator.transition(to: rankScene, using: .fullScreen, with: StoryboardType.main, animated: true) case .itemVC: - let itemViewModel = ItemViewModel(sceneCoordinator: self.sceneCoordinator, storage: self.storage) + let itemViewModel = ItemViewModel(sceneCoordinator: sceneCoordinator, + storage: storage as! (GameItemManagable & GameMoneyManagable)) let itemScene = MainScene.item(itemViewModel) self.sceneCoordinator.transition(to: itemScene, using: .fullScreen, with: StoryboardType.main, animated: true) case .gameVC: let gameUnitManager = GameUnitManager(allKinds: Unit.initialValues()) - let gameViewModel = GameViewModel(sceneCoordinator: self.sceneCoordinator, storage: self.storage, gameUnitManager: gameUnitManager) + let gameViewModel = GameViewModel(sceneCoordinator: sceneCoordinator, + storage: storage as! (HighScoreManagable & GameItemManagable), + gameUnitManager: gameUnitManager) let gameScene = GameScene.game(gameViewModel) self.sceneCoordinator.transition(to: gameScene, using: .fullScreen, with: StoryboardType.game, animated: true) @@ -60,12 +66,14 @@ final class MainViewModel: AdViewModel { self.sceneCoordinator.transition(to: settingScene, using: .overCurrent, with: StoryboardType.main, animated: true) case .storyVC: - let storyViewModel = StoryViewModel(sceneCoordinator: sceneCoordinator, storage: storage, settings: settingInfo, isFirstTimePlay: false) + let storyViewModel = StoryViewModel(sceneCoordinator: sceneCoordinator, + settings: settingInfo, + isFirstTimePlay: false) let storyScene = GameHelperScene.story(storyViewModel) self.sceneCoordinator.transition(to: storyScene, using: .fullScreen, with: StoryboardType.main, animated: true) case .howToVC: - let howToViewModel = HowToPlayViewModel(sceneCoordinator: sceneCoordinator, storage: storage) + let howToViewModel = HowToPlayViewModel(sceneCoordinator: sceneCoordinator) let howToScene = GameHelperScene.howToPlay(howToViewModel) self.sceneCoordinator.transition(to: howToScene, using: .fullScreen, with: StoryboardType.main, animated: true) } diff --git a/FullStackCodingBot/FullStackCodingBot/ViewModel/PauseViewModel.swift b/FullStackCodingBot/FullStackCodingBot/ViewModel/PauseViewModel.swift index 8459fec..8a975b6 100644 --- a/FullStackCodingBot/FullStackCodingBot/ViewModel/PauseViewModel.swift +++ b/FullStackCodingBot/FullStackCodingBot/ViewModel/PauseViewModel.swift @@ -11,10 +11,10 @@ final class PauseViewModel: CommonViewModel { return currentScore.map {String($0)}.asDriver(onErrorJustReturn: "") }() - init(sceneCoordinator: SceneCoordinatorType, storage: StorageType, currentScore: Int, newGameStatus: BehaviorRelay) { + init(sceneCoordinator: SceneCoordinatorType, currentScore: Int, newGameStatus: BehaviorRelay) { self.newGameStatus = newGameStatus self.currentScore.accept(currentScore) - super.init(sceneCoordinator: sceneCoordinator, storage: storage) + super.init(sceneCoordinator: sceneCoordinator) } func makeMoveAction(to viewController: PauseActionType) { diff --git a/FullStackCodingBot/FullStackCodingBot/ViewModel/RankViewModel.swift b/FullStackCodingBot/FullStackCodingBot/ViewModel/RankViewModel.swift index f82d073..2867043 100644 --- a/FullStackCodingBot/FullStackCodingBot/ViewModel/RankViewModel.swift +++ b/FullStackCodingBot/FullStackCodingBot/ViewModel/RankViewModel.swift @@ -6,14 +6,14 @@ final class RankViewModel: CommonViewModel { let cancelAction: CocoaAction - init(sceneCoordinator: SceneCoordinatorType, storage: StorageType, cancelAction: CocoaAction? = nil) { + init(sceneCoordinator: SceneCoordinatorType, cancelAction: CocoaAction? = nil) { self.cancelAction = CocoaAction { if let action = cancelAction { action.execute(()) } return sceneCoordinator.close(animated: true).asObservable().map { _ in } } - super.init(sceneCoordinator: sceneCoordinator, storage: storage) + super.init(sceneCoordinator: sceneCoordinator) } } diff --git a/FullStackCodingBot/FullStackCodingBot/ViewModel/ShopViewModel.swift b/FullStackCodingBot/FullStackCodingBot/ViewModel/ShopViewModel.swift index d5ffab9..701b7dc 100644 --- a/FullStackCodingBot/FullStackCodingBot/ViewModel/ShopViewModel.swift +++ b/FullStackCodingBot/FullStackCodingBot/ViewModel/ShopViewModel.swift @@ -5,8 +5,9 @@ import Action import Firebase import GoogleMobileAds -final class ShopViewModel: AdViewModel { +final class ShopViewModel: CommonViewModel { + private let storage: RewardManagable & GameMoneyManagable let cancelAction: CocoaAction var itemStorage: Driver<[ShopItem]> { @@ -22,9 +23,10 @@ final class ShopViewModel: AdViewModel { private let soundEffectStation: SingleSoundEffectStation init(sceneCoordinator: SceneCoordinatorType, - storage: StorageType, + storage: RewardManagable & GameMoneyManagable, cancelAction: CocoaAction? = nil, soundEffectType: MainSoundEffect = .reward) { + self.storage = storage self.cancelAction = CocoaAction { if let action = cancelAction { action.execute(()) @@ -32,7 +34,7 @@ final class ShopViewModel: AdViewModel { return sceneCoordinator.close(animated: true).asObservable().map { _ in } } self.soundEffectStation = SingleSoundEffectStation(soundEffectType: soundEffectType) - super.init(sceneCoordinator: sceneCoordinator, storage: storage) + super.init(sceneCoordinator: sceneCoordinator) } func execute() { diff --git a/FullStackCodingBot/FullStackCodingBot/ViewModel/StoryViewModel.swift b/FullStackCodingBot/FullStackCodingBot/ViewModel/StoryViewModel.swift index 878b771..abc2992 100644 --- a/FullStackCodingBot/FullStackCodingBot/ViewModel/StoryViewModel.swift +++ b/FullStackCodingBot/FullStackCodingBot/ViewModel/StoryViewModel.swift @@ -2,7 +2,7 @@ import Foundation import RxSwift import RxCocoa -final class StoryViewModel: AdViewModel { +final class StoryViewModel: CommonViewModel { lazy var script = BehaviorRelay(value: storyManager.current()) private var storyManager: StoryManager @@ -10,14 +10,13 @@ final class StoryViewModel: AdViewModel { private let isFirstTimePlay: Bool init(sceneCoordinator: SceneCoordinatorType, - storage: StorageType, settings: SettingInformation, storyManger: StoryManager = StoryManager(), isFirstTimePlay: Bool = true) { self.settings = settings self.storyManager = storyManger self.isFirstTimePlay = isFirstTimePlay - super.init(sceneCoordinator: sceneCoordinator, storage: storage) + super.init(sceneCoordinator: sceneCoordinator) } func setupStoryTimer() { @@ -44,6 +43,7 @@ final class StoryViewModel: AdViewModel { } private func makeMoveActionToMain() { + let storage = Storage() // 임시 let mainViewModel = MainViewModel(sceneCoordinator: sceneCoordinator, storage: storage, settings: settings) let mainScene = MainScene.main(mainViewModel) self.sceneCoordinator.transition(to: mainScene, using: .root, with: StoryboardType.main, animated: true) diff --git a/FullStackCodingBot/Podfile.lock b/FullStackCodingBot/Podfile.lock index 8a39c99..6484602 100644 --- a/FullStackCodingBot/Podfile.lock +++ b/FullStackCodingBot/Podfile.lock @@ -173,4 +173,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 9dcb07048230100d40f32bab60eefa35b9442eae -COCOAPODS: 1.10.1 +COCOAPODS: 1.10.2