2022/01/15 CMC iOS Conference 자료
수익형 앱 런칭 동아리 CMC 9기로 활동하며, iOS Conference Day에 발표로 진행하였던 RxSwift Traits에 관한 내용이에요. 조금 급하게 준비하느라 부연 설명이 부족하여 추후 한번 다시 Traits에 관해 정리를 해야겠다는 생각이 듭니다! 그래도 다른 iOS 분들이 투표를 많이 해주셨는지 부상도 받았습니다:)
비동기 프로그래밍을 관찰 가능한 흐름으로 지원해주는 API.
옵저버 패턴과 이터레이터 패턴 그리고 함수형 프로그래밍을 조합한 반응형 프레임워크.
세 가지 유형의 이벤트만 방출
enum Event<Element> {
case next(Element) // next element of a sequence
case error(Swift.Error) // sequence failed with error
case completed // sequence terminated successfully
}
Finite Observable (단일 스트림 요소 관리)
func download(file: String) -> Observable<Data> {
return Observable<Data>.create { emitter in
let task = URLSession.shared.dataTask(with: URL(string: file)!) { data, _, error in
guard let data = data,
error = nil else {
emitter.onError(error!)
return
}
emitter.onNext(data)
emitter.onCompleted()
}
task.resume()
return Disposables.create { task.cancel() }
}
}
Network.download(file: "https://www...")
.subscribeOn(ConcurrentDispatchQueueScheduler.init(queue: DispatchQueue.global()))
.subscribe(onNext: { data in
//임시 파일에 데이터 추가
}, onError: { error in
//사용자에게 에러 표현
}, onCompleted: {
//다운로드 된 파일 사용
})
.disposed(by: disposeBag)
Infinite Observable (무한 스트림 요소 관리)
UIDevice.rx.orientation
.subscribe(onNext: { current in
switch current {
case .landscape:
// 가로모드 배치
case .portrait:
// 세로모드 배치
}
})
.disposed(by: disposeBag)
단일 요소만을 한번 방출
success, error의 이벤트로 구성되어 있음.
Single
을 사용하는 일반적인 예는 응답, 오류만 반환할수 있는 HTTP 요청을 수행하는데 사용되지만 단일요소를 사용하여 무한 스트림 요소가 아닌 단일 요소만 관리하는 경우를 모델하는데 사용할수 있음.
func download(file: String) -> Single<Data> {
return Single<Data>.create { single in
let task = URLSession.shared.dataTask(with: URL(string: file)!) { data, _, error in
guard let data = data,
error = nil else {
single(.error(error!)
return
}
single(.success(data))
}
task.resume()
return Disposables.create { task.cancel() }
}
}
Network.download(file: "https://www...")
.subscribeOn(ConcurrentDispatchQueueScheduler.init(queue: DispatchQueue.global()))
.subscribe(onSuccess: { json in
//다운로드 된 파일 사용
}, onError: { error in
//사용자에게 에러 표현
})
.disposed(by: disposeBag)
어떤 요소도 방출하지 않음
complete, error의 이벤트로 구성되어 있음.
Completable
은 완료에 따른 요소에 신경쓰지 않은 경우 사용하면 유용합니다. 요소를 내보낼수 없는 경우 Observable를 사용하여 비교할수 있습니다.
func cacheLocally() -> Completable {
return Completable.create { completable in
// Store some data locally
...
...
guard success else {
completable(.error(CacheError.failedCaching))
return Disposables.create {}
}
completable(.completed)
return Disposables.create {}
}
}
cacheLocally()
.subscribe(onCompleted: {
print("Completed with no error")
}, onError: { error in
print("Completed with an error: \(error.localizedDescription)")
})
.disposed(by: disposeBag)
RxCocoa란?
다양한 protocol을 extension한 것들과 UIKit을 위한 rx영역을 제공하는 프레임워크
오류가 없습니다.(오류를 방출하지 않는다는 의미)
observe는 Main scheulder에서 발생합니다.
// 기존 방법
Network.fetchName(uid: "dasdjwlqwe")
.subscribeOn(ConcurrentDispatchQueueScheduler.init(queue: DispatchQueue.global()))
.observeOn(MainScheduler.instance) // Main Thread
.catchErrorJustReturn("이름") //next, error, completed, dipose
.materialize()
... // completed, dispose 처리
.dematerialize()
.bind(to: label.rx.text)
.disposed(by: disposeBag)
// asDriver
Network.fetchName(uid: "dasdjwlqwe")
.subscribeOn(ConcurrentDispatchQueueScheduler.init(queue: DispatchQueue.global()))
.asDriver()
.asDriverJustReturn("이름")
.drive(label.rx.text)
.disposed(by: disposeBag)
Driver와 같은 기능 But, Driver는 초기값 방출하고 Signal은 안함(Behavior: Publish)