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
95k
Rubik's Cubes and Genetic Algorithms In Swift
javisoto
1
970
NSSpain 2016: Building Fabric.app in Swift
javisoto
4
860
Swift User Group - April 2016: Building Fabric.app in Swift
javisoto
4
26k
Swift Summit San Francisco October 2015
javisoto
4
1.4k
iOS Conf Singapore October 2015
javisoto
0
670
NSMeetup San Francisco July 2015
javisoto
3
820
RAC3, A Real World Use Case (aka ReactiveChess)
javisoto
0
570
Back to the Futures
javisoto
4
14k
Other Decks in Programming
See All in Programming
PSR-15 はあなたのための ものではない? - phpcon2024
myamagishi
0
400
Оптимизируем производительность блока Казначейство
lamodatech
0
950
生成AIでGitHubソースコード取得して仕様書を作成
shukob
0
630
2025.01.17_Sansan × DMM.swift
riofujimon
2
560
ASP.NET Core の OpenAPIサポート
h455h1
0
120
asdf-ecspresso作って 友達が増えた話 / Fujiwara Tech Conference 2025
koluku
0
1.4k
技術的負債と向き合うカイゼン活動を1年続けて分かった "持続可能" なプロダクト開発
yuichiro_serita
0
300
GitHub CopilotでTypeScriptの コード生成するワザップ
starfish719
26
6k
선언형 UI에서의 상태관리
l2hyunwoo
0
270
React 19でお手軽にCSS-in-JSを自作する
yukukotani
5
560
Swiftコンパイラ超入門+async関数の仕組み
shiz
0
170
Flatt Security XSS Challenge 解答・解説
flatt_security
0
730
Featured
See All Featured
BBQ
matthewcrist
85
9.4k
Navigating Team Friction
lara
183
15k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.5k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.2k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Mobile First: as difficult as doing things right
swwweet
222
9k
A Tale of Four Properties
chriscoyier
157
23k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
44
9.4k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
3
240
It's Worth the Effort
3n
183
28k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
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