[Swift] MVVM패턴을 공부해봅시다🌈

GomMinjae·2021년 9월 13일
0

디자인패턴🌈

목록 보기
1/2
post-thumbnail

오늘은 MVVM 패턴에 대하여 공부해보겠습니다. 평소에 MVC패턴으로만 개발을 했지만 새로운 아키텍처로 개발을 해보고 싶어서 공부하게 되었습니다. MVVM패턴은 기본적으로 Model, View, ViewModel로 이루어져있습니다. 이 세가지 구성요소가 서로 상호 연결되어있는 패턴입니다. Model은 데이터를 처리하고 View는 오직 UI만 담당합니다. 그리고 마지막으로 ViewModel은 View와 Model의 주요연결을 담당합니다.

Model


Model부분은 데이터 모델 , 데이터 접근 레이어, 비즈니스 로직이 포함되어 있습니다.

모델은 데이터의 흐름에 관하여 알고있고 이 작업들을 ViewModel에 의해 작동되고 모델이 데이터에 대한 작업을 마치면 ViewModel에게 결과를 알립니다.

View


데이터를 표시하는 UI(User Interface)를 담당합니다. 이벤트들은 ViewModel에서 처리하게 되고 View는 ViewModel의 변경사항을 감지하고 ViewModel이 업데이트한 데이터를 보여줍니다. 재사용성과 테스트 용이성을 가지고 있습니다.

View와 Model은 서로 연결이 없습니다. 오직 ViewModel에 의해 연결됩니다.

ViewModel


ViewModel은 주요 로직을 담당합니다. 이벤트를 처리할때 Model을 업데이트하고 그 결과를 다시 받아서 View에 전달하여 UI를 업데이트 해야하는 책임을 가지고 있습니다. 객체를 쉽게 관리하기 쉬운 장점이 있습니다. ViewModel은 화면 표현의 대부분을 처리합니다.

Example


예제로 간단한 Login화면을 구성해보겠습니다. (Swift Tutorials 유튜브를 참고하였습니다')

  • Model
struct User {
  var name: String
  var email: String
}
  • ViewModel
class ViewModel: NSObject {
    var user: User! //Model 
    var userName: String { return user.name }
    var email: String { return user.email }
    
    typealias authenticationLoginCallback = (_ status: Bool, _ message: String) -> Void //callback 
    
    var callback: authenticationLoginCallback?
    
    //로그인 유효성 검사 
    func authenticationUser(_ email: String, _ password: String) {
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) {
            if self.userName.count != 0 {
                if password.count != 0 {
                    self.verifyUser(self.userName, password)
                }else {
                    self.callback?(false, "password error")
                }
            }else {
                self.callback?(false, "user error")
            }
        }
    }
    //유저 확인 
    fileprivate func verifyUser(_ email: String, _ password: String) {
        if userName == "test" && password == "1234" {
            user = User(name: userName, email: "\(userName)@gmail.com")
            self.callback?(true, "success")
        }else {
            self.callback?(false, "Please enter valid source")
        }
    }
    
  //로그인 완료시 callback 메소드 
    func loginCompletion(callBack: @escaping authenticationLoginCallback) {
        self.callback = callBack
    }
    
}
  • ViewController
class ViewController: UIViewController {
    //Outlets
    @IBOutlet weak var messageLabel: UILabel!
    @IBOutlet weak var userNameField: UITextField!
    @IBOutlet weak var passwordField: UITextField!
   
  var viewModel = ViewModel()//ViewModel

    override func viewDidLoad() {
        super.viewDidLoad()
        self.messageLabel.isHidden = true
        // Do any additional setup after loading the view.
    }
    
    @objc func loginUser() {
        self.messageLabel.isHidden = true
        guard let userName = self.userNameField.text else { return }
        guard let password = self.passwordField.text else { return }
        viewModel.authenticationUser(userName, password)//로그인 유효성 검사
        
      //callback에 따른 UI변환 
        viewModel.loginCompletion { [weak self] status, message in
            guard let self = self else { return }
            if status {
                self.messageLabel.text = "login success"
                self.messageLabel.isHidden = false
            } else {
                self.messageLabel.text = message
                self.messageLabel.isHidden = false
            }
        }
    }
}

마치며

이렇게 ViewModel에서 주요 로직(로그인 유효 검사)를 담당해서 ViewController에 전달해주면 ViewController에서는 오직 UI(messageLabel)만 바꿔줍니다. 이것들이 MVVM 패턴의 원리입니다. ViewModel은 view에 관한 어떠한 의존성이나 연결성도 없습니다. 이것이 다른 디자인패턴들과의 차이점인것 같습니다. 이번 포스팅에서는 간단한 MVVM의 내용들을 다뤄보았습니다. 다음에는 좀 더 심화된 RxSwift + MVVM을 공부해 보도록 하겠습니다.

profile
iOS를 공부하고 있습니다.🔥

0개의 댓글