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
660
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
WEBエンジニア向けAI活用入門
sutetotanuki
0
300
Dev ContainersとGitHub Codespacesの素敵な関係
ymd65536
1
120
破壊せよ!データ破壊駆動で考えるドメインモデリング / data-destroy-driven
minodriven
15
3.9k
Progressive Web Apps für Desktop und Mobile mit Angular (Hands-on)
christianliebel
PRO
0
110
PagerDuty を軸にした On-Call 構築と運用課題の解決 / PagerDuty Japan Community Meetup 4
horimislime
1
110
讓數據說話:用 Python、Prometheus 和 Grafana 講故事
eddie
0
340
Tuning GraphQL on Rails
pyama86
2
1k
PHP でアセンブリ言語のように書く技術
memory1994
PRO
1
150
The future of development – Are our jobs getting harder or easier?
hollycummins
1
250
Jakarta Concurrencyによる並行処理プログラミングの始め方 (JJUG CCC 2024 Fall)
tnagao7
1
230
Synchronizationを支える技術
s_shimotori
1
150
Vue3の一歩踏み込んだパフォーマンスチューニング2024
hal_spidernight
3
3.1k
Featured
See All Featured
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
27
790
Making Projects Easy
brettharned
115
5.9k
Designing on Purpose - Digital PM Summit 2013
jponch
115
6.9k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
328
21k
Speed Design
sergeychernyshev
24
570
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
43
6.6k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
27
4.1k
Keith and Marios Guide to Fast Websites
keithpitt
408
22k
Building Flexible Design Systems
yeseniaperezcruz
327
38k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
Intergalactic Javascript Robots from Outer Space
tanoku
268
27k
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