diff --git a/iOS/baseball-game/baseball-game.xcodeproj/project.pbxproj b/iOS/baseball-game/baseball-game.xcodeproj/project.pbxproj index d9def672c..466f96683 100644 --- a/iOS/baseball-game/baseball-game.xcodeproj/project.pbxproj +++ b/iOS/baseball-game/baseball-game.xcodeproj/project.pbxproj @@ -7,23 +7,65 @@ objects = { /* Begin PBXBuildFile section */ + AE5C79AF2640E8710075EBC3 /* GameCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE5C79AD2640E8710075EBC3 /* GameCell.swift */; }; + AE5C79B02640E8710075EBC3 /* GameCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = AE5C79AE2640E8710075EBC3 /* GameCell.xib */; }; + AE5C79B2264127300075EBC3 /* Game.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE5C79B1264127300075EBC3 /* Game.swift */; }; + AE5C79B426412B830075EBC3 /* Network.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE5C79B326412B830075EBC3 /* Network.swift */; }; + AE5C79B7264138E70075EBC3 /* SelectViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE5C79B6264138E70075EBC3 /* SelectViewModel.swift */; }; + AE7A1542263FE4DE005EBAB9 /* SelectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE7A1541263FE4DE005EBAB9 /* SelectionViewController.swift */; }; + AEFE32DA2643971B0077AA5F /* LoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEFE32D92643971B0077AA5F /* LoginViewController.swift */; }; E4AA6883263FDDA500139BD6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4AA6882263FDDA500139BD6 /* AppDelegate.swift */; }; E4AA6885263FDDA500139BD6 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4AA6884263FDDA500139BD6 /* SceneDelegate.swift */; }; - E4AA6887263FDDA500139BD6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4AA6886263FDDA500139BD6 /* ViewController.swift */; }; - E4AA688A263FDDA500139BD6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E4AA6888263FDDA500139BD6 /* Main.storyboard */; }; + E4AA6887263FDDA500139BD6 /* GamePlayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4AA6886263FDDA500139BD6 /* GamePlayViewController.swift */; }; E4AA688C263FDDA800139BD6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E4AA688B263FDDA800139BD6 /* Assets.xcassets */; }; E4AA688F263FDDA800139BD6 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E4AA688D263FDDA800139BD6 /* LaunchScreen.storyboard */; }; + E4FE76D82641242400151B35 /* SelectPitcherViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4FE76D72641242400151B35 /* SelectPitcherViewController.swift */; }; + E4FE76DA26412ACD00151B35 /* GameManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4FE76D926412ACD00151B35 /* GameManager.swift */; }; + E4FE76DF26438ABC00151B35 /* PitchListTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4FE76DE26438ABC00151B35 /* PitchListTableViewCell.swift */; }; + E4FE76E12643B0AC00151B35 /* GamePlay.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E4FE76E02643B0AC00151B35 /* GamePlay.storyboard */; }; + E4FE76E62643B57400151B35 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E4FE76E42643B57400151B35 /* Main.storyboard */; }; + E4FE76EB2643BDA800151B35 /* GamePlayViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4FE76EA2643BDA800151B35 /* GamePlayViewModel.swift */; }; + E4FE76ED2643DA3400151B35 /* Turn.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4FE76EC2643DA3400151B35 /* Turn.swift */; }; + E4FE76EF2643DA4600151B35 /* Player.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4FE76EE2643DA4600151B35 /* Player.swift */; }; + E4FE76F12643DA5600151B35 /* Pitch.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4FE76F02643DA5600151B35 /* Pitch.swift */; }; + E4FE76F32643DA7300151B35 /* GameManagable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4FE76F22643DA7300151B35 /* GameManagable.swift */; }; + E4FE76F8264407E600151B35 /* TeamScoreView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4FE76F7264407E600151B35 /* TeamScoreView.swift */; }; + E4FE76FA2644108900151B35 /* PitcherInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4FE76F92644108900151B35 /* PitcherInfoView.swift */; }; + E4FE76FC2644136600151B35 /* BatterInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4FE76FB2644136600151B35 /* BatterInfoView.swift */; }; + E4FE77062644DCBC00151B35 /* Team.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4FE77052644DCBC00151B35 /* Team.swift */; }; + E4FE77082644DCC500151B35 /* GameInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4FE77072644DCC500151B35 /* GameInfo.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + AE5C79AD2640E8710075EBC3 /* GameCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameCell.swift; sourceTree = ""; }; + AE5C79AE2640E8710075EBC3 /* GameCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GameCell.xib; sourceTree = ""; }; + AE5C79B1264127300075EBC3 /* Game.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Game.swift; sourceTree = ""; }; + AE5C79B326412B830075EBC3 /* Network.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Network.swift; sourceTree = ""; }; + AE5C79B6264138E70075EBC3 /* SelectViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectViewModel.swift; sourceTree = ""; }; + AE7A1541263FE4DE005EBAB9 /* SelectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectionViewController.swift; sourceTree = ""; }; + AEFE32D92643971B0077AA5F /* LoginViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewController.swift; sourceTree = ""; }; E4AA687F263FDDA500139BD6 /* baseball-game.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "baseball-game.app"; sourceTree = BUILT_PRODUCTS_DIR; }; E4AA6882263FDDA500139BD6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; E4AA6884263FDDA500139BD6 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - E4AA6886263FDDA500139BD6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - E4AA6889263FDDA500139BD6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + E4AA6886263FDDA500139BD6 /* GamePlayViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GamePlayViewController.swift; sourceTree = ""; }; E4AA688B263FDDA800139BD6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; E4AA688E263FDDA800139BD6 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; E4AA6890263FDDA900139BD6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E4FE76D72641242400151B35 /* SelectPitcherViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectPitcherViewController.swift; sourceTree = ""; }; + E4FE76D926412ACD00151B35 /* GameManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameManager.swift; sourceTree = ""; }; + E4FE76DE26438ABC00151B35 /* PitchListTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PitchListTableViewCell.swift; sourceTree = ""; }; + E4FE76E02643B0AC00151B35 /* GamePlay.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = GamePlay.storyboard; sourceTree = ""; }; + E4FE76E52643B57400151B35 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + E4FE76EA2643BDA800151B35 /* GamePlayViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GamePlayViewModel.swift; sourceTree = ""; }; + E4FE76EC2643DA3400151B35 /* Turn.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Turn.swift; sourceTree = ""; }; + E4FE76EE2643DA4600151B35 /* Player.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Player.swift; sourceTree = ""; }; + E4FE76F02643DA5600151B35 /* Pitch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Pitch.swift; sourceTree = ""; }; + E4FE76F22643DA7300151B35 /* GameManagable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameManagable.swift; sourceTree = ""; }; + E4FE76F7264407E600151B35 /* TeamScoreView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TeamScoreView.swift; sourceTree = ""; }; + E4FE76F92644108900151B35 /* PitcherInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PitcherInfoView.swift; sourceTree = ""; }; + E4FE76FB2644136600151B35 /* BatterInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatterInfoView.swift; sourceTree = ""; }; + E4FE77052644DCBC00151B35 /* Team.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Team.swift; sourceTree = ""; }; + E4FE77072644DCC500151B35 /* GameInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameInfo.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -37,6 +79,26 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + AE5C79B526412B900075EBC3 /* Network */ = { + isa = PBXGroup; + children = ( + AE5C79B326412B830075EBC3 /* Network.swift */, + ); + path = Network; + sourceTree = ""; + }; + AE7A1543263FE4FE005EBAB9 /* Selection */ = { + isa = PBXGroup; + children = ( + AEFE32D92643971B0077AA5F /* LoginViewController.swift */, + AE7A1541263FE4DE005EBAB9 /* SelectionViewController.swift */, + E4FE77012644DC4200151B35 /* View */, + E4FE77022644DC4B00151B35 /* Model */, + E4FE77032644DC7700151B35 /* ViewModel */, + ); + path = Selection; + sourceTree = ""; + }; E4AA6876263FDDA500139BD6 = { isa = PBXGroup; children = ( @@ -57,8 +119,10 @@ isa = PBXGroup; children = ( E4AA6896263FDDD400139BD6 /* AppCycle */, - E4AA6886263FDDA500139BD6 /* ViewController.swift */, - E4AA6888263FDDA500139BD6 /* Main.storyboard */, + E4FE76E42643B57400151B35 /* Main.storyboard */, + AE7A1543263FE4FE005EBAB9 /* Selection */, + E4FE76E72643B5DD00151B35 /* GamePlay */, + AE5C79B526412B900075EBC3 /* Network */, E4AA688B263FDDA800139BD6 /* Assets.xcassets */, E4AA688D263FDDA800139BD6 /* LaunchScreen.storyboard */, E4AA6890263FDDA900139BD6 /* Info.plist */, @@ -75,6 +139,85 @@ path = AppCycle; sourceTree = ""; }; + E4FE76E72643B5DD00151B35 /* GamePlay */ = { + isa = PBXGroup; + children = ( + E4AA6886263FDDA500139BD6 /* GamePlayViewController.swift */, + E4FE76F6264407BA00151B35 /* View */, + E4FE76E92643B67000151B35 /* Model */, + E4FE77042644DC9E00151B35 /* ViewModel */, + E4FE76E82643B60B00151B35 /* SelectPitcher */, + ); + path = GamePlay; + sourceTree = ""; + }; + E4FE76E82643B60B00151B35 /* SelectPitcher */ = { + isa = PBXGroup; + children = ( + E4FE76D72641242400151B35 /* SelectPitcherViewController.swift */, + ); + path = SelectPitcher; + sourceTree = ""; + }; + E4FE76E92643B67000151B35 /* Model */ = { + isa = PBXGroup; + children = ( + E4FE76F22643DA7300151B35 /* GameManagable.swift */, + E4FE76D926412ACD00151B35 /* GameManager.swift */, + E4FE76EC2643DA3400151B35 /* Turn.swift */, + E4FE76EE2643DA4600151B35 /* Player.swift */, + E4FE76F02643DA5600151B35 /* Pitch.swift */, + ); + path = Model; + sourceTree = ""; + }; + E4FE76F6264407BA00151B35 /* View */ = { + isa = PBXGroup; + children = ( + E4FE76E02643B0AC00151B35 /* GamePlay.storyboard */, + E4FE76F7264407E600151B35 /* TeamScoreView.swift */, + E4FE76F92644108900151B35 /* PitcherInfoView.swift */, + E4FE76FB2644136600151B35 /* BatterInfoView.swift */, + E4FE76DE26438ABC00151B35 /* PitchListTableViewCell.swift */, + ); + path = View; + sourceTree = ""; + }; + E4FE77012644DC4200151B35 /* View */ = { + isa = PBXGroup; + children = ( + AE5C79AD2640E8710075EBC3 /* GameCell.swift */, + AE5C79AE2640E8710075EBC3 /* GameCell.xib */, + ); + path = View; + sourceTree = ""; + }; + E4FE77022644DC4B00151B35 /* Model */ = { + isa = PBXGroup; + children = ( + AE5C79B1264127300075EBC3 /* Game.swift */, + E4FE77052644DCBC00151B35 /* Team.swift */, + E4FE77072644DCC500151B35 /* GameInfo.swift */, + ); + path = Model; + sourceTree = ""; + }; + E4FE77032644DC7700151B35 /* ViewModel */ = { + isa = PBXGroup; + children = ( + AE5C79B6264138E70075EBC3 /* SelectViewModel.swift */, + ); + path = ViewModel; + sourceTree = ""; + }; + E4FE77042644DC9E00151B35 /* ViewModel */ = { + isa = PBXGroup; + children = ( + E4FE76EA2643BDA800151B35 /* GamePlayViewModel.swift */, + ); + path = ViewModel; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -133,8 +276,10 @@ buildActionMask = 2147483647; files = ( E4AA688F263FDDA800139BD6 /* LaunchScreen.storyboard in Resources */, + E4FE76E62643B57400151B35 /* Main.storyboard in Resources */, + E4FE76E12643B0AC00151B35 /* GamePlay.storyboard in Resources */, E4AA688C263FDDA800139BD6 /* Assets.xcassets in Resources */, - E4AA688A263FDDA500139BD6 /* Main.storyboard in Resources */, + AE5C79B02640E8710075EBC3 /* GameCell.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -145,29 +290,49 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E4AA6887263FDDA500139BD6 /* ViewController.swift in Sources */, + E4FE76EB2643BDA800151B35 /* GamePlayViewModel.swift in Sources */, + E4AA6887263FDDA500139BD6 /* GamePlayViewController.swift in Sources */, + E4FE76F8264407E600151B35 /* TeamScoreView.swift in Sources */, + E4FE76FA2644108900151B35 /* PitcherInfoView.swift in Sources */, + E4FE76DA26412ACD00151B35 /* GameManager.swift in Sources */, + E4FE76DF26438ABC00151B35 /* PitchListTableViewCell.swift in Sources */, + E4FE76D82641242400151B35 /* SelectPitcherViewController.swift in Sources */, + AEFE32DA2643971B0077AA5F /* LoginViewController.swift in Sources */, + E4FE77062644DCBC00151B35 /* Team.swift in Sources */, + AE5C79AF2640E8710075EBC3 /* GameCell.swift in Sources */, + E4FE76ED2643DA3400151B35 /* Turn.swift in Sources */, + AE5C79B2264127300075EBC3 /* Game.swift in Sources */, + E4AA6887263FDDA500139BD6 /* GamePlayViewController.swift in Sources */, + AE7A1542263FE4DE005EBAB9 /* SelectionViewController.swift in Sources */, + E4FE76FC2644136600151B35 /* BatterInfoView.swift in Sources */, + AE5C79B7264138E70075EBC3 /* SelectViewModel.swift in Sources */, E4AA6883263FDDA500139BD6 /* AppDelegate.swift in Sources */, + AE5C79B426412B830075EBC3 /* Network.swift in Sources */, + E4FE76EF2643DA4600151B35 /* Player.swift in Sources */, + E4FE76F12643DA5600151B35 /* Pitch.swift in Sources */, + E4FE77082644DCC500151B35 /* GameInfo.swift in Sources */, E4AA6885263FDDA500139BD6 /* SceneDelegate.swift in Sources */, + E4FE76F32643DA7300151B35 /* GameManagable.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ - E4AA6888263FDDA500139BD6 /* Main.storyboard */ = { + E4AA688D263FDDA800139BD6 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( - E4AA6889263FDDA500139BD6 /* Base */, + E4AA688E263FDDA800139BD6 /* Base */, ); - name = Main.storyboard; + name = LaunchScreen.storyboard; sourceTree = ""; }; - E4AA688D263FDDA800139BD6 /* LaunchScreen.storyboard */ = { + E4FE76E42643B57400151B35 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( - E4AA688E263FDDA800139BD6 /* Base */, + E4FE76E52643B57400151B35 /* Base */, ); - name = LaunchScreen.storyboard; + name = Main.storyboard; sourceTree = ""; }; /* End PBXVariantGroup section */ diff --git a/iOS/baseball-game/baseball-game.xcodeproj/project.xcworkspace/xcuserdata/song.xcuserdatad/UserInterfaceState.xcuserstate b/iOS/baseball-game/baseball-game.xcodeproj/project.xcworkspace/xcuserdata/song.xcuserdatad/UserInterfaceState.xcuserstate index 728e7f224..32b7b4afb 100644 Binary files a/iOS/baseball-game/baseball-game.xcodeproj/project.xcworkspace/xcuserdata/song.xcuserdatad/UserInterfaceState.xcuserstate and b/iOS/baseball-game/baseball-game.xcodeproj/project.xcworkspace/xcuserdata/song.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/iOS/baseball-game/baseball-game/AppCycle/SceneDelegate.swift b/iOS/baseball-game/baseball-game/AppCycle/SceneDelegate.swift index cd7ba6719..4afbd8c90 100644 --- a/iOS/baseball-game/baseball-game/AppCycle/SceneDelegate.swift +++ b/iOS/baseball-game/baseball-game/AppCycle/SceneDelegate.swift @@ -10,6 +10,17 @@ import UIKit class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + + guard let windowScene = (scene as? UIWindowScene) else { return } + window = UIWindow(windowScene: windowScene) + let rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "LoginViewController") as LoginViewController + + let navigationViewController = UINavigationController(rootViewController: rootViewController) + + window?.rootViewController = navigationViewController + } } diff --git a/iOS/baseball-game/baseball-game/Base.lproj/Main.storyboard b/iOS/baseball-game/baseball-game/Base.lproj/Main.storyboard index 25a763858..fa2e5eaee 100644 --- a/iOS/baseball-game/baseball-game/Base.lproj/Main.storyboard +++ b/iOS/baseball-game/baseball-game/Base.lproj/Main.storyboard @@ -1,24 +1,139 @@ - + + - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOS/baseball-game/baseball-game/GamePlay/GamePlayViewController.swift b/iOS/baseball-game/baseball-game/GamePlay/GamePlayViewController.swift new file mode 100644 index 000000000..4efd378ff --- /dev/null +++ b/iOS/baseball-game/baseball-game/GamePlay/GamePlayViewController.swift @@ -0,0 +1,119 @@ +// +// ViewController.swift +// baseball-game +// +// Created by Song on 2021/05/03. +// + +import UIKit +import Combine + +class GamePlayViewController: UIViewController { + + @IBOutlet weak var pitchListTableView: UITableView! + @IBOutlet weak var pitchButton: UIButton! + @IBOutlet weak var teamScoreView: TeamScoreView! + @IBOutlet weak var inningLabel: UILabel! + @IBOutlet weak var turnLabel: UILabel! + @IBOutlet weak var pitcherInfoView: PitcherInfoView! + @IBOutlet weak var batterInfoView: PitcherInfoView! + + enum ViewID { + static let storyboard = "GamePlay" + static let controller = "gamePlay" + static let segue = "selectPitcher" + static let cell = "pitchListCell" + } + + private var gamePlayViewModel: GamePlayViewModel! + private var dataSource: UITableViewDiffableDataSource! + + private let isUserHomeSide = true + private var cancelBag = Set() + + override func viewDidLoad() { + super.viewDidLoad() + self.gamePlayViewModel = GamePlayViewModel(isUserHomeSide) + self.pitchButton.isHidden = true + gamePlayViewModel.requestGame() + configureDataSource() + bind() + } + + private func bind() { + gamePlayViewModel.$gameManager + .receive(on: DispatchQueue.main) + .sink { [weak self] gameManager in + guard let gameManager = gameManager else { return } + self?.updateViews(with: gameManager) + } + .store(in: &cancelBag) + + gamePlayViewModel.$pitches + .receive(on: DispatchQueue.main) + .sink { [weak self] pitches in + guard let pitches = pitches else { return } + self?.createSnapshot(from: pitches) + } + .store(in: &cancelBag) + + gamePlayViewModel.$error + .receive(on: DispatchQueue.main) + .sink { error in + guard let error = error else { return } + print(error) ///사용자에게 에러 표시하는 부분 미구현 + }.store(in: &cancelBag) + } + + @IBAction func pitcherChangeTouched(_ sender: Any) { + performSegue(withIdentifier: ViewID.segue, sender: nil) + } + + private func updateViews(with gameManager: GameManagable) { + teamScoreView.updateTeamNames(from: gameManager.teams()) + teamScoreView.updateScores(from: gameManager.scores()) + inningLabel.text = gameManager.inning() + pitcherInfoView.updateLabels(from: gameManager.pitcher()) + batterInfoView.updateLabels(from: gameManager.batter()) + + guard let isUserDefense = gameManager.isUserDefense() else { return } + + if isUserDefense { + self.pitchButton.isHidden = false + turnLabel.text = GameManager.Role.defense + pitcherInfoView.highlight() + batterInfoView.unhighlight() + } else { + self.pitchButton.isHidden = true + turnLabel.text = GameManager.Role.offense + pitcherInfoView.unhighlight() + batterInfoView.highlight() + } + } +} + +extension GamePlayViewController { + + private func configureDataSource() { + self.dataSource = UITableViewDiffableDataSource.init(tableView: pitchListTableView) { + (tableView, indexPath, pitch) -> UITableViewCell in + + guard let cell = self.pitchListTableView.dequeueReusableCell(withIdentifier: ViewID.cell) as? PitchListTableViewCell else { + return PitchListTableViewCell() + } + + let index = indexPath.row + cell.updateLabels(count: index, result: pitch.result, log: pitch.log) + + return cell + } + } + + private func createSnapshot(from pitches: [Pitch]) { + var snapshot = NSDiffableDataSourceSnapshot() + + snapshot.appendSections([0]) + snapshot.appendItems(pitches, toSection: 0) + self.dataSource.apply(snapshot) + } +} diff --git a/iOS/baseball-game/baseball-game/GamePlay/Model/GameManagable.swift b/iOS/baseball-game/baseball-game/GamePlay/Model/GameManagable.swift new file mode 100644 index 000000000..cbe6c5c91 --- /dev/null +++ b/iOS/baseball-game/baseball-game/GamePlay/Model/GameManagable.swift @@ -0,0 +1,24 @@ +// +// GameManagable.swift +// baseball-game +// +// Created by Song on 2021/05/06. +// + +import Foundation + +protocol GameManagable { + + func teams() -> [String: String] + + func scores() -> [String: Int] + + func inning() -> String + + func pitcher() -> Player + + func batter() -> Player + + func isUserDefense() -> Bool? + +} diff --git a/iOS/baseball-game/baseball-game/GamePlay/Model/GameManager.swift b/iOS/baseball-game/baseball-game/GamePlay/Model/GameManager.swift new file mode 100644 index 000000000..7dbc3f46d --- /dev/null +++ b/iOS/baseball-game/baseball-game/GamePlay/Model/GameManager.swift @@ -0,0 +1,77 @@ +// +// Game.swift +// baseball-game +// +// Created by Song on 2021/05/04. +// + +import Foundation + +class GameManager: Decodable { + + private var isUserHomeSide: Bool? + var turn: Turn + + init(isUserHomeSide: Bool, turn: Turn) { + self.isUserHomeSide = isUserHomeSide + self.turn = turn + } + + enum CodingKeys: String, CodingKey { + case isUserHomeSide + case turn = "game" + } + + enum Side { + static let home = "home" + static let away = "away" + } + + enum Role { + static let offense = "offense" + static let defense = "defense" + } +} + +extension GameManager: GameManagable { + + func teams() -> [String: String] { + let homeTeam = turn.home.name + let awayTeam = turn.away.name + return [Side.home: homeTeam, Side.away: awayTeam] + } + + func scores() -> [String: Int] { + let homeScore = turn.home.score + let awayScore = turn.away.score + return [Side.home: homeScore, Side.away: awayScore] + } + + func inning() -> String { + let inningInfos = turn.inning + let topOrBottom = inningInfos[1] == 1 ? "초" : "말" + return "\(inningInfos[0])회 \(topOrBottom)" + } + + func pitcher() -> Player { + return isHomeDefense() ? turn.home.player : turn.away.player + } + + func batter() -> Player { + return isHomeDefense() ? turn.away.player : turn.home.player + } + + private func isHomeDefense() -> Bool { + return turn.home.role == Role.defense + } + + func isUserDefense() -> Bool? { + guard let isUserHomeSide = isUserHomeSide else { return nil } + + if isUserHomeSide { + return isHomeDefense() + } else { + return turn.away.role == Role.defense + } + } +} diff --git a/iOS/baseball-game/baseball-game/GamePlay/Model/Pitch.swift b/iOS/baseball-game/baseball-game/GamePlay/Model/Pitch.swift new file mode 100644 index 000000000..c7acb1792 --- /dev/null +++ b/iOS/baseball-game/baseball-game/GamePlay/Model/Pitch.swift @@ -0,0 +1,22 @@ +// +// Pitch.swift +// baseball-game +// +// Created by Song on 2021/05/06. +// + +import Foundation + +struct Pitch: Decodable, Hashable { + + let id = UUID() + + var result: String + + var log: String + + enum CodingKeys: String, CodingKey { + case result = "pitch" + case log = "status" + } +} diff --git a/iOS/baseball-game/baseball-game/GamePlay/Model/Player.swift b/iOS/baseball-game/baseball-game/GamePlay/Model/Player.swift new file mode 100644 index 000000000..016ac61f1 --- /dev/null +++ b/iOS/baseball-game/baseball-game/GamePlay/Model/Player.swift @@ -0,0 +1,18 @@ +// +// Player.swift +// baseball-game +// +// Created by Song on 2021/05/06. +// + +import Foundation + +struct Player: Decodable { + + var position: String + + var name: String + + var info: String + +} diff --git a/iOS/baseball-game/baseball-game/GamePlay/Model/Turn.swift b/iOS/baseball-game/baseball-game/GamePlay/Model/Turn.swift new file mode 100644 index 000000000..dcf2366ec --- /dev/null +++ b/iOS/baseball-game/baseball-game/GamePlay/Model/Turn.swift @@ -0,0 +1,50 @@ +// +// Turn.swift +// baseball-game +// +// Created by Song on 2021/05/06. +// + +import Foundation + +struct Turn: Decodable { + + var inning: [Int] + + var home: Team + + var away: Team + + struct Team: Decodable { + + var name: String + + var score: Int + + var role: String + + var player: Player + + enum CodingKeys: String, CodingKey { + case name = "team" + case score + case role + case player + } + } + + var ballCounts: [Int] + + var baseInfo: [Bool] + + var pitches: [Pitch] + + enum CodingKeys: String, CodingKey { + case inning + case home + case away + case ballCounts + case baseInfo + case pitches = "list" + } +} diff --git a/iOS/baseball-game/baseball-game/GamePlay/SelectPitcher/SelectPitcherViewController.swift b/iOS/baseball-game/baseball-game/GamePlay/SelectPitcher/SelectPitcherViewController.swift new file mode 100644 index 000000000..bc67e088e --- /dev/null +++ b/iOS/baseball-game/baseball-game/GamePlay/SelectPitcher/SelectPitcherViewController.swift @@ -0,0 +1,39 @@ +// +// SelectPitcherViewController.swift +// baseball-game +// +// Created by Song on 2021/05/04. +// + +import UIKit + +class SelectPitcherViewController: UIViewController { + + @IBOutlet weak var pitcherCollectionView: UICollectionView! + + private let cellId = "selectPitcherCell" + + override func viewDidLoad() { + super.viewDidLoad() + pitcherCollectionView.dataSource = self + } + + @IBAction func closeTouched(_ sender: Any) { + dismiss(animated: true, completion: nil) + } + +} + +//임시 코드 - diffable로 변경 +extension SelectPitcherViewController: UICollectionViewDataSource { + + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return 10 + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) + return cell + } + +} diff --git a/iOS/baseball-game/baseball-game/GamePlay/View/BatterInfoView.swift b/iOS/baseball-game/baseball-game/GamePlay/View/BatterInfoView.swift new file mode 100644 index 000000000..04e3d80db --- /dev/null +++ b/iOS/baseball-game/baseball-game/GamePlay/View/BatterInfoView.swift @@ -0,0 +1,28 @@ +// +// BatterInfoView.swift +// baseball-game +// +// Created by Song on 2021/05/06. +// + +import UIKit + +class BatterInfoView: UIView { + + @IBOutlet weak var nameLabel: UILabel! + @IBOutlet weak var infoLabel: UILabel! + + func updateLabels(from playerInfo: Player) { + nameLabel.text = playerInfo.name + infoLabel.text = playerInfo.info + } + + func highlight() { + self.backgroundColor = .lightGray + } + + func unhighlight() { + self.backgroundColor = .white + } + +} diff --git a/iOS/baseball-game/baseball-game/GamePlay/View/GamePlay.storyboard b/iOS/baseball-game/baseball-game/GamePlay/View/GamePlay.storyboard new file mode 100644 index 000000000..b7e6b19f6 --- /dev/null +++ b/iOS/baseball-game/baseball-game/GamePlay/View/GamePlay.storyboard @@ -0,0 +1,528 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOS/baseball-game/baseball-game/GamePlay/View/PitchListTableViewCell.swift b/iOS/baseball-game/baseball-game/GamePlay/View/PitchListTableViewCell.swift new file mode 100644 index 000000000..f59e60cb9 --- /dev/null +++ b/iOS/baseball-game/baseball-game/GamePlay/View/PitchListTableViewCell.swift @@ -0,0 +1,30 @@ +// +// PitchListTableViewCell.swift +// baseball-game +// +// Created by Song on 2021/05/06. +// + +import UIKit + +class PitchListTableViewCell: UITableViewCell { + + @IBOutlet weak var countLabel: UILabel! + @IBOutlet weak var resultLabel: UILabel! + @IBOutlet weak var logLabel: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + } + + func updateLabels(count: Int, result: String, log: String) { + self.countLabel.text = "\(count)" + self.resultLabel.text = result + self.logLabel.text = log + } + +} diff --git a/iOS/baseball-game/baseball-game/GamePlay/View/PitcherInfoView.swift b/iOS/baseball-game/baseball-game/GamePlay/View/PitcherInfoView.swift new file mode 100644 index 000000000..6c90212a3 --- /dev/null +++ b/iOS/baseball-game/baseball-game/GamePlay/View/PitcherInfoView.swift @@ -0,0 +1,28 @@ +// +// PlayerInfoView.swift +// baseball-game +// +// Created by Song on 2021/05/06. +// + +import UIKit + +class PitcherInfoView: UIView { + + @IBOutlet weak var nameLabel: UILabel! + @IBOutlet weak var infoLabel: UILabel! + + func updateLabels(from playerInfo: Player) { + nameLabel.text = playerInfo.name + infoLabel.text = playerInfo.info + } + + func highlight() { + self.backgroundColor = .lightGray + } + + func unhighlight() { + self.backgroundColor = .white + } + +} diff --git a/iOS/baseball-game/baseball-game/GamePlay/View/TeamScoreView.swift b/iOS/baseball-game/baseball-game/GamePlay/View/TeamScoreView.swift new file mode 100644 index 000000000..60817f891 --- /dev/null +++ b/iOS/baseball-game/baseball-game/GamePlay/View/TeamScoreView.swift @@ -0,0 +1,32 @@ +// +// TeamScoreView.swift +// baseball-game +// +// Created by Song on 2021/05/06. +// + +import UIKit + +class TeamScoreView: UIView { + + @IBOutlet weak var homeTeamLabel: UILabel! + @IBOutlet weak var homeScoreLabel: UILabel! + + @IBOutlet weak var awayTeamLabel: UILabel! + @IBOutlet weak var awayScoreLabel: UILabel! + + func updateTeamNames(from names: [String: String]) { + let homeName = names[GameManager.Side.home]! + let awayName = names[GameManager.Side.away]! + homeTeamLabel.text = homeName + awayTeamLabel.text = awayName + } + + func updateScores(from scores: [String: Int]) { + let homeScore = scores[GameManager.Side.home]! + let awayScore = scores[GameManager.Side.away]! + homeScoreLabel.text = "\(homeScore)" + awayScoreLabel.text = "\(awayScore)" + } + +} diff --git a/iOS/baseball-game/baseball-game/GamePlay/ViewModel/GamePlayViewModel.swift b/iOS/baseball-game/baseball-game/GamePlay/ViewModel/GamePlayViewModel.swift new file mode 100644 index 000000000..a0fe03bb1 --- /dev/null +++ b/iOS/baseball-game/baseball-game/GamePlay/ViewModel/GamePlayViewModel.swift @@ -0,0 +1,34 @@ +// +// GamePlayViewModel.swift +// baseball-game +// +// Created by Song on 2021/05/06. +// + +import Foundation +import Combine + +class GamePlayViewModel { + + @Published var gameManager: GameManagable! + @Published var pitches: [Pitch]! + @Published var error: Error! + + private let isUserHomeSide: Bool + private var cancelBag = Set() + + init(_ isUserHomeSide: Bool) { + self.isUserHomeSide = isUserHomeSide + } + + func requestGame() { + NetworkManager.get(type: GameManager.self, url: EndPoint.url(path: "/1/attack")!) + .sink { error in + self.error = error as? Error + } receiveValue: { data in + self.pitches = data.turn.pitches + self.gameManager = GameManager(isUserHomeSide: self.isUserHomeSide, turn: data.turn) + }.store(in: &cancelBag) + } + +} diff --git a/iOS/baseball-game/baseball-game/Info.plist b/iOS/baseball-game/baseball-game/Info.plist index 5b531f7b2..53c6efd04 100644 --- a/iOS/baseball-game/baseball-game/Info.plist +++ b/iOS/baseball-game/baseball-game/Info.plist @@ -2,6 +2,11 @@ + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable diff --git a/iOS/baseball-game/baseball-game/Network/Network.swift b/iOS/baseball-game/baseball-game/Network/Network.swift new file mode 100644 index 000000000..8d792c5cc --- /dev/null +++ b/iOS/baseball-game/baseball-game/Network/Network.swift @@ -0,0 +1,82 @@ +// +// Network.swift +// baseball-game +// +// Created by Lia on 2021/05/04. +// + +import Foundation +import Combine + +enum NetworkError: Error { + case BadURL + case DecodingError +} + +enum EndPoint { + static let scheme = "https" + static let host = "28620c3c-a2bb-4264-bf32-8546221c8a8d.mock.pstmn.io" + static let path = "/baseball/games" + + static func url(path: String) -> URL? { + var components = URLComponents() + + components.scheme = EndPoint.scheme + components.host = EndPoint.host + components.path = "\(EndPoint.path)\(path)" + + return components.url + } +} + + +class NetworkManager { + + static func get(type: T.Type, url: URL) -> AnyPublisher { + + return URLSession.shared.dataTaskPublisher(for: url) + .tryMap { element -> Data in + guard let httpResponse = element.response as? HTTPURLResponse, + httpResponse.statusCode == 200 else { + throw NetworkError.BadURL + } + return element.data + } + .decode(type: T.self, decoder: JSONDecoder()) + .mapError({ (error) -> Error in + return error + }) + .eraseToAnyPublisher() + } + + static func post(url: URL, data: T) -> AnyPublisher { + + return Just(data) + .encode(encoder: JSONEncoder()) + .mapError { error -> Error in + print(error) ///사용자에게 에러 표시하는 부분 미구현 + return error + } + .map { data -> URLRequest in + var request = URLRequest(url: url) + request.httpMethod = "post" + request.httpBody = data + request.addValue("application/json", forHTTPHeaderField: "Content-Type") + request.setValue(String(data.count), forHTTPHeaderField: "Content-Length") + + return request + } + .flatMap { request in + return URLSession.shared.dataTaskPublisher(for: request) + .tryMap { element -> Void in + guard let httpResponse = element.response as? HTTPURLResponse, + httpResponse.statusCode == 200 else { + throw NetworkError.BadURL + } + return + } + } + .eraseToAnyPublisher() + } + +} diff --git a/iOS/baseball-game/baseball-game/Selection/LoginViewController.swift b/iOS/baseball-game/baseball-game/Selection/LoginViewController.swift new file mode 100644 index 000000000..97d6c3b78 --- /dev/null +++ b/iOS/baseball-game/baseball-game/Selection/LoginViewController.swift @@ -0,0 +1,22 @@ +// +// LoginViewController.swift +// baseball-game +// +// Created by Lia on 2021/05/06. +// + +import UIKit + +class LoginViewController: UIViewController { + + @IBOutlet weak var IDTextField: UITextField! + + @IBAction func okButtonTouched(_ sender: UIButton) { + let gameInfo = GameInfo(userID: IDTextField.text ?? "", team: "") + + guard let nextVC = storyboard?.instantiateViewController(withIdentifier: "SelectionViewController") as? SelectionViewController else { return } + nextVC.viewModel.setModel(with: gameInfo) + self.navigationController?.pushViewController(nextVC, animated: false) + } + +} diff --git a/iOS/baseball-game/baseball-game/Selection/Model/Game.swift b/iOS/baseball-game/baseball-game/Selection/Model/Game.swift new file mode 100644 index 000000000..fab07c5a3 --- /dev/null +++ b/iOS/baseball-game/baseball-game/Selection/Model/Game.swift @@ -0,0 +1,14 @@ +// +// Game.swift +// baseball-game +// +// Created by Lia on 2021/05/04. +// + +import Foundation + +struct Game: Codable, Hashable { + var id: Int = 0 + var home: Team = Team() + var away: Team = Team() +} diff --git a/iOS/baseball-game/baseball-game/Selection/Model/GameInfo.swift b/iOS/baseball-game/baseball-game/Selection/Model/GameInfo.swift new file mode 100644 index 000000000..ec8d3168f --- /dev/null +++ b/iOS/baseball-game/baseball-game/Selection/Model/GameInfo.swift @@ -0,0 +1,14 @@ +// +// GameInfo.swift +// baseball-game +// +// Created by Song on 2021/05/07. +// + +import Foundation + +struct GameInfo: Codable { + var userID: String = "" + var gameID: Int = 0 + var team: String = "" +} diff --git a/iOS/baseball-game/baseball-game/Selection/Model/Team.swift b/iOS/baseball-game/baseball-game/Selection/Model/Team.swift new file mode 100644 index 000000000..dbdc38026 --- /dev/null +++ b/iOS/baseball-game/baseball-game/Selection/Model/Team.swift @@ -0,0 +1,13 @@ +// +// Team.swift +// baseball-game +// +// Created by Song on 2021/05/07. +// + +import Foundation + +struct Team: Codable, Hashable { + var team: String = "" + var status: String = "" +} diff --git a/iOS/baseball-game/baseball-game/Selection/SelectionViewController.swift b/iOS/baseball-game/baseball-game/Selection/SelectionViewController.swift new file mode 100644 index 000000000..69581ecf3 --- /dev/null +++ b/iOS/baseball-game/baseball-game/Selection/SelectionViewController.swift @@ -0,0 +1,74 @@ +// +// SelectionViewController.swift +// baseball-game +// +// Created by Lia on 2021/05/03. +// + +import UIKit + +class SelectionViewController: UIViewController { + + @IBOutlet weak var backgroundView: UIView! + @IBOutlet weak var gameListTableView: UITableView! + + private let gradientLayer: CAGradientLayer = CAGradientLayer() + + var viewModel = SelectViewModel() + private var dataSource: UITableViewDiffableDataSource! + + + override func viewDidLoad() { + super.viewDidLoad() + self.setBackground() + + self.viewModel.request() + self.registerNib() + self.configureDataSource() + self.createSnapshot() + } + +} + + +extension SelectionViewController { + enum Section { + case main + } + + private func registerNib() { + self.gameListTableView.register(GameCell.nib, forCellReuseIdentifier: GameCell.reuseIdentifier) + } + + private func configureDataSource() { + self.dataSource = UITableViewDiffableDataSource.init(tableView: self.gameListTableView) { (tableView, indexPath, game) -> UITableViewCell in + + let cell = self.gameListTableView.dequeueReusableCell(withIdentifier: GameCell.reuseIdentifier) as! GameCell + cell.fill(self.viewModel, state: game) + + return cell + } + } + + private func createSnapshot() { + var snapshot = NSDiffableDataSourceSnapshot() + + snapshot.appendSections([.main]) + viewModel.didFetchData { games in + snapshot.appendItems(games) + self.dataSource.apply(snapshot) + } + } +} + + +extension SelectionViewController { + + private func setBackground() { + self.gradientLayer.colors = [#colorLiteral(red: 0, green: 0, blue: 0, alpha: 1).cgColor, #colorLiteral(red: 0.06274510175, green: 0, blue: 0.1921568662, alpha: 1).cgColor, #colorLiteral(red: 0.1921568662, green: 0.007843137719, blue: 0.09019608051, alpha: 1).cgColor, #colorLiteral(red: 0.06274510175, green: 0, blue: 0.1921568662, alpha: 1).cgColor, #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1).cgColor] + self.gradientLayer.startPoint = CGPoint(x: 0, y: 0) + self.gradientLayer.endPoint = CGPoint(x: 1, y: 1) + self.gradientLayer.frame = self.view.bounds + self.backgroundView.layer.addSublayer(self.gradientLayer) + } +} diff --git a/iOS/baseball-game/baseball-game/Selection/View/GameCell.swift b/iOS/baseball-game/baseball-game/Selection/View/GameCell.swift new file mode 100644 index 000000000..85b71b550 --- /dev/null +++ b/iOS/baseball-game/baseball-game/Selection/View/GameCell.swift @@ -0,0 +1,62 @@ +// +// GameCell.swift +// baseball-game +// +// Created by Lia on 2021/05/04. +// + +import UIKit + +class GameCell: UITableViewCell { + static let reuseIdentifier = "GameCell" + static let nib = UINib(nibName: GameCell.reuseIdentifier, bundle: nil) + + private var viewModel: SelectViewModel! + + @IBOutlet weak var gameIdLabel: UILabel! + @IBOutlet weak var awayTeamButton: UIButton! + @IBOutlet weak var homeTeamButton: UIButton! + + private var gameInfo = GameInfo() + private var awayTeam: String! + private var homeTeam: String! + + + override func awakeFromNib() { + super.awakeFromNib() + } + + func fill(_ viewModel: SelectViewModel, state: Game) { + self.viewModel = viewModel + self.gameInfo = GameInfo(userID: viewModel.gameInfo.userID, gameID: state.id) + + self.gameIdLabel.text = "GAME \(state.id)" + self.awayTeamButton.setTitle(state.away.team, for: .normal) + self.homeTeamButton.setTitle(state.home.team, for: .normal) + self.setIsEnabled(state: state) + + self.awayTeam = state.away.team + self.homeTeam = state.home.team + } + + private func setIsEnabled(state: Game) { + if state.away.status == "selected" { self.awayTeamButton.isEnabled = false } + if state.home.status == "selected" { self.homeTeamButton.isEnabled = false } + } + + @IBAction func awayButtonTouched(_ sender: UIButton) { + self.gameInfo.team = self.awayTeam + self.viewModel.setModel(with: self.gameInfo) + self.viewModel.postSelection(with: self.gameInfo) + self.awayTeamButton.isEnabled = false + + } + + @IBAction func homeButtonTouched(_ sender: UIButton) { + self.gameInfo.team = self.homeTeam + self.viewModel.setModel(with: self.gameInfo) + self.viewModel.postSelection(with: self.gameInfo) + self.homeTeamButton.isEnabled = false + } + +} diff --git a/iOS/baseball-game/baseball-game/Selection/View/GameCell.xib b/iOS/baseball-game/baseball-game/Selection/View/GameCell.xib new file mode 100644 index 000000000..3848076be --- /dev/null +++ b/iOS/baseball-game/baseball-game/Selection/View/GameCell.xib @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOS/baseball-game/baseball-game/Selection/ViewModel/SelectViewModel.swift b/iOS/baseball-game/baseball-game/Selection/ViewModel/SelectViewModel.swift new file mode 100644 index 000000000..7e73a7bf7 --- /dev/null +++ b/iOS/baseball-game/baseball-game/Selection/ViewModel/SelectViewModel.swift @@ -0,0 +1,60 @@ +// +// SelectViewModel.swift +// baseball-game +// +// Created by Lia on 2021/05/04. +// + +import Foundation +import Combine + +class SelectViewModel { + private(set) var gameInfo: GameInfo! + private var cancellable = Set() + + + func setModel(with gameInfo: GameInfo) { + self.gameInfo = gameInfo + } + + //MARK: GET + func request() { + NetworkManager.get(type: [Game].self, url: EndPoint.url(path: "")!) + .receive(on: DispatchQueue.main) + .sink { error in + print(error) ///사용자에게 에러 표시하는 부분 미구현 + } receiveValue: { games in + self.fetch(data: games) + } + .store(in: &cancellable) + } + + private func fetch(data: [Game]) { + NotificationCenter.default.post(name: NotificationName.fetched, object: nil, userInfo: ["games": data]) + } + + func didFetchData(completion: @escaping ([Game]) -> Void) { + NotificationCenter.default.publisher(for: NotificationName.fetched) + .map{ ($0.userInfo as! [String:[Game]]) } + .sink { (userInfo) in + completion(userInfo["games"] ?? []) + }.store(in: &cancellable) + } + + //MARK: POST + func postSelection(with gameInfo: GameInfo) { + NetworkManager.post(url: EndPoint.url(path: "")!, data: gameInfo) + .receive(on: DispatchQueue.main) + .sink { error in + print(error) ///사용자에게 에러 표시하는 부분 미구현 + } receiveValue: { _ in + print("success") ///서버 POST 기능 미구현 + } + .store(in: &cancellable) + } + +} + +enum NotificationName { + static let fetched = Notification.Name("fetched") +} diff --git a/iOS/baseball-game/baseball-game/ViewController.swift b/iOS/baseball-game/baseball-game/ViewController.swift deleted file mode 100644 index b9367dc25..000000000 --- a/iOS/baseball-game/baseball-game/ViewController.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// ViewController.swift -// baseball-game -// -// Created by Song on 2021/05/03. -// - -import UIKit - -class ViewController: UIViewController { - - override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view. - } - - -} -