josee2
josee2 Devlog
josee2
전체 방문자
오늘
어제
  • 분류 전체보기 (54)
    • Swift (33)
      • 문법 (33)
    • iOS (13)
    • Algorithm (3)
      • 프로그래머스 (1)
      • BOJ (0)
      • 기타 (2)
    • 일상 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • IOS
  • GCD
  • 동시큐
  • serial
  • 동시
  • 멀티쓰레드
  • Sync
  • Swift
  • SeSAC
  • Async
  • 비동기
  • 서울청년취업사관학교
  • 직렬
  • 스위프트
  • concurrent
  • 문자열 템플릿
  • 쓰레드
  • 동기
  • 동시성프로그래밍
  • 프로세스

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
josee2

josee2 Devlog

카테고리 없음

[iOS] MVMM패턴의 기초(3) - 실습

2022. 9. 10. 01:52

 로그인화면 프로젝트


이번엔 간단하게 로그인 화면을 만들어 보면서 직접 실습을 해보자.

이름과 패스워드의 글자수가 조건을 만족하지 못하면 로그인을 할 수 없고 조건을 만족한다면 로그인을 할 수 있는 간단한 프로젝트이다.

 

 

 ViewModel

뷰모델의 역할은 간단하게 뷰와 모델 사이에서 값이 변경되면 알려주고 전달해주는 것이다.

그렇다면 뷰모델을 어떻게 구성해야 값이 변경되는 것을 받고 또 변경된 값들을 전달해 줄 수 있게 할 수 있을까?

그렇다 전에 작성해둔 Observable을 뷰모델에서 인스턴스화 시킨 후 사용하면 가능하다.

// In Observable
class Observable<T> {
    
    var listener: ( (T) -> Void)?
    
    var value: T {
        didSet {
            print("didSet", value)
            listener?(value)
        }
    }
    
    init(value: T) {
        self.value = value
    }
    
    func bind(completionHandler: @escaping (T) -> Void) {
        completionHandler(value)
        listener = completionHandler
    }
}

// In ViewModel
class LoginViewModel {
    
    var name: Observable<String> = Observable(value: "")
    var password: Observable<String> = Observable(value: "")
    var email: Observable<String> = Observable(value: "")
    var isValid: Observable<Bool> = Observable(value: false)


	// 로그인 버튼이 활성화될지 안 될지를 정해주는 메소드
    func checkValidation() {
        if name.value.count >= 6 && password.value.count >= 4 {
            isValid.value = true
        } else {
            isValid.value = false
        }
    }
}

다음과 같이 뷰모델에 Observable을 빈 값으로 초기화를 시켜주었다.

그러면 뷰모델에서 Observable을 컨트롤 할 수 있게되고  ViewController( MVVM패턴에서는 View 역할을 한다고 보면 됩니다)에서 뷰모델에게 값을 전달 해줄 수 있게된다.

View(ViewController) -> ModelView -> Observable 순서를 통해 값이 변경되면 즉시 인식이 가능하게 되는 것이다.


View(ViewController)

그럼 이제 ViewController에 코드를 작성해보자

// In ViewController
class ViewController: UIViewController {

    @IBOutlet weak var nameTextField: UITextField!
    @IBOutlet weak var passwordTextField: UITextField!
    @IBOutlet weak var emailTextField: UITextField!
    @IBOutlet weak var loginButton: UIButton!
    
    let viewModel = LoginViewModel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        passwordTextField.isSecureTextEntry = true
        
        viewModel.name.bind(completionHandler: { text in
            self.nameTextField.text = text
        })
        
        viewModel.password.bind(completionHandler: { text in
            self.passwordTextField.text = text
        })
        
        viewModel.email.bind(completionHandler: { text in
            self.emailTextField.text = text
        })
        
        viewModel.isValid.bind(completionHandler: { bool in
            self.loginButton.isEnabled = bool
            self.loginButton.backgroundColor = bool ? .green : .red
        })

    }
    
    @IBAction func nameTextFieldChanged(_ sender: UITextField) {
        viewModel.name.value = nameTextField.text!
        viewModel.checkValidation()
    }
    
    @IBAction func passwordTextFieldChanged(_ sender: UITextField) {
        viewModel.password.value = passwordTextField.text!
        viewModel.checkValidation()
    }
    
    @IBAction func emailTextFieldChanged(_ sender: UITextField) {
        viewModel.email.value = emailTextField.text!
        viewModel.checkValidation()
    }
}

각각의 텍스트필드를 스토리보드 상에서 변수로 만들어주고 액션을 추가해주었다.

액션은 텍스트필드의 값이 변경될 때마다 인식이 가능하도록 해주기위해서 EditingChanged 액션을 사용하였다.

하나씩 흐름을 천천히 살펴보자.

가장 먼저 LoginViewModel을 초기화 시켜주어 뷰컨트롤러에서 사용이 가능하게 해준다.

다음으로 bind메소드를 작성해준다.

여기서 bind 메소드를 작성해주면 어떻게될까?

값이 변경될 때마다 만들어준 bind 메소드가 실행될 것이다.

그러면 값이 변경될 때마다 업데이트 해주는 역할은 어디서 할 까?

그건 바로 텍스트필드 액션에서 해주게된다.

텍스트필드에서 값이 바뀔 때마다 value가 바뀌도록 해두었기 때문이다.

nameTextFieldChanged -> value 업데이트 -> 업데이트 일어나면 bind 메소드 실행 됨

이 순서대로 흐름이 진행되기 때문에 값이 변할 때마다 몇 글자가 들어있는지 인식이 가능하게되고 로그인 버튼의 비활성화 / 활성화 여부를 바로 확인할 수 있게 되는 것이다.

중요한 흐름은 여기서 끝나고 그 외에 checkValidation()은 글자가 바뀔 때마다 체크해줘야하는 것은 당연한 것이고 isEnabled는 버튼을 활성화 여부를 나타내주는 프로퍼티이다.

 


이로써 정말 간단하게 MVVM패턴에 대해 알아보았다. 

아직 헷갈리고 어려운 부분이 분명있지만 이 기본적인 흐름을 잘 이해하고 공부해나가면 충분히 MVVM 패턴에 대해서 완벽히 이해하고 사용할 수 있을 것이다.

 

 

저작자표시 비영리 변경금지 (새창열림)
    josee2
    josee2
    iOS 개발자 지망생의 공부기록입니다.

    티스토리툴바