RxSwift를 이용한 Login 기능 구현
이번에는 RxSwift
와 RxCocoa
를 이용하여 간단한 Login 프로세스를 구현해보도록 하겠습니다.
Layout
이번에 만들어 볼 앱의 레이아웃은 위 사진과 같습니다.
간단히 Email과 Password를 입력받기 위한 TextField
와 로그인 진행을 위한 Button
을 하나 생성하였습니다.
ViewModel
View를 위해 ViewModel이 제공해야 하는 프로퍼티와 기능에 대하여 먼저 정의하겠습니다.
Input
과 Output
을 나눠서 살펴보면 아래와 같이 정리할 수 있습니다.
-
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에 값을 입력해봅니다.
입력한 값이 실시간으로 콘솔 로그에 출력됩니다.
또한, 앞서 작성한 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 |