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
90k
Rubik's Cubes and Genetic Algorithms In Swift
javisoto
1
850
NSSpain 2016: Building Fabric.app in Swift
javisoto
4
790
Swift User Group - April 2016: Building Fabric.app in Swift
javisoto
4
25k
Swift Summit San Francisco October 2015
javisoto
4
1.3k
iOS Conf Singapore October 2015
javisoto
0
610
NSMeetup San Francisco July 2015
javisoto
3
760
RAC3, A Real World Use Case (aka ReactiveChess)
javisoto
0
530
Back to the Futures
javisoto
4
14k
Other Decks in Programming
See All in Programming
Blue/Greenデプロイの導入による 運用フローの改善
kudoas
1
370
CA.swift19 恋するAIアプリ開発の裏側
oskmr
0
360
大規模Reactアプリのリアーキテクチャ~8万行のTanStack Query移行の軌跡~
kj455
4
950
Java 22 Overview
kishida
1
180
Tailwind CSSを本気でカスタマイズする方法
fsubal
13
5.2k
Elm Form Validation
bkuhlmann
0
510
try! Swift Tokyo 2024のLT枠に採択されたプロポーザルを出すときに考えていたこと
ski
0
350
⼤規模⾔語モデルの拡張(RAG)が 終わったかも知れない件について
nearme_tech
23
15k
Changed Rules: Architectures with Lightweight Stores
manfredsteyer
PRO
0
240
Ruby Function Composition
bkuhlmann
1
330
MetricKitで予期せぬ終了を検知する話 / Detect unexpected termination with MetricKit
nekowen
1
180
FigmaとPHPで作る1ミリたりとも表示崩れしない最強の帳票印刷ソリューション
ttskch
43
19k
Featured
See All Featured
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
501
140k
From Idea to $5000 a Month in 5 Months
shpigford
377
45k
5 minutes of I Can Smell Your CMS
philhawksworth
199
19k
Building Better People: How to give real-time feedback that sticks.
wjessup
355
18k
The Language of Interfaces
destraynor
151
23k
Atom: Resistance is Futile
akmur
259
25k
Art, The Web, and Tiny UX
lynnandtonic
289
19k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
120
39k
Bootstrapping a Software Product
garrettdimon
PRO
302
110k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
78
42k
What's new in Ruby 2.0
geeforr
337
31k
Into the Great Unknown - MozCon
thekraken
10
990
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