RxSwift의 example을 코드로 쓴다(그 1)

17050 단어 RxSwiftSwift4

소개



코드에서만 RxSwift example을 다시 작성했습니다.
(레이아웃은 snapKit을 사용하고 있습니다)

example 그 1



TextFiled에 숫자를 넣으면 맨 아래 레이블에 세 개의 값의 합계가 즉시 계산되는 example


환경 구축



프로젝트 파일 만들기



이름은 무엇이든 좋지만 이번 예제에서는 RxSwift_for_code

podfile 편집


$ vi Podfile

Podfile의 내용target 'RxSwift_for_code' doRxSwift_for_code를 프로젝트 파일에서 사용한 이름으로 만드십시오.
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'

use_frameworks!

target 'RxSwift_for_code' do
    pod 'RxSwift',    '~> 4.0'
    pod 'RxCocoa',    '~> 4.0'
    pod 'SnapKit', '~> 4.0.0'
end

Podfile에 등록한 라이브러리를 사용한다 (bundler로 cocoapod를 관리하고 있기 때문에 pod의 명령을 사용할 때는 bundle exec를 앞에 붙일 필요가 있다)


$ pod install

이 때 만든 RxSwift_for_code.xcworkspace를 시작합니다.


ViewController.swift 를 열고 아래 코드를 복사하여

코드 내용


ViewController.swiftのなかみ
import UIKit
import RxSwift
import RxCocoa
import SnapKit

class ViewController: UIViewController {
    var disposeBag = DisposeBag()

    var number1: UITextField = {
        let textField = UITextField()
        textField.borderStyle = .roundedRect
        return textField
    }()
    var number2: UITextField = {
        let textField = UITextField()
        textField.borderStyle = .roundedRect
        return textField
    }()
    var number3: UITextField = {
        let textField = UITextField()
        textField.borderStyle = .roundedRect
        return textField
    }()

    var label: UILabel = {
        let label = UILabel()
        return label
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(self.number1)
        self.number1.snp.makeConstraints { (make) -> Void in
            make.width.equalTo(200)
            make.height.equalTo(50)
            make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(100)
            make.centerX.equalTo(self.view)
        }
        self.view.addSubview(self.number2)
        self.number2.snp.makeConstraints { (make) -> Void in
            make.width.equalTo(200)
            make.height.equalTo(50)
            make.top.equalTo(self.number1.snp.bottom)
            make.centerX.equalTo(self.view)
        }
        self.view.addSubview(self.number3)
        self.number3.snp.makeConstraints { (make) -> Void in
            make.width.equalTo(200)
            make.height.equalTo(50)
            make.top.equalTo(self.number2.snp.bottom)
            make.centerX.equalTo(self.view)
        }
        self.view.addSubview(self.label)
        self.label.snp.makeConstraints { (make) -> Void in
            make.width.equalTo(200)
            make.height.equalTo(50)
            make.top.equalTo(self.number3.snp.bottom)
            make.centerX.equalTo(self.view)
        }

      //観測可能なシーケンスのいずれかが要素を生成するたびに、セレクタ関数を使用して、指定された観測可能なシーケンスを1つの観測可能なシーケンスにマージします。
//orEmpty:`String?`型のコントロールプロパティを `String`型のコントロールプロパティに変換します。
Observable.combineLatest(number1.rx.text.orEmpty,number2.rx.text.orEmpty,number3.rx.text.orEmpty) { textValue1, textValue2, textValue3 -> Int in
            return (Int(textValue1) ?? 0) + (Int(textValue2) ?? 0) + (Int(textValue3) ?? 0)
        }
        //入ってきた値をStringに変換する関数
        .map { $0.description}
        //新しいサブスクリプションを作成し、オブザーバに要素を送信します。
        .bind(to: label.rx.text)
        .disposed(by: disposeBag)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}


이해를 위한 나름대로의 해석



Observable에 이어지는 것은 처리의 일련의 흐름이라고 생각한다

CombineLatest라는 함수



이 함수는 관측하는 값(이 예라면 UITextFiled의 text의 값)을 복수 넣어 하나의 데이터의 흐름으로 하는 함수라고 생각한다
public static func combineLatest<O1, O2, O3>(_ source1: O1, _ source2: O2, _ source3: O3, resultSelector: @escaping (O1.E, O2.E, O3.E) throws -> Self.E) -> RxSwift.Observable<Self.E> where O1 : ObservableType, O2 : ObservableType, O3 : ObservableType

덧붙여서 위의 함수의 정의를 살펴보면 네 번째 인수인 resultSelector는 클로저를 받는 인수이다.
맨 마지막 인수로 클로저의 경우 위의 예와 같이 밖으로 튀어 나올 수 있습니다.

즉, 네 번째 인수는 이것입니다.
textValue1은 O1.E, textValue2는 O2.E, textValue3은 O3.E에 해당하는 도중에 String형은 Int로 변환되어 클로저 내의 처리가 끝난다(Self.E→Int가 되는군요)
{ textValue1, textValue2, textValue3 -> Int in
            return (Int(textValue1) ?? 0) + (Int(textValue2) ?? 0) + (Int(textValue3) ?? 0)
        }

number1.rx.text.orEmpty의 orEmpty



orEmpty: String? 형식의 컨트롤 속성을 String 형식의 컨트롤 속성으로 변환합니다.
UITextFiled에 들어가 있는지 들어 있지 않은지 모르는 값이기 때문에 String?이라는 것이 전제 조건이라고 생각하지만, 이 데이터의 흐름에 들어갈 때는 String형으로 변환해 주는 편리한 함수라고 하는 것 같다

$0.description



직전의 클로저의 처리를 빠져나가면 Int형의 데이터가 나오게 된다
map 함수는 흐르는 각 데이터를 처리하는 함수입니다.
클로저의 인수는 $ 0으로 표현 될 수 있으므로 클로저 내에서 Int로 변환 된 값 (예 : $ 0 = 14과 같은 값)이 들어옵니다.
$0.description과 같이 description을 연결하면 $0에 들어온 값을 String형으로 변환해준다
(예 14(Int)→"14"(String))

.bind(to: label.rx.text)



마지막으로 bind 함수에 들어가기
public func bind<O>(to observer: O) -> Disposable where O : ObserverType, O.E == Self.E?

인수는 observer 형의 무엇인가의 형태 반환값은 Disposable 로 들어오는 데이터와 같은 형태일 필요가 있다

String으로 변환한 값은, UILabel 클래스의 인스턴스인 label의 text에 넣는다고 하는 것 같다

.disposed(by: disposeBag)



마지막으로 흘러 들어간 앞의 값의 반환값은 전의 단계에서 Disposable가 되어 있을 것
이것은, 처리가 끝난 후에는 관측을 그만둘 필요가 있다고 하는 것으로 보지 않는 것처럼 붙이고 있는 감각
(언젠가 제대로 이해하면 쓰고 싶다)

좋은 웹페이지 즐겨찾기