RxSwift 시작하기RxSwift 시작하기 (설치 & Button Tap Event)
RxSwift설치부터 tap event를 bind와 subcribe를 이용하여 이벤트를 바인딩 하는 것을 포스팅 할것 이다.
이전에는 RxSwift의 간략적인 내용을 포스팅 했다.
2019/04/26 - [iOS/Swift] - RxSwift (ReactiveX)
이번 포스팅은 RxSwift설치부터 간단한 사용까지 포스팅 할것이다.
RxSwift는 라이브러리 이기 때문에 CocoaPods으로 설치후 사용한다. (다른 방법도 있지만 제일 편한것 같다.)
아래 코드는 Podfile의 내용이다. 현재는 4.0을 사용하고 있지만 GitHub에 들어가서 최신버전을 확인하기 바란다.
https://play.google.com/store/apps/details?id=com.danchoo.tagalbum&hl=ko
======================================================================================================
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
use_frameworks!
target 'projectNanme' do
#RxSwift
pod 'RxSwift', '~> 4.0'
pod 'RxCocoa', '~> 4.0'
end
======================================================================================================
RxSwift는 RsSwift와 RxCocoa로 이루어져 있다.
추가적인 기능을 하는 것도 따로있다. 라이브러리 크기때문에 나누어 놓은것인지...
RxGesture, RxAnimated, RxDataSources 등 추가적인 기능에 대한 정의가 따로 있다.
필요한 라이브러리를 따로 추가해서 사용해야 한다.
GitHub : https://github.com/ReactiveX/RxSwift
RxSwift로 버튼 제어하기
RxSwift의 간단한 예제를 통해 조금씩 포스팅을 진행하려고 한다.
storyboard를 사용하여 Navigation Controller를 생성후 오른쪽 상단에 버튼을 넣어 Rx로 Tap Event를 bind 할것이다.
1. UIController에 Navigation Controller 추가
storyboard의 UIViewController를 선택 -> 상단 메뉴 -> Editor -> Embed In -> Navigation Controller
2. 코드로 버튼 생성 및 Tap Event Bind
https://smartstore.naver.com/happysiso
======================================================================================================
import UIKit
import RxSwift
class SampleViewController: UIViewController {
let disposeBag = DisposeBag()
@IBOutlet var height: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
initNavigation()
}
private func initNavigation() {
self.navigationItem.hidesBackButton = false
self.navigationItem.rightBarButtonItem = getRightBarButton()
}
private func getRightBarButton() -> UIBarButtonItem {
// 버튼 생성
let button = UIButton()
button.setTitle("확인", for: .normal)
button.setTitleColor(UIColor.black, for: .normal)
// Tap Event
button.rx.tap.bind { [weak self] in
self?.onTapButton()
}.disposed(by: disposeBag)
return UIBarButtonItem(customView: button)
}
private func onTapButton() {
print("onTapButton")
}
}
======================================================================================================
코드를 실행시키면 위와같은 화면이 나온다. (상단만 캡처했다.)
확인 버튼을 누르게 되면 output으로 onTapButton 로그가 나올 것이다.
이제부터 코드를 살펴 보자.
RxSwift를 사용하려면 RxSwift를 import해야한다.
1. rx.tap
button.rx.tap.bind { [weak self] in
self?.onTapButton()
}.disposed(by: disposeBag)
bind : 묶다, 연결시키다.
- rx.tap.bind { in }: tap이벤트를 연결시키는 역활을 한다.
원형 : public func bind(onNext: @escaping (Self.E) -> Void) -> Disposable
rx.tap.bind(onNxet: { in }) 이렇게 써도 된다.
xcode에서 친절하게 자동완성을 하면 onNext가 없는 Closure로 완성이 된다.
onNext를 쓰지 않고 조금이라도 더 간단하고 명확하게 사용하기 위함인 것으로 보인다.
2. DisposeBag
let disposeBag = DisposeBag()
Dispose : ~을 없애다, 처리하다, 해치우다
Bag : 봉투, 포대, 자루, 가방
DisposeBag 단어의 뜻을 보았을때 '봉투, 포대, 자루, 가방과 같은 것들을 없애다' 라고 해석이 가능하다.
DisposeBag은 우리가 등록한 Observable을 담고 있다가 해제를 시켜주는 역활을 한다.
Objective C를 사용할때 우리는 NSNotificationCenter로 observer를 등록 한 후 필요가 없어졌을 때 oberver를 해제시켜준다.
이전에는 observer를 해제 시켜주지 않아서 혹은 해제가 되지 않아서 메모리 릭이 발생하곤 한다.
RxSwfit에서 이것을 해결하기 위하여 DisposeBag을 사용한다.
DisposeBag을 가지고 있는 Object가 소멸됐을 때 DiposeBag이 담고있던 Observerable을 모두 제거해준다.
각 Observerable에 Dispose를 호출 할 수 있지만 모든 Observable을 관리 하기에는 비효율 적이다.
Disposable
bind는 Disposable를 반환한다.
Disposable : 사용 후 버릴 수 있는, 일회용의
Disposable은 아래와 같이 정의가 되어있는 protocol이다.
======================================================================================================
/// Represents a disposable resource.
public protocol Disposable {
/// Dispose resource.
func dispose()
}
======================================================================================================
DisposeBag의 설명과 같이 Observable의 사용이 끝났을 때 Observer를 해제 시켜주기 위하여 사용한다.
Observable을 한번에 관리하기 위하여 rx.bind.{}.disposed(by: disposeBag) 와 같이 DisposeBag을 사용한다.
disposed(by: ) function은 Disposable의 estension으로 구현되어있다.
======================================================================================================
extension Disposable {
/// Adds `self` to `bag`
///
/// - parameter bag: `DisposeBag` to add `self` to.
public func disposed(by bag: DisposeBag) {
bag.insert(self)
}
}
======================================================================================================
rx.tap.subscribe로 변경하기
======================================================================================================
import UIKit
import RxSwift
class SampleViewController: UIViewController {
let disposeBag = DisposeBag()
@IBOutlet var height: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
initNavigation()
}
private func initNavigation() {
self.navigationItem.hidesBackButton = false
self.navigationItem.rightBarButtonItem = getRightBarButton()
}
private func getRightBarButton() -> UIBarButtonItem {
// 버튼 생성
let button = UIButton()
button.setTitle("확인", for: .normal)
button.setTitleColor(UIColor.black, for: .normal)
// Tap Event
// button.rx.tap.bind { [weak self] in
// self?.onTapButton()
// }.disposed(by: disposeBag)
// Tap Event
button.rx.tap.subscribe(onNext: { [weak self] in
self?.onTapBtutton()
}).disposed(by: disposeBag)
return UIBarButtonItem(customView: button)
}
private func onTapButton() {
print("onTapButton")
}
}
======================================================================================================
subscribe
subscribe : 구독하다. 가입하다
RxSwift를 하면 subscribe를 많이 사용하게 된다.
======================================================================================================
/**
Subscribes an element handler, an error handler, a completion handler and disposed handler to an observable sequence.
- parameter onNext: Action to invoke for each element in the observable sequence.
- parameter onError: Action to invoke upon errored termination of the observable sequence.
- parameter onCompleted: Action to invoke upon graceful termination of the observable sequence.
- parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has
gracefully completed, errored, or if the generation is canceled by disposing subscription).
- returns: Subscription object used to unsubscribe from the observable sequence.
*/
public func subscribe(onNext: ((Self.E) -> Void)? = nil,
onError: ((Error) -> Void)? = nil,
onCompleted: (() -> Void)? = nil,
onDisposed: (() -> Void)? = nil) -> Disposable
======================================================================================================
button.rx.tap.subscribe(onNext: { [weak self] in
self?.onTapBtutton()
}).disposed(by: disposeBag)
======================================================================================================
subscribe는 '구독하다' 라는 뜻을 가지고있다. subscribe를 호출한 시점부터 observing을 시작하게 된다.
onNext
Observable은 Observable이 항목을 내보낼 때마다이 메서드를 호출합니다. 이 메서드는 Observable에 의해 생성 된 항목을 매개 변수로 사용합니다. (출처: http://reactivex.io/documentation/operators/subscribe.html)
참고 링크
http://reactivex.io/documentation/operators/subscribe.html
https://github.com/ReactiveX/RxSwift/blob/master/RxSwift/Disposables/DisposeBag.swift
'iOS > Swift' 카테고리의 다른 글
RxSwift property observe (BehaviorRelay, Variable) (0) | 2019.05.25 |
---|---|
RxSwift 객체 구독하기 (Observable) (0) | 2019.05.18 |
RxSwift (ReactiveX) (0) | 2019.04.26 |
Swift Contacts read and write (주소록 읽기, 쓰기) (0) | 2019.01.13 |
Swift Realm (2) - 조회하기 (0) | 2019.01.06 |
댓글