IGListKit과 RxSwift를 합쳐 보았다 🤔
IGListKit과 RxSwift를 합쳐 보았다 🤔
작년의 Try Swift New York에서 발표가 있었던 Instagram의 Feed 구현에 이용되고 있는 IGListKit (Try Swift의 발표는 여기)
현재 구현되어 있는 것은 IGListKit 중에서도 UICollectionView
그냥 다른 DataSource나 Delegate는 구현할 수 없습니다! 좋은 방법을 찾으면서 업데이트 해 나갈 수 있다고 생각합니다!
이 프로젝트는 Github에 공개되어 있으므로 복제하고 움직여보십시오!
-> htps : // 기주 b. 코 m / 유자 시오 h / R G G St t
배경
RxSwift를 사용하고 있는 프로젝트에서 IGListKit를 사용하면 아무래도, 리스트에 표시한다 UITableView
의 갱신과, 리스트를 갱신하는 메소드를 부르는 타이밍을, IGListAdapterDataSource
하는 순서등을 바꾸어 고려하지 않으면 안됩니다!
만약 리스트에 표시하는 Element의 갱신보다 먼저 리스트 자체를 갱신해 버리면, 버그나 크래쉬에 연결됩니다.
또 리스트에 표시하는 Element
는 subscribe
이 아니면 되므로, ViewModel측에 프로퍼티이 1개 증가해 버려, 이 프로퍼티도 매회 갱신할 필요가 옵니다.
👇👇👇👇👇👇
이 문제를 해결하기 위해 Element
를 그대로 Observable
Example
이번에는 실제로 IGListKit과 RxSwift를 사용하여 다음 UI를 구현해 보았다.
이 프로젝트는 리포지토리에 게시되었습니다.
| About RxIGListKit
RxSwift에서 Observable<Element> 와 DataSource 에는 UITableView 메서드가 준비되어 있어 DataSource 를 정의해, 그 안에 지정한 UICollectionView 의 Observable 를 바인드 하는 것만으로 갱신을 할 수 있습니다.
이번에는 IGListAdapter에 items(dataSource: _) 를 구현했습니다 🚀
Step 1
Element 및 items(dataSource: _) 와 마찬가지로 UITableView 프로토콜을 정의합니다.
protocol RxIGListAdapterDataSource {
associatedtype Element
func listAdapter(_ adapter: IGListAdapter, observedEvent: Event<Element>) -> Void
}
Step 2
IGListAdapter에 Reactive Extension으로 UICollectionView를 추가!
func items<DataSource: RxIGListAdapterDataSource & IGListAdapterDataSource,
O: ObservableType>(dataSource: DataSource)
-> (_ source: O)
-> Disposable where DataSource.Element == O.E {
return { source in
let subscription=source
.subscribe { dataSource.listAdapter(self.base, observedEvent: $0) }
return Disposables.create {
subscription.dispose()
}
}
}
Step 3
나머지는 DataSource를 정의하고 연결하는 것입니다 👍
How to use
DataSource를 정의해, 그 안의 RxIGListAdapterDataSource 와 같은 형태의 스트림을 연결하는 것만으로 IGListKit로 구현된 리스트를 갱신할 수가 있습니다.
lazy privatevar adapter: IGListAdapter = {
return IGListAdapter(updater: IGListAdapterUpdater(), viewController: self, workingRangeSize: 2)
} ()
private let disposeBag = DisposeBag()
private let dataSource = DataSource()
override func viewDidLoad() {
super.viewDidLoad()
adapter.rx.setDataSource(dataSource)
.disposed(by: disposeBag)
viewModel.feeds
.drive(adapter.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
}
final class DataSource: NSObject, IGListAdapterDataSource, RxIGListAdapterDataSource {
typealias Element = [Foo]
var elements: Element = []
func listAdapter(_ adapter: IGListAdapter, observedEvent: Event<Element>) {
if case .next(let elements) = observedEvent {
self.elements = elements
adapter.performUpdates(animated: true)
}
}
func objects(for listAdapter: IGListAdapter) -> [IGListDiffable] {
return elements
}
func listAdapter(_ listAdapter: IGListAdapter, sectionControllerFor object: Any) -> IGListSectionController {
return SectionController()
}
func emptyView(for listAdapter: IGListAdapter) -> UIView? {
return nil
}
}
Help
다음은 IGListSectionType을 RxSwift화해 가고 싶기 때문에 무엇인가 좋은 방법이 있으면 코멘트를 받을 수 있으면 다행입니다. items(dataSource: _) 이나 Element 와 같이 ModelSelected 등을 추가할 수 있으면~라고 생각합니다. 리포지토리 -> htps : // 기주 b. 코 m / 유자 시오 h / R G G St t
Reference
이 문제에 관하여(IGListKit과 RxSwift를 합쳐 보았다 🤔), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yuzushioh/items/788acebbf0c3b53caf6c
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(IGListKit과 RxSwift를 합쳐 보았다 🤔), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/yuzushioh/items/788acebbf0c3b53caf6c텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)