diff --git a/MVVM_Calculator/MVVM_Calculator.xcodeproj/project.pbxproj b/MVVM_Calculator/MVVM_Calculator.xcodeproj/project.pbxproj index 1779cd9..d2ac575 100644 --- a/MVVM_Calculator/MVVM_Calculator.xcodeproj/project.pbxproj +++ b/MVVM_Calculator/MVVM_Calculator.xcodeproj/project.pbxproj @@ -9,27 +9,27 @@ /* Begin PBXBuildFile section */ 55A09183250BC44E000FF31A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A09182250BC44E000FF31A /* AppDelegate.swift */; }; 55A09185250BC44E000FF31A /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A09184250BC44E000FF31A /* SceneDelegate.swift */; }; - 55A09187250BC44E000FF31A /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A09186250BC44E000FF31A /* ViewController.swift */; }; + 55A09187250BC44E000FF31A /* CalculatorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A09186250BC44E000FF31A /* CalculatorViewController.swift */; }; 55A0918A250BC44E000FF31A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 55A09188250BC44E000FF31A /* Main.storyboard */; }; 55A0918C250BC44F000FF31A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 55A0918B250BC44F000FF31A /* Assets.xcassets */; }; 55A0918F250BC44F000FF31A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 55A0918D250BC44F000FF31A /* LaunchScreen.storyboard */; }; - 55A0919B250BC6D2000FF31A /* Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A0919A250BC6D2000FF31A /* Model.swift */; }; - 55A0919D250BC796000FF31A /* ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A0919C250BC796000FF31A /* ViewModel.swift */; }; - 55A0919F250BCB1A000FF31A /* OperationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A0919E250BCB1A000FF31A /* OperationType.swift */; }; + 55A0919B250BC6D2000FF31A /* CalculatorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A0919A250BC6D2000FF31A /* CalculatorModel.swift */; }; + 55A0919D250BC796000FF31A /* CalculatorViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A0919C250BC796000FF31A /* CalculatorViewModel.swift */; }; + 55A0919F250BCB1A000FF31A /* Command.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A0919E250BCB1A000FF31A /* Command.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 55A0917F250BC44E000FF31A /* MVVM_Calculator.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MVVM_Calculator.app; sourceTree = BUILT_PRODUCTS_DIR; }; 55A09182250BC44E000FF31A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 55A09184250BC44E000FF31A /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - 55A09186250BC44E000FF31A /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 55A09186250BC44E000FF31A /* CalculatorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalculatorViewController.swift; sourceTree = ""; }; 55A09189250BC44E000FF31A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 55A0918B250BC44F000FF31A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 55A0918E250BC44F000FF31A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 55A09190250BC44F000FF31A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 55A0919A250BC6D2000FF31A /* Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Model.swift; sourceTree = ""; }; - 55A0919C250BC796000FF31A /* ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModel.swift; sourceTree = ""; }; - 55A0919E250BCB1A000FF31A /* OperationType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OperationType.swift; sourceTree = ""; }; + 55A0919A250BC6D2000FF31A /* CalculatorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalculatorModel.swift; sourceTree = ""; }; + 55A0919C250BC796000FF31A /* CalculatorViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalculatorViewModel.swift; sourceTree = ""; }; + 55A0919E250BCB1A000FF31A /* Command.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Command.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -43,6 +43,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 192940912517957600F6FBEA /* Common */ = { + isa = PBXGroup; + children = ( + 55A0919E250BCB1A000FF31A /* Command.swift */, + ); + path = Common; + sourceTree = ""; + }; 55A09176250BC44E000FF31A = { isa = PBXGroup; children = ( @@ -76,6 +84,7 @@ 55A09196250BC45F000FF31A /* Source */ = { isa = PBXGroup; children = ( + 192940912517957600F6FBEA /* Common */, 55A09197250BC466000FF31A /* Model */, 55A09199250BC478000FF31A /* View */, 55A09198250BC470000FF31A /* ViewModel */, @@ -86,8 +95,7 @@ 55A09197250BC466000FF31A /* Model */ = { isa = PBXGroup; children = ( - 55A0919A250BC6D2000FF31A /* Model.swift */, - 55A0919E250BCB1A000FF31A /* OperationType.swift */, + 55A0919A250BC6D2000FF31A /* CalculatorModel.swift */, ); path = Model; sourceTree = ""; @@ -95,7 +103,7 @@ 55A09198250BC470000FF31A /* ViewModel */ = { isa = PBXGroup; children = ( - 55A0919C250BC796000FF31A /* ViewModel.swift */, + 55A0919C250BC796000FF31A /* CalculatorViewModel.swift */, ); path = ViewModel; sourceTree = ""; @@ -103,7 +111,7 @@ 55A09199250BC478000FF31A /* View */ = { isa = PBXGroup; children = ( - 55A09186250BC44E000FF31A /* ViewController.swift */, + 55A09186250BC44E000FF31A /* CalculatorViewController.swift */, ); path = View; sourceTree = ""; @@ -179,12 +187,12 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 55A0919D250BC796000FF31A /* ViewModel.swift in Sources */, - 55A0919F250BCB1A000FF31A /* OperationType.swift in Sources */, - 55A09187250BC44E000FF31A /* ViewController.swift in Sources */, + 55A0919D250BC796000FF31A /* CalculatorViewModel.swift in Sources */, + 55A0919F250BCB1A000FF31A /* Command.swift in Sources */, + 55A09187250BC44E000FF31A /* CalculatorViewController.swift in Sources */, 55A09183250BC44E000FF31A /* AppDelegate.swift in Sources */, 55A09185250BC44E000FF31A /* SceneDelegate.swift in Sources */, - 55A0919B250BC6D2000FF31A /* Model.swift in Sources */, + 55A0919B250BC6D2000FF31A /* CalculatorModel.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/MVVM_Calculator/MVVM_Calculator/AppDelegate.swift b/MVVM_Calculator/MVVM_Calculator/AppDelegate.swift index 0295976..33666d4 100644 --- a/MVVM_Calculator/MVVM_Calculator/AppDelegate.swift +++ b/MVVM_Calculator/MVVM_Calculator/AppDelegate.swift @@ -9,29 +9,22 @@ import UIKit @UIApplicationMain -class AppDelegate: UIResponder, UIApplicationDelegate { - - - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - // Override point for customization after application launch. +final class AppDelegate: UIResponder, UIApplicationDelegate { + func application(_ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { return true } // MARK: UISceneSession Lifecycle - func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { - // Called when a new scene session is being created. - // Use this method to select a configuration to create the new scene with. - return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + func application(_ application: UIApplication, + configurationForConnecting connectingSceneSession: UISceneSession, + options: UIScene.ConnectionOptions) -> UISceneConfiguration { + return UISceneConfiguration(name: "Default Configuration", + sessionRole: connectingSceneSession.role) } - func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { - // Called when the user discards a scene session. - // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. - // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + func application(_ application: UIApplication, + didDiscardSceneSessions sceneSessions: Set) { } - - } - diff --git a/MVVM_Calculator/MVVM_Calculator/Base.lproj/Main.storyboard b/MVVM_Calculator/MVVM_Calculator/Base.lproj/Main.storyboard index 196248b..bc364cb 100644 --- a/MVVM_Calculator/MVVM_Calculator/Base.lproj/Main.storyboard +++ b/MVVM_Calculator/MVVM_Calculator/Base.lproj/Main.storyboard @@ -1,5 +1,5 @@ - + @@ -7,10 +7,10 @@ - + - + @@ -258,7 +258,6 @@ - @@ -270,12 +269,12 @@ - - - - - - + + + + + + diff --git a/MVVM_Calculator/MVVM_Calculator/SceneDelegate.swift b/MVVM_Calculator/MVVM_Calculator/SceneDelegate.swift index c372ca9..39bf22c 100644 --- a/MVVM_Calculator/MVVM_Calculator/SceneDelegate.swift +++ b/MVVM_Calculator/MVVM_Calculator/SceneDelegate.swift @@ -8,46 +8,26 @@ import UIKit -class SceneDelegate: UIResponder, UIWindowSceneDelegate { - +final class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? - - func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { - // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. - // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. - // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, + options connectionOptions: UIScene.ConnectionOptions) { guard let _ = (scene as? UIWindowScene) else { return } - } - func sceneDidDisconnect(_ scene: UIScene) { - // Called as the scene is being released by the system. - // This occurs shortly after the scene enters the background, or when its session is discarded. - // Release any resources associated with this scene that can be re-created the next time the scene connects. - // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + let storyboard = UIStoryboard(name: "Main", bundle: nil) + guard let viewController = storyboard.instantiateInitialViewController() as? CalculatorViewController else { return } + viewController.setViewModel(CalculatorViewModel()) + window?.rootViewController = viewController } - func sceneDidBecomeActive(_ scene: UIScene) { - // Called when the scene has moved from an inactive state to an active state. - // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. - } + func sceneDidDisconnect(_ scene: UIScene) {} - func sceneWillResignActive(_ scene: UIScene) { - // Called when the scene will move from an active state to an inactive state. - // This may occur due to temporary interruptions (ex. an incoming phone call). - } + func sceneDidBecomeActive(_ scene: UIScene) {} - func sceneWillEnterForeground(_ scene: UIScene) { - // Called as the scene transitions from the background to the foreground. - // Use this method to undo the changes made on entering the background. - } - - func sceneDidEnterBackground(_ scene: UIScene) { - // Called as the scene transitions from the foreground to the background. - // Use this method to save data, release shared resources, and store enough scene-specific state information - // to restore the scene back to its current state. - } + func sceneWillResignActive(_ scene: UIScene) {} + func sceneWillEnterForeground(_ scene: UIScene) {} + func sceneDidEnterBackground(_ scene: UIScene) {} } - diff --git a/MVVM_Calculator/MVVM_Calculator/Source/Model/OperationType.swift b/MVVM_Calculator/MVVM_Calculator/Source/Common/Command.swift similarity index 75% rename from MVVM_Calculator/MVVM_Calculator/Source/Model/OperationType.swift rename to MVVM_Calculator/MVVM_Calculator/Source/Common/Command.swift index d02e39a..09e82e8 100644 --- a/MVVM_Calculator/MVVM_Calculator/Source/Model/OperationType.swift +++ b/MVVM_Calculator/MVVM_Calculator/Source/Common/Command.swift @@ -1,21 +1,16 @@ // -// OperationType.swift +// Command.swift // MVVM_Calculator // // Created by IJ . on 2020/09/12. // Copyright © 2020 jun. All rights reserved. // -enum OperationType: String { - + +enum Command: String { case plus = "+" - case minus = "-" - case multiply = "×" - case divide = "÷" - case result = "=" - case initialize = "AC" } diff --git a/MVVM_Calculator/MVVM_Calculator/Source/Model/CalculatorModel.swift b/MVVM_Calculator/MVVM_Calculator/Source/Model/CalculatorModel.swift new file mode 100644 index 0000000..b3fb64e --- /dev/null +++ b/MVVM_Calculator/MVVM_Calculator/Source/Model/CalculatorModel.swift @@ -0,0 +1,88 @@ +// +// CalculatorModel.swift +// MVVM_Calculator +// +// Created by IJ . on 2020/09/11. +// Copyright © 2020 jun. All rights reserved. +// + +protocol CalculatorModelDelegate: class { + func calculatorModelDidChangeNowValue(with value: Int) +} + +struct CalculatorModel { + private(set) var beforeValue: Int = 0 + private(set) var nowValue: Int = 0 { + didSet { + delegate?.calculatorModelDidChangeNowValue(with: nowValue) + } + } + + weak var delegate: CalculatorModelDelegate? + + private var beforeCommand: Command? + private var hasCommandUpdated: Bool = false + + mutating func setBeforeValue(_ beforeValue: Int) { + self.beforeValue = beforeValue + } + + mutating func setNowValue(_ nowValue: Int){ + if hasCommandUpdated { + self.nowValue = nowValue + } else { + self.nowValue = self.nowValue * 10 + nowValue + } + + if hasCommandUpdated { + hasCommandUpdated = false + } + } + + mutating func setCommand(_ command: String) { + guard let command = Command(rawValue: command) else { return } + + switch command { + case .plus: + performOperatorCommand(.plus) + case .divide: + performOperatorCommand(.divide) + case .minus: + performOperatorCommand(.minus) + case .multiply: + performOperatorCommand(.multiply) + case .result: + guard let beforeCommand = beforeCommand else { return } + + switch beforeCommand { + case .plus: + nowValue = beforeValue + nowValue + case .divide: + nowValue = beforeValue / nowValue + case .minus: + nowValue = beforeValue - nowValue + case .multiply: + nowValue = beforeValue * nowValue + default: + print("4칙연산 이외의 케이스 감지 ERROR") + } + case .initialize: + initialize() + } + } +} + +// MARK: - Private Method + +private extension CalculatorModel { + mutating func performOperatorCommand(_ command: Command) { + setBeforeValue(nowValue) + beforeCommand = command + hasCommandUpdated = true + } + + mutating func initialize() { + nowValue = 0 + beforeValue = 0 + } +} diff --git a/MVVM_Calculator/MVVM_Calculator/Source/Model/Model.swift b/MVVM_Calculator/MVVM_Calculator/Source/Model/Model.swift deleted file mode 100644 index 6359702..0000000 --- a/MVVM_Calculator/MVVM_Calculator/Source/Model/Model.swift +++ /dev/null @@ -1,93 +0,0 @@ -// -// Model.swift -// MVVM_Calculator -// -// Created by IJ . on 2020/09/11. -// Copyright © 2020 jun. All rights reserved. -// - -import Foundation - -struct Model { - - var beforeValue: Int - var nowValue: Int { - didSet { //값이 변경되기 직전 호출, 프로퍼티 옵저버 - NotificationCenter.default.post(name: NSNotification.Name(rawValue: "NowValueNotificationCenter"), object: self.nowValue) - } - } - var beforeOperationType: OperationType? - var operationType: OperationType? - var isOperationCheck: Bool = false - - private func calculatePlus() -> Int { - return beforeValue + nowValue - } - - mutating func setBeforeValue(changeValue: Int) { - self.beforeValue = changeValue - } - - mutating func setNowValue(changeValue: Int){ - if isOperationCheck { - self.nowValue = changeValue - } else { - self.nowValue = self.nowValue * 10 + changeValue - } - - if isOperationCheck { - self.isOperationCheck = false - } - } - - mutating func setOpertaorCalculate(operatorValue: String) { - if let operation = OperationType(rawValue: operatorValue) { - switch operation { - case .plus: - calculate(.plus) - case .divide: - calculate(.divide) - case .minus: - calculate(.minus) - case .multiply: - calculate(.multiply) - case .result: - if let beforeOperation = beforeOperationType { - switch beforeOperation { - case .plus: - self.nowValue = self.beforeValue + self.nowValue - case .divide: - self.nowValue = self.beforeValue / self.nowValue - case .minus: - self.nowValue = self.beforeValue - self.nowValue - case .multiply: - self.nowValue = self.beforeValue * self.nowValue - default: print("4칙연산 이외의 케이스 감지 ERROR") - break - } - } - - case .initialize: - self.nowValue = 0 - self.beforeValue = 0 - default: - break - } - } - - } - private mutating func calculate(_ beforeOperationType: OperationType) { - self.setBeforeValue(changeValue: self.nowValue) - self.isOperationCheck = true - self.beforeOperationType = beforeOperationType - } - - private func getNowValue() -> Int { - return self.nowValue - } - - private func getBeforeValue() -> Int { - return self.beforeValue - } - -} diff --git a/MVVM_Calculator/MVVM_Calculator/Source/View/CalculatorViewController.swift b/MVVM_Calculator/MVVM_Calculator/Source/View/CalculatorViewController.swift new file mode 100644 index 0000000..0b8d4eb --- /dev/null +++ b/MVVM_Calculator/MVVM_Calculator/Source/View/CalculatorViewController.swift @@ -0,0 +1,71 @@ +// +// CalculatorViewController.swift +// MVVM_Calculator +// +// Created by IJ . on 2020/09/11. +// Copyright © 2020 jun. All rights reserved. +// + +import UIKit + +final class CalculatorViewController: UIViewController { + @IBOutlet private var presentLabel: UILabel! + @IBOutlet private var numberButtons: [UIButton]! + @IBOutlet private var commandButtons: [UIButton]! + + private var viewModel: CalculatorViewModel! + + override func viewDidLoad() { + super.viewDidLoad() + + for button in numberButtons { + button.addTarget(self, action: #selector(touchUpNumberButtons(_:)), for: .touchUpInside) + } + + for button in commandButtons { + button.addTarget(self, action: #selector(touchUpOperatorButtons(_:)), for: .touchUpInside) + } + } + + override func viewWillLayoutSubviews() { + super.viewWillLayoutSubviews() + + for numberButton in numberButtons { + numberButton.layer.cornerRadius = numberButton.bounds.height / 2 + } + + for operatorButton in commandButtons { + operatorButton.layer.cornerRadius = operatorButton.bounds.height / 2 + } + } + + func setViewModel(_ viewModel: CalculatorViewModel) { + self.viewModel = viewModel + viewModel.bindingObject = self + } +} + +// MARK: - Data Binding + +extension CalculatorViewController: CalculatorViewModelBinding { + func calculatorDidFinishCalculation(with result: String) { + presentLabel.text = result + } +} + +// MARK: - Action + +private extension CalculatorViewController { + @objc func touchUpNumberButtons(_ sender: UIButton) { + guard let number = sender.titleLabel?.text else { return } + guard let buttonNumber = Int(number) else { return } + + viewModel.setNowValue(buttonNumber) + } + + @objc func touchUpOperatorButtons(_ sender: UIButton) { + guard let operatorValue = sender.titleLabel?.text else { return } + + viewModel.setCommand(operatorValue) + } +} diff --git a/MVVM_Calculator/MVVM_Calculator/Source/View/ViewController.swift b/MVVM_Calculator/MVVM_Calculator/Source/View/ViewController.swift deleted file mode 100644 index f8c0f1a..0000000 --- a/MVVM_Calculator/MVVM_Calculator/Source/View/ViewController.swift +++ /dev/null @@ -1,77 +0,0 @@ -// -// ViewController.swift -// MVVM_Calculator -// -// Created by IJ . on 2020/09/11. -// Copyright © 2020 jun. All rights reserved. -// - -import UIKit - -class ViewController: UIViewController { - - @IBOutlet weak var plusButton: UIButton! - @IBOutlet weak var presentLabel: UILabel! - @IBOutlet var numberButtons: [UIButton]! - @IBOutlet var operatorButtons: [UIButton]! - - - let viewModel = CaculatorViewModel() - - override func viewDidLoad() { - super.viewDidLoad() - - for button in numberButtons { - button.addTarget(self, action: #selector(touchUpNumberButtons(_:)), for: .touchUpInside) - } - - for button in operatorButtons { - button.addTarget(self, action: #selector(touchUpOperatorButtons(_:)), for: .touchUpInside) - } - - NotificationCenter.default.addObserver(self, selector: #selector(viewSetNowValue), name: Notification.Name("NowValueViewNotificationCenter"), object: nil) - //RxCocoa를 사용하지 않아서 바인딩이 안되서, M과 View가 연결되어짐 구조를 먼저 짠뒤 수정예정 - //Model에서 nowValue -> VM에서 노티로 옵저버, 값 전달 -> View - } - - override func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(animated) - //viewWillAppear()에서 하면 자몽이 만들어짐...why? - for numberButton in numberButtons { - numberButton.layer.cornerRadius = numberButton.bounds.height / 2 - } - - for operatorButton in operatorButtons { - operatorButton.layer.cornerRadius = operatorButton.bounds.height / 2 - } - } - - @IBAction func touchUpPlusButton(_ sender: Any) { - //test - viewModel.just() - } - - @objc func viewSetNowValue(_ notification: Notification) { - //notification.object as? Int - if let changeValue = notification.object { - presentLabel.text = "\(changeValue)" - } - } - - @objc func touchUpNumberButtons(_ sender: UIButton) { - guard let number = sender.titleLabel?.text else { return } - guard let buttonNumber = Int(number) else { return } - - viewModel.setModelNowValue(nowValue: buttonNumber) - } - - @objc func touchUpOperatorButtons(_ sender: UIButton) { - guard let operatorValue = sender.titleLabel?.text else { return } - - viewModel.setOperatorValue(operatorValue: operatorValue) - - } - - -} - diff --git a/MVVM_Calculator/MVVM_Calculator/Source/ViewModel/CalculatorViewModel.swift b/MVVM_Calculator/MVVM_Calculator/Source/ViewModel/CalculatorViewModel.swift new file mode 100644 index 0000000..113f899 --- /dev/null +++ b/MVVM_Calculator/MVVM_Calculator/Source/ViewModel/CalculatorViewModel.swift @@ -0,0 +1,45 @@ +// +// CalculatorViewModel.swift +// MVVM_Calculator +// +// Created by IJ . on 2020/09/11. +// Copyright © 2020 jun. All rights reserved. +// + +protocol CalculatorViewModelBinding: class { + func calculatorDidFinishCalculation(with result: String) +} + +final class CalculatorViewModel { + weak var bindingObject: CalculatorViewModelBinding? + + private var model = CalculatorModel() + + init() { + model.delegate = self + } +} + +// MARK: - Input + +extension CalculatorViewModel { + func setBeforeValue(_ beforeValue: Int) { + model.setBeforeValue(beforeValue) + } + + func setNowValue(_ nowValue: Int) { + model.setNowValue(nowValue) + } + + func setCommand(_ command: String) { + model.setCommand(command) + } +} + +// MARK: - Output + +extension CalculatorViewModel: CalculatorModelDelegate { + func calculatorModelDidChangeNowValue(with value: Int) { + bindingObject?.calculatorDidFinishCalculation(with: String(value)) + } +} diff --git a/MVVM_Calculator/MVVM_Calculator/Source/ViewModel/ViewModel.swift b/MVVM_Calculator/MVVM_Calculator/Source/ViewModel/ViewModel.swift deleted file mode 100644 index 85c14c4..0000000 --- a/MVVM_Calculator/MVVM_Calculator/Source/ViewModel/ViewModel.swift +++ /dev/null @@ -1,42 +0,0 @@ -// -// ViewModel.swift -// MVVM_Calculator -// -// Created by IJ . on 2020/09/11. -// Copyright © 2020 jun. All rights reserved. -// - -import Foundation - -class CaculatorViewModel { - - var model = Model(beforeValue: 0, nowValue: 0) - - func just(){ - - } - - func setModelBeforeValue(beforeValue: Int) { - model.setBeforeValue(changeValue: beforeValue) - } - - func setModelNowValue(nowValue: Int) { - model.setNowValue(changeValue: nowValue) - } - - func setOperatorValue(operatorValue: String) { - model.setOpertaorCalculate(operatorValue: operatorValue) - } - - @objc func getNowValueLabel(_ notification: Notification) { - // print("viewModel에서\(notification.object ?? 0)") - NotificationCenter.default.post(name: NSNotification.Name(rawValue: "NowValueViewNotificationCenter"), object: notification.object) - } - - - init() { - - NotificationCenter.default.addObserver(self, selector: #selector(getNowValueLabel), name: Notification.Name("NowValueNotificationCenter"), object: nil) - print("ViewModel생성자") - } -}