본문 바로가기

iOS

[iOS] RxSwift를 이용한 Login 기능 구현

RxSwift를 이용한 Login 기능 구현

 

이번에는 RxSwiftRxCocoa 를 이용하여 간단한 Login 프로세스를 구현해보도록 하겠습니다.

 

Layout


image

이번에 만들어 볼 앱의 레이아웃은 위 사진과 같습니다.

 

간단히 Email과 Password를 입력받기 위한 TextField 와 로그인 진행을 위한 Button을 하나 생성하였습니다.

 

ViewModel


 

View를 위해 ViewModel이 제공해야 하는 프로퍼티와 기능에 대하여 먼저 정의하겠습니다.

 

InputOutput 을 나눠서 살펴보면 아래와 같이 정리할 수 있습니다.

 

  • Input

    • emailTextField: BehaviorRelay
    • pwTextField: BehaviorRelay
  • Output

    • emailText 값과 pwText값의 유효성에 따른 결과값: Observable

간단히 Input, Output은 위와 같이 나눠지며 Output 결과에 따라서 Login 버튼의 isEnabled 속성과 alpha 속성을 조절할 것 입니다.

 

위와 같이 뷰모델을 작성해보겠습니다.

 

class LoginViewModel {
    let emailTextRelay = BehaviorRelay<String>(value: "")
    let pwTextRelay = BehaviorRelay<String>(value: "")

    func isValid() -> Observable<Bool> {
        return Observable.combineLatest(emailTextRelay, pwTextRelay).map  { username, password in
            return username.count > 0 && username.contains("@") && username.contains(".") && password.count > 0
        }
    }
}

 

사용자로부터 입력받는 email, pw 값을 combineLatest 를 통해 Obsevable 타입을 반환합니다.

 

이때 사용자의 입력값이 적절한지 간단히 유효성을 검사하도록 합니다.

 

ViewController


 

이제 ViewModel이 완성되었으니 ViewController 를 작성해보겠습니다.

 

@IBOutlet 을 제외하고 아래 프로퍼티를 생성합니다.

 

let viewModel = LoginViewModel()
let disposeBag = DisposeBag()

 

기존에 작성한 ViewModel의 인스턴스와 DisposeBag 을 하나 생성합니다.

 

이후, ViewModel의 결과를 View에 즉각 반영하기 위한 Binding 로직을 작성합니다.

 

// Binding UI
private func binding() {
    // 사용자의 email 입력을 viewModel의 emailTextRelay로 바인딩

    emailTextField.rx.text
        .orEmpty
        .bind(to: viewModel.emailTextRelay)
        .disposed(by: disposeBag)

    // 사용자의 password 입력을 viewModel의 pwTextRelay로 바인딩
    pwTextField.rx.text
        .orEmpty
        .bind(to: viewModel.pwTextRelay)
        .disposed(by: disposeBag)

    // viewModel의 isValid 결과값 (Observable<Bool>)을 로그인 버튼의 isEnabled 속성에 바인딩
    viewModel.isValid()
        .bind(to: loginButton.rx.isEnabled)
        .disposed(by: disposeBag)

    // viewModel의 isValid 결과값 (Observable<Bool>)을 로그인 버튼의 alpha 속성에 바인딩
    viewModel.isValid()
        .map { $0 ? 1 : 0.3 }
        .bind(to: loginButton.rx.alpha)
        .disposed(by: disposeBag)

    // 사용자의 email 입력 이벤트를 구독하여 콘솔 로그에 출력
    emailTextField.rx.text
        .orEmpty
        .subscribe(onNext: {
            print("email: \($0)")
        })
        .disposed(by: disposeBag)

    //  사용자의 password 입력 이벤트를 구독하여 콘솔 로그에 출력
    pwTextField.rx.text
        .orEmpty
        .subscribe(onNext: {
            print("password: \($0)")
        })
        .disposed(by: disposeBag)

 

위와 같이 binding 작업을 위한 함수를 생성하고 이를 viewDidLoad()에서 호출합니다.

 

override func viewDidLoad() {
    super.viewDidLoad()
    pwTextField.isSecureTextEntry = true
    binding()
}

 

프로그램을 실행 시킨 후, email과 PW TextField에 값을 입력해봅니다.

 

image

 

입력한 값이 실시간으로 콘솔 로그에 출력됩니다.

 

image

또한, 앞서 작성한 email & PW 유효성을 만족하면 로그인 버튼의 alpha 값이 1로 초기화되면서 isEnabled 속성 또한 True 값으로 초기화됩니다.

 

오늘은 RxSwift와 RxCocoa를 통해 정말 간단한 Login 프로세스를 구현해보았습니다.

 

매우 간단한 예제임에도 불구하고 MVVM 패턴과 Rx를 이용해보니 확실히 기존에 사용하던 방법에 비하여 유지보수성, View 업데이트 등 다양한 이점을 얻을 수 있었습니다.

'iOS' 카테고리의 다른 글

[iOS] [Swift] setNeedsLayout & layoutIfNeeded  (0) 2020.10.20
[iOS] [Swift] Protocol Oriented Programming  (0) 2020.10.16
[iOS] [Swift] Convenince init  (0) 2020.10.07
[iOS] RxSwift 시작하기  (0) 2020.09.29
[iOS] KingFisher 소개  (1) 2020.09.22