[RxSwift] #6 performSegue / Single, Maybe, Completable
raywenderlich RxSwift Ch1~4
raywenderlich 의 RxSwift 책을 기반으로 한 RxSwift 정리 를 보고 공부하고 있다. Ch1 ~ Ch3 의 경우는 앞서 정리했던 곰튀김님의 강의에서 들은 Observable과 Subject를 조금 더 실용적인 예제로 살펴보고 문제도 풀어보는 정도의 내용이었다.
Ch4는 Relay, Subject 를 이용한 이미지 콜라주 어플리케이션 예제였다. UI는 이미 다 작성된 뼈대 위에 RxSwift를 얹어서 Clear, Save, + 버튼에 대한 코드를 작성하는 것이었다. 예제 코드는 여기에!
PhotosViewController (이하 PhotosVC), MainViewController (이하 MainVC)
원래 좋아하는 공부 방식인 코드 순서대로 따라가는 것 정리하기의 경우는 원글에서 너무 잘 해두셨기 때문에, 새로 알게 된 포인트들에 대해서 정리해보려고 한다.
1. VC 이동 시, 데이터 주고 받기
MainVC -> PhotosVC 로 이동하여 PhotosVC 에서 사진을 골라서 MainVC 에 사진 데이터를 넘겨줘야하는 이런 경우에는, 보통 delegate 를 이용해서 넘겨주기 마련이다. PhotosVC 에서는 delegate 를 이용하여 처리를 위임하고 실 처리는 MainVC 의 함수에서 한다.
하지만, Rx에서는 delegate 패턴을 사용하지 않는다.
Observable 로 양쪽 VC에서 데이터의 흐름을 구독하게 할 수 있기 때문이다.
// MainVC
@IBAction func actionAdd() {
let photosVC = storyboard?.instantiateViewController(withIdentifier: "PhotosViewController") as! PhotosViewController
navigationController?.pushViewController(photosVC, animated: true)
// 그 대신 이렇게 이동할 VC의 Observable 을 구독하여 데이터를 받아온다.
photosVC.selectedPhotos
.subscribe(onNext: { [weak self] image in
guard let images = self?.images else { return }
images.accept(images.value + [image])
}, onDisposed: {
print("photo selection completed")
})
.disposed(by: disposeBag)
}
// PhotosVC
private var selectedPhotosSubject = PublishSubject<UIImage>()
// MainVC 에서 selectedPhotos에 데이터를 보낼 일이 없기 때문에, 데이터의 수정을 막기 위해 Observable 을 구독하게 한다.
var selectedPhotos: Observable<UIImage> {
return selectedPhotosSubject.asObservable()
}
대신 여기서 신경써야 하는 부분은, MainVC 에서 selectedPhotos 를 구독하고 있기 때문에, PhotosVC 가 없어진다고 해서 selectedPhotosSubject 가 메모리에서 해제되지 않는다는 점이다.
// PhotosVC
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
selectedPhotosSubject.onCompleted()
}
viewWillDisappear 에서 명시적으로 Subject를 종료시켜서 해제하자.
2. Single, Maybe, Completable / Custom Observable
Custom Observable 코드를 (photo id 하나만 emit 하는) Single 을 이용해서 refactoring 해보았다.
static func save(_ image: UIImage) -> Single<String> {
// return Observable.create({ observer in
return Single.create (subscribe: { observer in
var saveAssetId: String?
PHPhotoLibrary.shared().performChanges({
let request = PHAssetChangeRequest.creationRequestForAsset(from: image)
saveAssetId = request.placeholderForCreatedAsset?.localIdentifier
}, completionHandler: { success, error in
DispatchQueue.main.async {
if success, let id = saveAssetId {
// observer.onNext(id)
// observer.onCompleted()
observer(.success(id))
} else {
observer(.error(error ?? Errors.couldNotSavePhoto))
}
}
})
return Disposables.create()
})
}
}
3. guard let else { return }
RxSwift 에서만 쓰이는 내용은 아니지만, 부분에 불러와야 하는 요소 중 nil 이 될 가능성이 있는 것을 불러와서 사용하면 guard 문 뒤로는 ? ! 를 붙일 필요가 없어서 편하게 사용할 수 있다. 적극 활용해야겠다.
느낀점
잘 모르겠을 때는 프로젝트로 직접 코드를 쳐보는게 최고라는 생각에 그냥 순서대로 쭉 따라서 코드를 한번 치고 최대한 흐름을 기억해보면서 조금씩 치팅하면서 코드를 또 쳐보는 방식으로 공부를 진행했다. 조금이나마 Observable 을 사용해서 데이터를 처리하는 방식을 손에 익힌 것 같다.
어느 상황에서 어떤 것을 써야하는지는 아직 감이 잘 안오지만, 강의 자료 Challenge 에 있는 것처럼 Observable로 만들고 Single로 리팩토링 하는 방식도 좋은 방식이니까!!! 일단 최대한 익숙해지자.
Author And Source
이 문제에 관하여([RxSwift] #6 performSegue / Single, Maybe, Completable), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@ddosang/RxSwift-6-performSegue-Single-Maybe-Completable저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)