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
Building Fabric.app with ReactiveCocoa
Search
Javier Soto
June 15, 2016
Programming
3
1.1k
Building Fabric.app with ReactiveCocoa
Overview of how the Fabric App was built by taking advantage of some of ReactiveCocoa's features.
Javier Soto
June 15, 2016
Tweet
Share
More Decks by Javier Soto
See All by Javier Soto
try! Swift Tokyo 2018: Optimizing Swift code for separation of concerns and simplicity
javisoto
9
93k
Rubik's Cubes and Genetic Algorithms In Swift
javisoto
1
940
NSSpain 2016: Building Fabric.app in Swift
javisoto
4
840
Swift User Group - April 2016: Building Fabric.app in Swift
javisoto
4
26k
Swift Summit San Francisco October 2015
javisoto
4
1.3k
iOS Conf Singapore October 2015
javisoto
0
650
NSMeetup San Francisco July 2015
javisoto
3
810
RAC3, A Real World Use Case (aka ReactiveChess)
javisoto
0
560
Back to the Futures
javisoto
4
14k
Other Decks in Programming
See All in Programming
sqlcを利用してsqlに型付けを
kamiyam
0
240
型付きで行うVSCode拡張機能開発 / VSCode Meetup #31
mazrean
0
250
Beyond Laravel Octane - Hyperf for Laravel Artisans
albertcht
1
200
色んなオートローダーを覗き見る #phpcon_okinawa
o0h
PRO
5
420
4年間変わらなかった YOUTRUSTのアーキテクチャ
daiki1003
2
660
Unlocking Python's Core Magic
leew
0
130
How to debug Xdebug... or any other weird bug in PHP
dunglas
2
1.4k
2024-10-01 dev2next - Observability for Modern JVM Applications
jonatan_ivanov
0
140
【YAPC::Hakodate 2024】TypeScriptエンジニアが感じたPerlのここが面白い
kimitashoichi
1
420
CSC509 Lecture 05
javiergs
PRO
0
170
App Store Connect APIで 作業時間を増やそう
mot_techtalk
3
120
Serverless renderování Webových komponent
rarous
PRO
0
130
Featured
See All Featured
Designing for humans not robots
tammielis
249
25k
Code Review Best Practice
trishagee
63
17k
Creatively Recalculating Your Daily Design Routine
revolveconf
217
12k
Debugging Ruby Performance
tmm1
73
12k
What the flash - Photography Introduction
edds
67
11k
The Cost Of JavaScript in 2023
addyosmani
43
5.9k
Gamification - CAS2011
davidbonilla
80
5k
Intergalactic Javascript Robots from Outer Space
tanoku
268
27k
KATA
mclloyd
28
13k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
27
1.9k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
504
140k
The Brand Is Dead. Long Live the Brand.
mthomps
53
38k
Transcript
Building Fabric.app with Reac5veCocoa "Building Fabric.app with Reac6veCocoa" - Javier
Soto. RACDC2016 - April 2016 1
Intro @Javi "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016
- April 2016 2
Outline • Intro • History • Contribu.ng to Reac.veCocoa •
Fabric App Architecture • RAC examples from Fabric App "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 3
Intro: What is Fabric.app? "Building Fabric.app with Reac6veCocoa" - Javier
Soto. RACDC2016 - April 2016 4
What is Fabric.app? "Building Fabric.app with Reac6veCocoa" - Javier Soto.
RACDC2016 - April 2016 5
History h"ps:/ /github.com/blog/1107-reac8vecocoa-for-a-be"er-world "Building Fabric.app with Reac6veCocoa" - Javier Soto.
RACDC2016 - April 2016 6
History • Reac&veCocoa 1: May 2012 (Objec&ve-C) • Reac&veCocoa 2:
September 2013 (Objec&ve-C) • Reac&veCocoa 3: September 2015 (Swi@ 1) • Reac&veCocoa 4: January 2016 (Swi@ 2) "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 7
"Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April
2016 8
Contribu)ng to Reac)veCocoa "Building Fabric.app with Reac6veCocoa" - Javier Soto.
RACDC2016 - April 2016 9
Contribu)ng to Reac)veCocoa: Coding • Refactoring • New tests •
Proposing new operators • Compa5bility with new Swi; versions "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 10
Contribu)ng to Reac)veCocoa: Other ways! • Replying to issues •
Wri1ng / improving docs • Helping other users • Evangelizing "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 11
Fabric App Architecture "Building Fabric.app with Reac6veCocoa" - Javier Soto.
RACDC2016 - April 2016 12
Fabric App Architecture • FabricAPI.framework: • Networking • Models •
Fabric App: • View Controllers • View Models "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 13
Examples of Usage of Reac0veCocoa in the Fabric App "Building
Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 14
Examples - Networking final class AuthenticatedFabricAPI { func applications() ->
SignalProducer<[Application], FabricAPIError> { return apiNetworking.requestJSONProducer( URL: APIURL(path: "api/v3/projects"), method: .GET ) .attemptMap(Application.decodeObjectsInJSON) .observeOn(UIScheduler()) } } "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 15
DataLoadState final class MyViewModel { var data: MyEntity? } "Building
Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 16
DataLoadState enum DataLoadState<DataType> { case Loading case Failed case Loaded(DataType)
} "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 17
DataLoadState enum DataLoadState<DataType> { case Loading case Failed case Loaded(DataType)
} extension SignalProducerType { func materializeToLoadState() -> SignalProducer<DataLoadState<Value>, NoError> { let producer = self .map(DataLoadState.Loaded) .startWithValue(DataLoadState.Loading) return producer.ignoreErrors(replacementValue: DataLoadState<Value>.Failed) } } "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 18
extension SignalProducerType where Value: DataLoadState { func ignoreLoadingAndErrorsAfterSuccess() -> SignalProducer<DataLoadState<Value.DataType>,
Error> { var hasSuccededOnce = false return self.filter { value in defer { if value.success { hasSuccededOnce = true } } return !hasSuccededOnce || value.success } } "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 19
Examples - View Models typealias ApplicationLoadState = DataLoadState<[Application]> final class
ApplicationListViewModel { let applications: AnyProperty<ApplicationLoadState> private let applicationsMutableProperty = MutableProperty(ApplicationLoadState.loading()) init(fabricAPI: AuthenticatedFabricAPI) { self.applications = AnyProperty(self.applicationsMutableProperty) self.applicationsMutableProperty <~ fabricAPI.applications().materializeToLoadState() } } "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 20
Examples - Consuming Data From a View Model self.viewModel.applications.producer.startWithNext {
applicationsLoadState in switch applicationsLoadState { case .Loading: label.text = "Loading..." case .Failed: label.text = "Error loading applications!" case .Loaded(let applications): reloadTableView(applications: applications) } } "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 21
Reac%veCocoa Extensions "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016
- April 2016 22
extension SignalProducerType { func startWithValue(value: Value) -> SignalProducer<Value, Error> {
return SignalProducer(value: value).concat(self.producer) } } "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 23
Reac%veCocoa Extensions extension SignalProducerType { func startWithNil() -> SignalProducer<Value?, Error>
{ return self .map(Optional.init) .startWithValue(nil) } "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 24
Reac%veCocoa Extensions extension SignalProducerType { func ignoreErrors( replacementValue replacementValue: Self.Value?
= nil ) -> SignalProducer<Value, NoError> { return self.flatMapError { _ in return replacementValue.map(SignalProducer.init) ?? .empty } } "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 25
Reac%veCocoa Extensions extension SignalProducerType { func failRandomly(withError error: Self.Error) ->
SignalProducer<Value, Error> { return self.attemptMap { value in let shouldFail = arc4random() % 3 == 0 return shouldFail ? Result(error: error) : Result(value: value) } } "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 26
Reac%veCocoa Extensions extension NSProcessInfo { var lowPowerModelEnabledProducer: SignalProducer<Bool, NoError> {
return NSNotificationCenter.defaultCenter() .rac_notifications(NSProcessInfoPowerStateDidChangeNotification, object: nil) .map { _ in return () } .startWithValue(()) .map { [unowned self] _ in return self.lowPowerModeEnabled } .skipRepeats(==) } } "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 27
Reac%veCocoa Extensions let shouldReload = combineLatest( viewIsOnScreen, NSProcessInfo.processInfo().lowPowerModelEnabledProducer.map { !$0
} ).map { $0 && $1 } let reloadPeriodically = shouldReload .flatMap(.Latest) { [unowned self] shouldReload in return shouldReload ? timer(30, onScheduler: scheduler).map { _ in () } : .empty } let request = reloadPeriodically.flatMap(.Latest) { someAPIRequest } "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 28
Reac%veCocoa Extensions extension SignalProducerType { func continueWhenApplicationIsBackgrounded( taskName taskName: String,
timeoutError: Self.Error ) -> SignalProducer<Value, Error> { } "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 29
Reac%veCocoa Extensions extension SignalProducerType { func repeatWith( producer: SignalProducer<(), NoError>,
throttleWithInterval: NSTimeInterval, onScheduler scheduler: DateSchedulerType ) -> SignalProducer<Value, Error> { return SignalProducer(value: ()).concat(producer) .throttle(throttleWithInterval, onScheduler: scheduler) .promoteErrors(Error) .flatMap(.Concat) { _ in return self.producer } } } "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 30
Reac%veCocoa Extensions self.api.request(parameterFoo: bar) .repeatWith( viewWillAppearProducer, throttleWithInterval: 60, onScheduler: QueueScheduler.mainQueueScheduler
) "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 31
Conclusion "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 -
April 2016 32
Ques%ons? "Building Fabric.app with Reac6veCocoa" - Javier Soto. RACDC2016 -
April 2016 33
Thank you! <3 ! See you next year! "Building Fabric.app
with Reac6veCocoa" - Javier Soto. RACDC2016 - April 2016 34