Reactive Cocoa: Function Reactive Programming!
Bài đăng này đã không được cập nhật trong 7 năm
Khởi động
Auto Binding ~> Code Step 1 Tạo IBOutlet như bình thường chúng ta vẫn làm.
// MARK: - IBOutlet
@IBOutlet weak fileprivate var emailTextField: UITextField!
@IBOutlet weak fileprivate var passwordTextField: UITextField!
@IBOutlet weak fileprivate var passwordAgainTextField: UITextField!
@IBOutlet weak fileprivate var useCreditCardSwitch: UISwitch!
@IBOutlet weak fileprivate var creditCardTextField: UITextField!
@IBOutlet weak fileprivate var cardStatusLabel: UILabel!
@IBOutlet weak fileprivate var verifyCardButton: UIButton!
@IBOutlet weak fileprivate var activityIndicator: UIActivityIndicatorView!
@IBOutlet weak fileprivate var registerButton: UIButton!
Step 2 binding View ~> viewModel
viewModel.email <~ emailTextField.reactive.continuousTextValues.skipNil()
viewModel.password <~ passwordTextField.reactive.continuousTextValues.skipNil()
viewModel.passwordAgain <~ passwordAgainTextField.reactive.continuousTextValues.skipNil()
viewModel.useCreditCard <~ useCreditCardSwitch.reactive.isOnValues
viewModel.creditCardNumber <~ creditCardTextField.reactive.continuousTextValues.skipNil()
Step 3 Proterties in viewModel được binding từ view(or controller)
/// Properties
var email = MutableProperty<String>("")
var password = MutableProperty<String>("")
var passwordAgain = MutableProperty<String>("")
var useCreditCard = MutableProperty<Bool>(false)
var creditCardNumber = MutableProperty<String>("")
var cardStatus = MutableProperty<CardStatus>(.notVerified)
Step 4 trong viewModel có các SignalProducer phát ra tín hiệu, view có thể bắt các sự kiện ở đây để cấu hình view
/// SignalProducer: phat tin hieu
var correctEmailProducer: SignalProducer<Bool, NoError>!
var correctPasswordProducer: SignalProducer<Bool, NoError>!
var correctCreditCardProducer: SignalProducer<Bool, NoError>!
var correctInputProducer: SignalProducer<Bool, NoError>!
Step 5 Cấu hình SignalProducer, và các giá trị mặc định.
// cau hinh tin hieu va property
extension RegisterViewModel {
func initBindings() {
//tao trang thai mac dinh creditCardNumber
creditCardNumber.producer.startWithValues { _ in
self.cardStatus.value = .notVerified
}
//kiem tra email
correctEmailProducer =
email.producer
.map({ (emailText) -> Bool in
emailText.isValidEmailContains()
})
//kiem tra pass
correctPasswordProducer =
SignalProducer.combineLatest(password.producer, passwordAgain.producer)
.map { (passwordText, passwordAgainText) -> Bool in
return (passwordText.characters.count > 5) && (passwordText == passwordAgainText)
}
//kiem tra card
correctCreditCardProducer =
SignalProducer.combineLatest(useCreditCard.producer, cardStatus.producer)
.map({ (useCard, cardStatus) -> Bool in
if !useCard {
return true
}
else if cardStatus == .verified {
return true
}
return false
})
//kiem tra email password va card
correctInputProducer =
SignalProducer.combineLatest(correctEmailProducer, correctPasswordProducer, correctCreditCardProducer)
.map({ (email, password, card) -> Bool in
return email && password && card
})
}
//khi button verify duoc press se goi ham nay
func verifyCardNumber() {
cardStatus.value = .verifying
ServiceHelper.sharedInstance.validateCreditCardNumber(creditCardNumber.value)
.startWithValues { valid in
self.cardStatus.value = valid ? .verified : .denied
}
}
//khi button register duoc press se goi ham nay
func createMainAppViewModel() -> MainAppViewModel {
let mainAppViewModel = MainAppViewModel()
mainAppViewModel.email = email.value
mainAppViewModel.creditCardNumber = useCreditCard.value ? creditCardNumber.value : nil
return mainAppViewModel
}
}
Step 6 ở view đơn giản mình sẽ lắng nghe từ viewModel,cấu hình view khi có sự kiện(vd correct pass thì enable button)
// lang nghe su kien emailTextField change all value
emailTextField.reactive.continuousTextValues.skipNil().observeValues { email in
print(email)
}
// lang nghe tin hieu correctEmailProducer
viewModel.correctEmailProducer.startWithValues { (correct) in
self.emailTextField.textColor = correct ? UIColor.gray : UIColor.red
}
// lang nghe tin hieu correctInputProducer
//registerButton.reactive.isEnabled <~ viewModel.correctInputProducer
//or
viewModel.correctInputProducer.startWithValues({ correct in
self.registerButton.isEnabled = correct
})
// lang nghe tin hieu correctPasswordProducer
viewModel.correctPasswordProducer.startWithValues { (correct) -> () in
let backgroundColor = correct ? UIColor.gray : UIColor.red
self.passwordTextField.textColor = backgroundColor
self.passwordAgainTextField.textColor = backgroundColor
}
//lang nghe property useCreditCard --> producer
viewModel.useCreditCard.producer.startWithValues { (useCard) -> () in
self.tableView.beginUpdates()
self.tableView.endUpdates()
}
//lang nghe property cardStatus --> producer
viewModel.cardStatus.producer.startWithValues { (status) -> () in
switch status {
case .notVerified:
self.cardStatusLabel.text = "Card has not been verified yet"
self.activityIndicator.isHidden = true
self.verifyCardButton.isHidden = false
case .verifying:
self.cardStatusLabel.text = "Card is currently being verified"
self.activityIndicator.isHidden = false
self.verifyCardButton.isHidden = true
case .verified:
self.cardStatusLabel.text = "Card is verified"
self.activityIndicator.isHidden = true
self.verifyCardButton.isHidden = true
case .denied:
self.cardStatusLabel.text = "Card is denied"
self.activityIndicator.isHidden = true
self.verifyCardButton.isHidden = false
}
}
Quan trọng vẫn là kết quả nó sẽ làm những gì!
- Nhiều lắm, mình cũng không biết hết nhưng trước hết nó hết sức là clean code.
- Thuận lợi phát triển theo mô hình MVVM và MVVM-C(binding data)
- nó đã clean code rồi thì -> dễ maintain
Tham khảo tại đây ReactiveCocoa Không liên quan mấy nhưng đây là link Demo RxCocoa nói chung cũng thuộc FRP
Kết Thực ra trong project demo mình đã comment rất rõ ràng và dễ đọc, mình mới tìm hiểu về Reactive Cocoa thôi cũng chưa nắm được hết mọi thứ trong Reactive Cocoa, tìm được 1 project Demo về Reactive Cocoa khó quá nên mình quyết định viết 1 bài Demo để các bạn tham khảo, kiến thức về FPR đã được rất nhiều các anh/chị đi trước viết và đây là sức mạnh nho nhỏ của FRP mà mình muốn giới thiệu,cám ơn các bạn đã đọc bài viết của mình.
All rights reserved