본문 바로가기
iOS/Swift

RxSwift 시작하기 (설치 & Button Tap Event - DisposeBag, rx.Tap )

by DnaJ 2019. 5. 3.
반응형

RxSwift 시작하기RxSwift 시작하기 (설치 & Button Tap Event)

RxSwift설치부터 tap eventbindsubcribe를 이용하여 이벤트를 바인딩 하는 것을 포스팅 할것 이다.

 

 

 

이전에는 RxSwift의 간략적인 내용을 포스팅 했다.

2019/04/26 - [iOS/Swift] - RxSwift (ReactiveX)

 

RxSwift (ReactiveX)

RxSwift (ReactiveX) RxSwift는 Rx 와 Swift의 합성어다. Rx : Reactive extension <- x는 eXtension에 X를 사용하고 있다. (왜 두번째 스펠링으로 했는지.... X가 두번째 있어서 그런가....?) - Reactive : 반응..

myseong.tistory.com

이번 포스팅은 RxSwift설치부터 간단한 사용까지 포스팅 할것이다.

 

RxSwift는 라이브러리 이기 때문에 CocoaPods으로 설치후 사용한다. (다른 방법도 있지만 제일 편한것 같다.)

아래 코드는 Podfile의 내용이다. 현재는 4.0을 사용하고 있지만 GitHub에 들어가서 최신버전을 확인하기 바란다.

 

 

https://play.google.com/store/apps/details?id=com.danchoo.tagalbum&hl=ko

 

태그앨범 - Google Play 앱

사진과 앨범을 태그로 관리하세요. 결혼식, 팬클럽, 동호회등 원하는 카테고리를 만들어 정리해보세요. 사진에 태그를 설정하여 손쉽게 찾아보세요!

play.google.com

 

 

======================================================================================================

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

 

ReactiveX/RxSwift

Reactive Programming in Swift. Contribute to ReactiveX/RxSwift development by creating an account on GitHub.

github.com

 

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

 

해피시소마켓 : 네이버쇼핑 스마트스토어

SISO

smartstore.naver.com

 

======================================================================================================

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은 Disposableestension으로 구현되어있다.

 

======================================================================================================

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

 

ReactiveX - Subscribe operator

In RxJS, you can subscribe to an Observable in two ways: subscribe a single function to either the onNext, the onCompleted, or onError notifications from an Observable, with subscribeOnNext, subscribeOnCompleted, or subscribeOnError respectively subscribe

reactivex.io

https://github.com/ReactiveX/RxSwift/blob/master/RxSwift/Disposables/DisposeBag.swift

 

ReactiveX/RxSwift

Reactive Programming in Swift. Contribute to ReactiveX/RxSwift development by creating an account on GitHub.

github.com

http://reactivex.io/

 

ReactiveX

CROSS-PLATFORM Available for idiomatic Java, Scala, C#, C++, Clojure, JavaScript, Python, Groovy, JRuby, and others

reactivex.io

 

 

반응형

댓글