Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
5分で学ぶ差分更新とRxDataSources
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Yuji Hato
April 10, 2018
Technology
0
360
5分で学ぶ差分更新とRxDataSources
Learn in 5 minutes
Incremental updates and RxDataSources
Yuji Hato
April 10, 2018
Tweet
Share
More Decks by Yuji Hato
See All by Yuji Hato
ABEMAにおける 生成AI活用の現在地 / The Current Status of Generative AI at ABEMA
dekatotoro
1
1.1k
ABEMAモバイルアプリ開発のDevOps戦略
dekatotoro
1
710
Multiplatform Engineering Roadmap for the Future
dekatotoro
1
150
Introduction to RIBs
dekatotoro
5
1.4k
継続的な開発スタイル 「AbemaTV iOSアプリを週一で リリースしている話」
dekatotoro
6
4.2k
iOS Adaptive UI - 解像度の異なるデバイスや画面の向きに対応する 最適なレイアウトへ -
dekatotoro
0
530
動画アプリをなめらかに動かす技術 - iOS -
dekatotoro
0
490
AbemaTV モバイルアプリの開発体制と 開発プロセスの話
dekatotoro
0
290
Apple TV - tvOS入門 -
dekatotoro
0
170
Other Decks in Technology
See All in Technology
来期の評価で変えようと思っていること 〜AI時代に変わること・変わらないこと〜
estie
0
110
AIエージェント勉強会第3回 エージェンティックAIの時代がやってきた
ymiya55
0
150
サイボウズ 開発本部採用ピッチ / Cybozu Engineer Recruit
cybozuinsideout
PRO
10
76k
QA組織のAI戦略とAIテスト設計システムAITASの実践
sansantech
PRO
1
220
イベントで大活躍する電子ペーパー名札を作る(その2) 〜 M5PaperとM5PaperS3 〜 / IoTLT @ JLCPCB オープンハードカンファレンス
you
PRO
0
210
【社内勉強会】新年度からコーディングエージェントを使いこなす - 構造と制約で引き出すClaude Codeの実践知
nwiizo
27
13k
Why we keep our community?
kawaguti
PRO
0
320
脳が溶けた話 / Melted Brain
keisuke69
1
1.1k
Blue/Green Deployment を用いた PostgreSQL のメジャーバージョンアップ
kkato1
0
160
20260323_データ分析基盤でGeminiを使う話
1210yuichi0
0
190
君はジョシュアツリーを知っているか?名前をつけて事象を正しく認識しよう / Do you know Joshua Tree?
ykanoh
4
140
非同期・イベント駆動処理の分散トレーシングの繋げ方
ichikawaken
1
160
Featured
See All Featured
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
1
330
Documentation Writing (for coders)
carmenintech
77
5.3k
The World Runs on Bad Software
bkeepers
PRO
72
12k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.1k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.2k
Heart Work Chapter 1 - Part 1
lfama
PRO
5
35k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
54k
Claude Code のすすめ
schroneko
67
220k
Bash Introduction
62gerente
615
210k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.1k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.1k
Transcript
AbemaTV iOSࣾϥϯνษڧձ 2018/04/10 Yuji Hato 5ͰֶͿ ࠩߋ৽ͱRxDataSources
About me Yuji Hato CyberAgent, Inc. / AbemaTV, Inc. dekatotoro
@dekatotoro Contributed services
RxDataSources
RxDataSources RxDataSources ͬͯԿʁ
RxDataSources RxSwiftͷͨΊͷUITableViewͱ UICollectionViewͷDataSource
RxDataSources Կ͕خ͍͠ͷʁ
RxDataSources UITableView, UICollectionViewͷ delete, insert, move͕ ؆୯ʹ࣮Ͱ͖Δ !
RxDataSources delete, insert, moveͷͨΊͷߋ৽ͷࠩΛந ग़͢ΔΞϧΰϦζϜਖ਼֬ʹΖ͏ͱ͢Δͱ ͚ͬ͜͏͍͠…
RxDataSources ࠩநग़ΞϧΰϦζϜ
RxDataSources ɾWagner-Fischer ɾHeckel ɾMyers ɾWu …
RxDataSources ࠩநग़ΞϧΰϦζϜͷϥΠϒϥϦ
RxDataSources ɾosteslag/Changeset … Wagner-Fischer ɾjflinter/Dwifft … Myers ɾwokalski/Diff.swift … Myers
ɾonyarnold/Differ … Myers(Diff.swiftͷfork) ɾonmyway133/DeepDiff … HeckelΆ͍ ɾInstagram/IGListKit … Heckel ɾRxSwiftCommunity/RxDataSources … Heckelվ ɾkazuhiro4949/EditDistance … Wu
RxDataSources IGListKit … SectionΛදݱͨ͠ଟ࣍ݩ ྻͷࠩʹରԠ͍ͯ͠ͳ͍ RxDataSources … ϢχʔΫIDΛ࣋ͪɺ ྻʹॏෳ͕ͳ͍લఏͰSectionͷࠩߋ৽
RxDataSources ↓ ͜ΕΘ͔Γ͍͢ https://github.com/horita-yuya/ DifferenceAlgorithmComparison
RxDataSources ࣮
RxDataSources
RxDataSources SectionModelͷprotocol
public protocol SectionModelType { associatedtype Item public var items: [Self.Item]
{ get } public init(original: Self, items: [Self.Item]) } RxDataSources
public protocol IdentifiableType { associatedtype Identity : Hashable public var
identity: Self.Identity { get } } RxDataSources
public protocol AnimatableSectionModelType : SectionModelType, IdentifiableType where Self.Item : IdentifiableType,
Self.Item : Equatable { } RxDataSources
RxDataSources SectionModel
enum DownloadSeriesSectionModel: AnimatableSectionModelType { typealias Item = DownloadSeriesSectionItem case episodeList(season:
DownloadSeason?, items: [Item]) case other(items: [Item]) // Mark: - IdentifiableType var identity: String { … } // Mark: - SectionModelType var items: [DownloadSeriesSectionItem] { switch self { case .episodeList(_, let items): return items case .other(let items): return items } } init(original: DownloadSeriesSectionModel, items: [Item]) { switch original { case .episodeList(let season, _): self = .episodeList(season: season, items: items) case .other: self = .other(items: items) } } } RxDataSources
RxDataSources SectionItemModel
enum DownloadSeriesSectionItem: IdentifiableType, Equatable { case episode(downloadMedia: DownloadMedia) case seeOtherEpisode(series:
DownloadSeries) // Mark: - IdentifiableType var identity: String { … } // Mark: - Equatable static func == (lhs: DownloadSeriesSectionItem, rhs: DownloadSeriesSectionItem) -> Bool { … } } RxDataSources
RxDataSources AnimatableSectionModel
public struct AnimatableSectionModel<Section: IdentifiableType, ItemType: IdentifiableType & Equatable> { public
var model: Section public var items: [Item] public init(model: Section, items: [ItemType]) { self.model = model self.items = items } } extension AnimatableSectionModel : AnimatableSectionModelType { public typealias Item = ItemType public typealias Identity = Section.Identity public var identity: Section.Identity { return model.identity } public init(original: AnimatableSectionModel, items: [Item]) { self.model = original.model self.items = items } public var hashValue: Int { return self.model.identity.hashValue } } RxDataSources Α͘ݟͨΒ3Y%BUB4PVSDFT ʹ"OJNBUBCMF4FDUJPO.PEFM͕ ༻ҙ͞Ε͍ͯΔͷͰ͜ΕΛ͏ ͷ͕CFUUFS
RxDataSources RxTableViewSectionedAnimatedDataSource
open class RxTableViewSectionedAnimatedDataSource<S: AnimatableSectionModelType> : TableViewSectionedDataSource<S> , RxTableViewDataSourceType { …
public init( animationConfiguration: AnimationConfiguration = AnimationConfiguration(), decideViewTransition: @escaping DecideViewTransition = { _, _, _ in .animated }, configureCell: @escaping ConfigureCell, titleForHeaderInSection: @escaping TitleForHeaderInSection = { _, _ in nil }, titleForFooterInSection: @escaping TitleForFooterInSection = { _, _ in nil }, canEditRowAtIndexPath: @escaping CanEditRowAtIndexPath = { _, _ in false }, canMoveRowAtIndexPath: @escaping CanMoveRowAtIndexPath = { _, _ in false }, sectionIndexTitles: @escaping SectionIndexTitles = { _ in nil }, sectionForSectionIndexTitle: @escaping SectionForSectionIndexTitle = { _, _, index in index } ) { self.animationConfiguration = animationConfiguration self.decideViewTransition = decideViewTransition super.init( configureCell: configureCell, titleForHeaderInSection: titleForHeaderInSection, titleForFooterInSection: titleForFooterInSection, canEditRowAtIndexPath: canEditRowAtIndexPath, canMoveRowAtIndexPath: canMoveRowAtIndexPath, sectionIndexTitles: sectionIndexTitles, sectionForSectionIndexTitle: sectionForSectionIndexTitle ) } … } RxDataSources
final class DownloadSeriesDelegate: NSObject, UITableViewDelegate { … lazy var dataSource:
RxTableViewSectionedAnimatedDataSource<DownloadSeriesSectionModel> = .init( animationConfiguration: AnimationConfiguration(insertAnimation: .fade, reloadAnimation: .none, deleteAnimation: .fade), configureCell: { [weak self] dataSource, table, indexPath, item in guard let me = self else { return UITableViewCell() // Should never reach here. } switch item { case .episode(let downloadMedia): let cell = table.dequeueReusableCell(DownloadListMediaCell.self, forIndexPath: indexPath) cell.configure(downloadMedia: downloadMedia) … return cell case .seeOtherEpisode(let series): let cell = table.dequeueReusableCell(DownloadSeeOtherEpisodeCell.self, forIndexPath: indexPath) cell.rx.tapGesture .subscribe(onNext: { [weak self] in … }) .disposed(by: cell.reusableDisposeBag) … return cell } }) … RxDataSources
final class DownloadSeriesViewStream { … let sectionModels: Property<[DownloadSeriesSectionModel]> private let
_sectionModels = Variable<[DownloadSeriesSectionModel]>([]) … } RxDataSources
final class DownloadSeriesViewController: UIViewController { … viewStream.sectionModels.asObservable() // IMPORTANT: //
crashճආɺཁௐࠪ. .throttle(1.0, latest: true, scheduler: ConcurrentMainScheduler.instance) .bind(to: tableView.rx.items(dataSource: delegate.dataSource)) .disposed(by: rx.disposeBag) … RxDataSources
RxDataSources UITableViewDelegateʁ
// MARK: - UITableViewDelegate func tableView(_ tableView: UITableView, heightForRowAt indexPath:
IndexPath) -> CGFloat { … } func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { … } func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { … } func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { … } … RxDataSources
Conclusion
Conclusion • ࠩநग़ΞϧΰϦζϜͷϥΠϒϥϦݕ౼͠Α͏ • DiffΞϧΰϦζϜࣗલͰ࡞Ζ͏ͱ͢Δͱ͚ͬ͜͏େม • RxSwift͍ͬͯΔͳΒRxDataSourcesͰྑͦ͞͏
Thank you