SlideShare a Scribd company logo
REACTIVECOCOA GOODNESS
PART I OF II
3PHASES OF LEARNING REACTIVECOCOA
1
2
3
WHAT IS REACTIVECOCOA?
AUTHORS (GITHUB FOLKS) SAY:
ReactiveCocoa (RAC) is an Objective-C framework inspired by Functional
Reactive Programming. It provides APIs for composing and transforming
streams of values.
THE IDEA TO CREATE REACTIVECOCOA SEEMS
TO HAVE COME FROM RX (MICROSOFT .NET),
WHICH IS SIMILAR.
RAC ALLOWS US AN EVENT-BASED
PROGRAMMING MODEL WHICH MAKES STATE
TRACKING OBSOLETE - in theory.
ONE THING IS CERTAIN:
IT MAKES STATE EASIER TO MAINTAIN.
SOME PEOPLE THINK RAC IS ALL ABOUT THIS...
// Keeps someObject.property synced with
// otherObject.other.property
// -> one-way binding
RAC(someObject, property) =
RACObserve(otherObject, other.property);
...OR THIS...
// Keeps someObject.property synced with
// otherObject.other.property
// and vice versa -> two-way binding
RACChannelTo(someObject, property) =
RACChannelTo(otherObject, other.property);
... BUT RAC IS SO MUCH MORE!
RAC = SIGNALS + SUBSCRIBERS
A SIGNAL IS A STREAM OF VALUES.
SIGNALS CAN BE TRANSFORMED, COMBINED, ETC.
A SUBSCRIBER SUBSCRIBES TO A SIGNAL.
RAC LETS BLOCKS, OBJECTS, AND PROPERTIES SUBSCRIBE TO SIGNALS.
USING SIGNALS AND SUBSCRIBERS, YOU CAN
MODEL ANY REACTION TO ANY EVENT THAT
HAPPENS IN YOUR APPLICATION.
MOST OF UI-CENTERED CODE
ACTUALLY REACTS TO SOMETHING!
DIVING INTO SIGNALS
MOST TRIVIAL SIGNAL:
RACEmptySignal
// Sends no value. Ever. #yolo
RACSignal *sendNothing =
[RACEmptySignal empty];
MOST TRIVIAL SIGNAL THAT SENDS VALUES:
RACReturnSignal
// All subscribers will immediately receive an
// empty array as 'next' value on subscription.
RACSignal *returnEmptyArrayOnSubscription =
[RACReturnSignal return:@[]];
BRIDGE OOP/FRP WORLD:
RACSubject
- (id)init {
if (self = [super init]) {
self.loadMoreSubject = [RACSubject subject];
}
return self;
}
- (void)loadMore {
[self.loadMoreSubject sendNext:nil];
}
OTHER SIGNALS:
RACSignal (DUH!),
RACReplaySubject,
RACChannelTerminal,
RACErrorSignal,...
UIKIT BATTERIES INCLUDED:
UITextfield.rac_textSignal
NSObject.rac_willDeallocSignal
UITableviewCell.rac_prepareForReuseSignal
UIButton.rac_command
UIRefreshControl.rac_command
...
SIGNAL LIBRARIES ON COCOAPODS
pod search RACExtensions
pod search reactivecocoa
YOU BUILD APP LOGIC BY
TRANSFORMING VALUES SENT
BY SIGNALS
MAP
[usersSignal map:^NSString *(MMUser *user) {
return user.email;
}];
FILTER
[usersSignal filter:^BOOL(MMUser *user) {
return user.isEnabled;
}];
ZIP
// If signalOne and signalTwo have both
// sent a value, signalOne's value is passed on.
[RACSignal zip:@[signalOne, signalTwo]
reduce:^id(RACTuple *t) {
return t.first;
}];
MERGE SIGNALS
// No matter if the user or a notification
// provokes a value send, the value is passed
// on in both cases.
[RACSignal merge:@[userTriggerSignal,
notificationCenterTriggerSignal]]
FLATTEN OR MAP/FLATTEN SIGNALS
// First maps all freshly sent requestParams to a new
// signal that will eventually send a server response.
// Then applies flatten such that we get all those
// server responses directly as values.
RACSignal *currentUsers = [requestParamsSignal
flattenMap:^RACStream *(NSDictionary *requestParams) {
return [MMAPI.sharedInstance
allUsersWithParams:requestParams];
}
];
(YEAH, YOU CAN BUILD
SIGNALS OF SIGNALS OF
SIGNALS.)
CONCAT SIGNALS
// Catches any error in signal, waits 1 second,
// then passes on the error, and then immediately
// retries (= resubscribes). Forever.
[[signal catch:^(NSError *error) {
return [[[RACSignal
empty]
delay:1.0]
concat:[RACSignal error:error]];
}] retry];
SCAN/REDUCE
// Starts off with a mutable array, and adds all
// events that are ever sent by the 'events' signal.
// E.g. for infinite scrolling.
RACSignal *combinedEventsInAllPages = [events
scanWithStart:NSMutableArray.new
reduce:^id(NSMutableArray *running,
NSArray *eventsInPage) {
[running addObject:eventsInPage];
return running;
}];
SKIP VALUES
// RACObserve immediately sends the current
// property value. Skip:1 'swallows' that one.
[[RACObserve(self, someProperty)] skip: 1];
TAKE X VALUES AND STOP
// Only sends the first 3 text values.
// Then the signal is disposed of.
[textField.rac_textSignal take: 3];
DISTINCT UNTIL CHANGED
// Does only send distinct (= first and new) values.
[RACObserve(self, isUserLoggedIn) distinctUntilChanged];
THROTTLE/DELAY/REPEAT...
... THERE IS A TRANSFORM FOR EVERYTHING.
SIGNALS CAN SWITCH THREADS
RAC(self, results) = [[[[RACReturnSignal
return:@[@(M_PI), @(M_E), @(M_SQRT1_2)]]
deliverOn:RACScheduler.scheduler]
// All that follows happens on a background thread
map:^NSNumber *(NSNumber *specialNumber) {
// Do expensive calculations
// NSNumber *result = ...
return result;
}]
// All that follows (RAC assignment) happens
// on the main thread
deliverOn:RACScheduler.mainThreadScheduler];
RACCOMMAND = ONE-OFF SIGNAL WRAPPER
self.registerCommand = [[RACCommand alloc] initWithEnabled:
[self.emailField.rac_textSignal map:^id(NSString *text) {
return @(text.length > 0);
}]
signalBlock:^RACSignal *(NSDictionary *params) {
return [MMAPI.sharedInstance registerWithParams:params];
}];
[self.registerCommand.executionSignals.flatten subscribeNext:^(id result) {
NSLog(@"Successfully registered!");
}];
// ...
[self.registerCommand execute:@{MMAPIRegisterEmail: self.emailField.text,
MMAPIRegisterPassword: self.pwField.text}];
SIGNALS CAN BE HOT OR COLD
A hot signal is a signal that sends values (and
presumably does work) regardless of whether it
has any subscribers.
A cold signal is a signal that defers its work and
the sending of any values until it has a
subscriber.
Hot signals often don't send subscribers all
values of all time, but only values after their
subscription time.
SO WE HAVE SIGNALS.
NOW WE NEED TO SUBSCRIBE.
SUBSCRIBE WITH A BLOCK
// Prints current date & time every second
RACSignal *dates = [RACSignal interval:1.0
onScheduler:RACScheduler.mainThreadScheduler];
[dates subscribeNext:^(NSDate *date) {
NSLog([NSDateFormatter
localizedStringFromDate:[NSDate date]
dateStyle:NSDateFormatterShortStyle
timeStyle:NSDateFormatterFullStyle]);
}];
SUBSCRIBE WITH A PROPERTY (KEYPATH)
// RAC() is a clever macro that abuses
// subscripting to let subscription look
// like a left-hand assignment
RAC(self.proxyObject.awesomeArray) =
[RACReturnSignal return:@[]];
INJECT BLOCK-BASED SIDE-EFFECTS
// doNext: is 'woven' into the signal chain,
// the side-effect becomes part of the signal.
// Dangerous, but sometimes necessary!
parametersOnRefreshOrParameterChanged =
[parametersOnRefreshOrParameterChanged
doNext:^(NSDictionary *parameters) {
@strongify(self)
self.isRefreshing = YES;
}];
SUBSCRIBE WITH A METHOD
// Calls updateAuthorizationWithAuthToken: when
// RACObserve() sends a value. RACObserve()
// will btw immediately send the first value,
// synchronously.
[self rac_liftSelector:
@selector(updateAuthorizationWithAuthToken:)
withSignals: RACObserve(MMSession.sharedSession,
currentCredentials.authToken), nil];
WHAT RAC BUYS YOU
CAN BIND UI COMPONENT VALUES TO MODEL
VALUES, INCLUDING TRANSFORMATIONS ...
... WHICH LEADS TO:
A REAL MVVM PARADIGM
CAN CALL METHODS WITH MULTIPLE
PARAMETERS WHEN SIGNALS FIRE IN A
CERTAIN CONFIGURATION
ELIMINATES THOSE ERROR-PRONE BOOL
FLAGS YOU USE TO KEEP TRACK OF COMPLEX
STATE
CAN WAIT FOR MULTIPLE SIGNALS UNTIL IT
DOES SOMETHING
(TEDIOUS AND DANGEROUS TO DO WITH
BOOL FLAGS)
MAKES THREAD SWITCHES EASY AS !
FORCES YOU TO THINK TWICE BEFORE
INTRODUCING A SIDE-EFFECT.
ENCOURAGES IMMUTABLE OBJECTS
(BUT DOES NOT ENFORCE THEM).
MAKES CODE EVEN MORE REUSABLE
(E.G.NETWORK RESPONSE ERROR FILTER)
NICE INTERFACE TO KVO AND
NSNotificationCenter
HAS NICE COLLECTION UTILS INDEPENDENT
OF SIGNALS
(MIGHT GET REMOVED SOMEDAY):
RACSequence
LIMITATIONS & PITFALLS
BLOCKS CAN EASILY CREATE RETAIN CYCLES
☞ ALWAYS USE @WEAKIFY AND @STRONGIFY
IF YOU OVERDO IT, PERFORMANCE SUFFERS
☞ WATCH BINDINGS IN UITABLEVIEWCELLS!
NO WAY FOR DISTINCTUNTILCHANGED TO
NOT USE ISEQUAL !
NO SPECIAL TREATMENT FOR MUTABLE
ARRAYS
[[[[[[[[CODE BECOMES] HARD] TO]
UNDERSTAND] IF YOU] NEST] SIGNALS]
TOO MUCH]
☞ USE INTERMEDIATE PROPERTIES!
HOW DOES RAC
DO ALL THIS?
BLOCKS, KVO,
METHOD SWIZZLING,
MACROS, GCD, LOCKS,...
(maybe every runtime feature there is)
MEMORY MANAGEMENT just works™.
BUT IT'S EASY TO CREATE SIGNALS THAT
LIVE FOREVER!
RAC'S CODE IS REALLY ADVANCED STUFF,
BUT HAVING A LOOK AT IT IS WORTH IT.
A WORD ABOUT SWIFT:
RAC can be used with Swift (didn't test it yet),
but a pure Swift implementation will take a while.
Also, KVO will not work without NSObject anyway.
Proof of concept is currently being merged into RAC:
https://github.com/jspahrsummers/RxSwift
IF YOU WANT TO LEARN RAC:
1. First have a look at how subscriptions work
2. Read through RAC's Github issues (mostly RAC Q/A)
3. Start slow, create a lot of intermediate properties
4. Go wild!
IF YOU ARE STUCK,
PING ME AT
@MANUELMALY
NO REALLY. DO IT!
THANKS FOR LISTENING!
COMING SOON: PART II INCLUDING
MVVM PATTERN AND MORE CODE
@MANUELMALY
CREATIVEPRAGMATICS.COM

More Related Content

What's hot

Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
Brainhub
 
Reactive cocoa
Reactive cocoaReactive cocoa
Reactive cocoa
iacisclo
 
Angular and The Case for RxJS
Angular and The Case for RxJSAngular and The Case for RxJS
Angular and The Case for RxJS
Sandi Barr
 
Reactive Java (33rd Degree)
Reactive Java (33rd Degree)Reactive Java (33rd Degree)
Reactive Java (33rd Degree)
Tomasz Kowalczewski
 
Rxjs ngvikings
Rxjs ngvikingsRxjs ngvikings
Rxjs ngvikings
Christoffer Noring
 
My Gentle Introduction to RxJS
My Gentle Introduction to RxJSMy Gentle Introduction to RxJS
My Gentle Introduction to RxJS
Mattia Occhiuto
 
RxJava on Android
RxJava on AndroidRxJava on Android
RxJava on Android
Dustin Graham
 
Cocoa heads 09112017
Cocoa heads 09112017Cocoa heads 09112017
Cocoa heads 09112017
Vincent Pradeilles
 
Intro to RxJava/RxAndroid - GDG Munich Android
Intro to RxJava/RxAndroid - GDG Munich AndroidIntro to RxJava/RxAndroid - GDG Munich Android
Intro to RxJava/RxAndroid - GDG Munich Android
Egor Andreevich
 
Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...
Mario Fusco
 
Reactive programming with RxJava
Reactive programming with RxJavaReactive programming with RxJava
Reactive programming with RxJava
Jobaer Chowdhury
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.js
cacois
 
Angular & RXJS: examples and use cases
Angular & RXJS: examples and use casesAngular & RXJS: examples and use cases
Angular & RXJS: examples and use cases
Fabio Biondi
 
Luis Atencio on RxJS
Luis Atencio on RxJSLuis Atencio on RxJS
Luis Atencio on RxJS
Luis Atencio
 
Oop assignment 02
Oop assignment 02Oop assignment 02
Oop assignment 02
MamoonKhan39
 
Rxjs swetugg
Rxjs swetuggRxjs swetugg
Rxjs swetugg
Christoffer Noring
 
GKAC 2015 Apr. - RxAndroid
GKAC 2015 Apr. - RxAndroidGKAC 2015 Apr. - RxAndroid
GKAC 2015 Apr. - RxAndroid
GDG Korea
 
JavaOne 2013: Java 8 - The Good Parts
JavaOne 2013: Java 8 - The Good PartsJavaOne 2013: Java 8 - The Good Parts
JavaOne 2013: Java 8 - The Good Parts
Konrad Malawski
 

What's hot (20)

Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
 
Reactive cocoa
Reactive cocoaReactive cocoa
Reactive cocoa
 
Map kit light
Map kit lightMap kit light
Map kit light
 
Angular and The Case for RxJS
Angular and The Case for RxJSAngular and The Case for RxJS
Angular and The Case for RxJS
 
Rxjs ppt
Rxjs pptRxjs ppt
Rxjs ppt
 
Reactive Java (33rd Degree)
Reactive Java (33rd Degree)Reactive Java (33rd Degree)
Reactive Java (33rd Degree)
 
Rxjs ngvikings
Rxjs ngvikingsRxjs ngvikings
Rxjs ngvikings
 
My Gentle Introduction to RxJS
My Gentle Introduction to RxJSMy Gentle Introduction to RxJS
My Gentle Introduction to RxJS
 
RxJava on Android
RxJava on AndroidRxJava on Android
RxJava on Android
 
Cocoa heads 09112017
Cocoa heads 09112017Cocoa heads 09112017
Cocoa heads 09112017
 
Intro to RxJava/RxAndroid - GDG Munich Android
Intro to RxJava/RxAndroid - GDG Munich AndroidIntro to RxJava/RxAndroid - GDG Munich Android
Intro to RxJava/RxAndroid - GDG Munich Android
 
Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...
 
Reactive programming with RxJava
Reactive programming with RxJavaReactive programming with RxJava
Reactive programming with RxJava
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.js
 
Angular & RXJS: examples and use cases
Angular & RXJS: examples and use casesAngular & RXJS: examples and use cases
Angular & RXJS: examples and use cases
 
Luis Atencio on RxJS
Luis Atencio on RxJSLuis Atencio on RxJS
Luis Atencio on RxJS
 
Oop assignment 02
Oop assignment 02Oop assignment 02
Oop assignment 02
 
Rxjs swetugg
Rxjs swetuggRxjs swetugg
Rxjs swetugg
 
GKAC 2015 Apr. - RxAndroid
GKAC 2015 Apr. - RxAndroidGKAC 2015 Apr. - RxAndroid
GKAC 2015 Apr. - RxAndroid
 
JavaOne 2013: Java 8 - The Good Parts
JavaOne 2013: Java 8 - The Good PartsJavaOne 2013: Java 8 - The Good Parts
JavaOne 2013: Java 8 - The Good Parts
 

Similar to ReactiveCocoa Goodness - Part I of II

Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"
Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"
Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"
Lviv Startup Club
 
Pieter De Baets - An introduction to React Native
Pieter De Baets - An introduction to React NativePieter De Baets - An introduction to React Native
Pieter De Baets - An introduction to React Native
tlv-ios-dev
 
Talk KVO with rac by Philippe Converset
Talk KVO with rac by Philippe ConversetTalk KVO with rac by Philippe Converset
Talk KVO with rac by Philippe Converset
CocoaHeads France
 
Reactive Cocoa
Reactive CocoaReactive Cocoa
Reactive Cocoa
Robert Brown
 
Functional Reactive Programming (CocoaHeads Bratislava)
Functional Reactive Programming (CocoaHeads Bratislava)Functional Reactive Programming (CocoaHeads Bratislava)
Functional Reactive Programming (CocoaHeads Bratislava)
Michal Grman
 
High Performance Microservices with Ratpack and Spring Boot
High Performance Microservices with Ratpack and Spring BootHigh Performance Microservices with Ratpack and Spring Boot
High Performance Microservices with Ratpack and Spring Boot
Daniel Woods
 
Saving lives with rx java
Saving lives with rx javaSaving lives with rx java
Saving lives with rx java
Shahar Barsheshet
 
Sqlapi0.1
Sqlapi0.1Sqlapi0.1
Sqlapi0.1
jitendral
 
«ReactiveCocoa и MVVM» — Николай Касьянов, SoftWear
«ReactiveCocoa и MVVM» — Николай Касьянов, SoftWear«ReactiveCocoa и MVVM» — Николай Касьянов, SoftWear
«ReactiveCocoa и MVVM» — Николай Касьянов, SoftWear
e-Legion
 
Structured concurrency with Kotlin Coroutines
Structured concurrency with Kotlin CoroutinesStructured concurrency with Kotlin Coroutines
Structured concurrency with Kotlin Coroutines
Vadims Savjolovs
 
MCE^3 - Ágnes Vásárhelyi - ReactiveCocoa Reloaded
MCE^3 - Ágnes Vásárhelyi - ReactiveCocoa ReloadedMCE^3 - Ágnes Vásárhelyi - ReactiveCocoa Reloaded
MCE^3 - Ágnes Vásárhelyi - ReactiveCocoa Reloaded
PROIDEA
 
iOS Multithreading
iOS MultithreadingiOS Multithreading
iOS MultithreadingRicha Jain
 
Introduction to Redux (for Angular and React devs)
Introduction to Redux (for Angular and React devs)Introduction to Redux (for Angular and React devs)
Introduction to Redux (for Angular and React devs)
Fabio Biondi
 
Functional Reactive Programming dengan ReactiveCocoa
Functional Reactive Programming dengan ReactiveCocoaFunctional Reactive Programming dengan ReactiveCocoa
Functional Reactive Programming dengan ReactiveCocoa
Didiet Noor
 
Getting Reactive with Cycle.js and xstream
Getting Reactive with Cycle.js and xstreamGetting Reactive with Cycle.js and xstream
Getting Reactive with Cycle.js and xstream
Steve Lee
 
Cassandra 2.1 boot camp, Overview
Cassandra 2.1 boot camp, OverviewCassandra 2.1 boot camp, Overview
Cassandra 2.1 boot camp, Overview
Joshua McKenzie
 
The Ring programming language version 1.8 book - Part 90 of 202
The Ring programming language version 1.8 book - Part 90 of 202The Ring programming language version 1.8 book - Part 90 of 202
The Ring programming language version 1.8 book - Part 90 of 202
Mahmoud Samir Fayed
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJava
Rick Warren
 
Managing State in React Apps with RxJS by James Wright at FrontCon 2019
Managing State in React Apps with RxJS by James Wright at FrontCon 2019Managing State in React Apps with RxJS by James Wright at FrontCon 2019
Managing State in React Apps with RxJS by James Wright at FrontCon 2019
DevClub_lv
 

Similar to ReactiveCocoa Goodness - Part I of II (20)

Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"
Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"
Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"
 
Pieter De Baets - An introduction to React Native
Pieter De Baets - An introduction to React NativePieter De Baets - An introduction to React Native
Pieter De Baets - An introduction to React Native
 
Talk KVO with rac by Philippe Converset
Talk KVO with rac by Philippe ConversetTalk KVO with rac by Philippe Converset
Talk KVO with rac by Philippe Converset
 
Reactive Cocoa
Reactive CocoaReactive Cocoa
Reactive Cocoa
 
Functional Reactive Programming (CocoaHeads Bratislava)
Functional Reactive Programming (CocoaHeads Bratislava)Functional Reactive Programming (CocoaHeads Bratislava)
Functional Reactive Programming (CocoaHeads Bratislava)
 
Reactive cocoa
Reactive cocoaReactive cocoa
Reactive cocoa
 
High Performance Microservices with Ratpack and Spring Boot
High Performance Microservices with Ratpack and Spring BootHigh Performance Microservices with Ratpack and Spring Boot
High Performance Microservices with Ratpack and Spring Boot
 
Saving lives with rx java
Saving lives with rx javaSaving lives with rx java
Saving lives with rx java
 
Sqlapi0.1
Sqlapi0.1Sqlapi0.1
Sqlapi0.1
 
«ReactiveCocoa и MVVM» — Николай Касьянов, SoftWear
«ReactiveCocoa и MVVM» — Николай Касьянов, SoftWear«ReactiveCocoa и MVVM» — Николай Касьянов, SoftWear
«ReactiveCocoa и MVVM» — Николай Касьянов, SoftWear
 
Structured concurrency with Kotlin Coroutines
Structured concurrency with Kotlin CoroutinesStructured concurrency with Kotlin Coroutines
Structured concurrency with Kotlin Coroutines
 
MCE^3 - Ágnes Vásárhelyi - ReactiveCocoa Reloaded
MCE^3 - Ágnes Vásárhelyi - ReactiveCocoa ReloadedMCE^3 - Ágnes Vásárhelyi - ReactiveCocoa Reloaded
MCE^3 - Ágnes Vásárhelyi - ReactiveCocoa Reloaded
 
iOS Multithreading
iOS MultithreadingiOS Multithreading
iOS Multithreading
 
Introduction to Redux (for Angular and React devs)
Introduction to Redux (for Angular and React devs)Introduction to Redux (for Angular and React devs)
Introduction to Redux (for Angular and React devs)
 
Functional Reactive Programming dengan ReactiveCocoa
Functional Reactive Programming dengan ReactiveCocoaFunctional Reactive Programming dengan ReactiveCocoa
Functional Reactive Programming dengan ReactiveCocoa
 
Getting Reactive with Cycle.js and xstream
Getting Reactive with Cycle.js and xstreamGetting Reactive with Cycle.js and xstream
Getting Reactive with Cycle.js and xstream
 
Cassandra 2.1 boot camp, Overview
Cassandra 2.1 boot camp, OverviewCassandra 2.1 boot camp, Overview
Cassandra 2.1 boot camp, Overview
 
The Ring programming language version 1.8 book - Part 90 of 202
The Ring programming language version 1.8 book - Part 90 of 202The Ring programming language version 1.8 book - Part 90 of 202
The Ring programming language version 1.8 book - Part 90 of 202
 
Building Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJavaBuilding Scalable Stateless Applications with RxJava
Building Scalable Stateless Applications with RxJava
 
Managing State in React Apps with RxJS by James Wright at FrontCon 2019
Managing State in React Apps with RxJS by James Wright at FrontCon 2019Managing State in React Apps with RxJS by James Wright at FrontCon 2019
Managing State in React Apps with RxJS by James Wright at FrontCon 2019
 

Recently uploaded

Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
Boni García
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
Hornet Dynamics
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
Roshan Dwivedi
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
Neo4j
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
Google
 
AI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website CreatorAI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website Creator
Google
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Mind IT Systems
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
Shane Coughlan
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
Rakesh Kumar R
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate
 

Recently uploaded (20)

Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
 
AI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website CreatorAI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website Creator
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
 

ReactiveCocoa Goodness - Part I of II

  • 2. 3PHASES OF LEARNING REACTIVECOCOA
  • 3. 1
  • 4.
  • 5. 2
  • 6.
  • 7. 3
  • 8.
  • 10. AUTHORS (GITHUB FOLKS) SAY: ReactiveCocoa (RAC) is an Objective-C framework inspired by Functional Reactive Programming. It provides APIs for composing and transforming streams of values.
  • 11. THE IDEA TO CREATE REACTIVECOCOA SEEMS TO HAVE COME FROM RX (MICROSOFT .NET), WHICH IS SIMILAR.
  • 12. RAC ALLOWS US AN EVENT-BASED PROGRAMMING MODEL WHICH MAKES STATE TRACKING OBSOLETE - in theory.
  • 13. ONE THING IS CERTAIN: IT MAKES STATE EASIER TO MAINTAIN.
  • 14. SOME PEOPLE THINK RAC IS ALL ABOUT THIS... // Keeps someObject.property synced with // otherObject.other.property // -> one-way binding RAC(someObject, property) = RACObserve(otherObject, other.property);
  • 15. ...OR THIS... // Keeps someObject.property synced with // otherObject.other.property // and vice versa -> two-way binding RACChannelTo(someObject, property) = RACChannelTo(otherObject, other.property);
  • 16. ... BUT RAC IS SO MUCH MORE!
  • 17. RAC = SIGNALS + SUBSCRIBERS
  • 18. A SIGNAL IS A STREAM OF VALUES. SIGNALS CAN BE TRANSFORMED, COMBINED, ETC.
  • 19. A SUBSCRIBER SUBSCRIBES TO A SIGNAL. RAC LETS BLOCKS, OBJECTS, AND PROPERTIES SUBSCRIBE TO SIGNALS.
  • 20. USING SIGNALS AND SUBSCRIBERS, YOU CAN MODEL ANY REACTION TO ANY EVENT THAT HAPPENS IN YOUR APPLICATION.
  • 21. MOST OF UI-CENTERED CODE ACTUALLY REACTS TO SOMETHING!
  • 23. MOST TRIVIAL SIGNAL: RACEmptySignal // Sends no value. Ever. #yolo RACSignal *sendNothing = [RACEmptySignal empty];
  • 24. MOST TRIVIAL SIGNAL THAT SENDS VALUES: RACReturnSignal // All subscribers will immediately receive an // empty array as 'next' value on subscription. RACSignal *returnEmptyArrayOnSubscription = [RACReturnSignal return:@[]];
  • 25. BRIDGE OOP/FRP WORLD: RACSubject - (id)init { if (self = [super init]) { self.loadMoreSubject = [RACSubject subject]; } return self; } - (void)loadMore { [self.loadMoreSubject sendNext:nil]; }
  • 28. SIGNAL LIBRARIES ON COCOAPODS pod search RACExtensions pod search reactivecocoa
  • 29. YOU BUILD APP LOGIC BY TRANSFORMING VALUES SENT BY SIGNALS
  • 30. MAP [usersSignal map:^NSString *(MMUser *user) { return user.email; }];
  • 31. FILTER [usersSignal filter:^BOOL(MMUser *user) { return user.isEnabled; }];
  • 32. ZIP // If signalOne and signalTwo have both // sent a value, signalOne's value is passed on. [RACSignal zip:@[signalOne, signalTwo] reduce:^id(RACTuple *t) { return t.first; }];
  • 33. MERGE SIGNALS // No matter if the user or a notification // provokes a value send, the value is passed // on in both cases. [RACSignal merge:@[userTriggerSignal, notificationCenterTriggerSignal]]
  • 34. FLATTEN OR MAP/FLATTEN SIGNALS // First maps all freshly sent requestParams to a new // signal that will eventually send a server response. // Then applies flatten such that we get all those // server responses directly as values. RACSignal *currentUsers = [requestParamsSignal flattenMap:^RACStream *(NSDictionary *requestParams) { return [MMAPI.sharedInstance allUsersWithParams:requestParams]; } ];
  • 35. (YEAH, YOU CAN BUILD SIGNALS OF SIGNALS OF SIGNALS.)
  • 36.
  • 37. CONCAT SIGNALS // Catches any error in signal, waits 1 second, // then passes on the error, and then immediately // retries (= resubscribes). Forever. [[signal catch:^(NSError *error) { return [[[RACSignal empty] delay:1.0] concat:[RACSignal error:error]]; }] retry];
  • 38. SCAN/REDUCE // Starts off with a mutable array, and adds all // events that are ever sent by the 'events' signal. // E.g. for infinite scrolling. RACSignal *combinedEventsInAllPages = [events scanWithStart:NSMutableArray.new reduce:^id(NSMutableArray *running, NSArray *eventsInPage) { [running addObject:eventsInPage]; return running; }];
  • 39. SKIP VALUES // RACObserve immediately sends the current // property value. Skip:1 'swallows' that one. [[RACObserve(self, someProperty)] skip: 1];
  • 40. TAKE X VALUES AND STOP // Only sends the first 3 text values. // Then the signal is disposed of. [textField.rac_textSignal take: 3];
  • 41. DISTINCT UNTIL CHANGED // Does only send distinct (= first and new) values. [RACObserve(self, isUserLoggedIn) distinctUntilChanged];
  • 42. THROTTLE/DELAY/REPEAT... ... THERE IS A TRANSFORM FOR EVERYTHING.
  • 43. SIGNALS CAN SWITCH THREADS RAC(self, results) = [[[[RACReturnSignal return:@[@(M_PI), @(M_E), @(M_SQRT1_2)]] deliverOn:RACScheduler.scheduler] // All that follows happens on a background thread map:^NSNumber *(NSNumber *specialNumber) { // Do expensive calculations // NSNumber *result = ... return result; }] // All that follows (RAC assignment) happens // on the main thread deliverOn:RACScheduler.mainThreadScheduler];
  • 44. RACCOMMAND = ONE-OFF SIGNAL WRAPPER self.registerCommand = [[RACCommand alloc] initWithEnabled: [self.emailField.rac_textSignal map:^id(NSString *text) { return @(text.length > 0); }] signalBlock:^RACSignal *(NSDictionary *params) { return [MMAPI.sharedInstance registerWithParams:params]; }]; [self.registerCommand.executionSignals.flatten subscribeNext:^(id result) { NSLog(@"Successfully registered!"); }]; // ... [self.registerCommand execute:@{MMAPIRegisterEmail: self.emailField.text, MMAPIRegisterPassword: self.pwField.text}];
  • 45. SIGNALS CAN BE HOT OR COLD A hot signal is a signal that sends values (and presumably does work) regardless of whether it has any subscribers. A cold signal is a signal that defers its work and the sending of any values until it has a subscriber. Hot signals often don't send subscribers all values of all time, but only values after their subscription time.
  • 46. SO WE HAVE SIGNALS. NOW WE NEED TO SUBSCRIBE.
  • 47. SUBSCRIBE WITH A BLOCK // Prints current date & time every second RACSignal *dates = [RACSignal interval:1.0 onScheduler:RACScheduler.mainThreadScheduler]; [dates subscribeNext:^(NSDate *date) { NSLog([NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterFullStyle]); }];
  • 48. SUBSCRIBE WITH A PROPERTY (KEYPATH) // RAC() is a clever macro that abuses // subscripting to let subscription look // like a left-hand assignment RAC(self.proxyObject.awesomeArray) = [RACReturnSignal return:@[]];
  • 49. INJECT BLOCK-BASED SIDE-EFFECTS // doNext: is 'woven' into the signal chain, // the side-effect becomes part of the signal. // Dangerous, but sometimes necessary! parametersOnRefreshOrParameterChanged = [parametersOnRefreshOrParameterChanged doNext:^(NSDictionary *parameters) { @strongify(self) self.isRefreshing = YES; }];
  • 50. SUBSCRIBE WITH A METHOD // Calls updateAuthorizationWithAuthToken: when // RACObserve() sends a value. RACObserve() // will btw immediately send the first value, // synchronously. [self rac_liftSelector: @selector(updateAuthorizationWithAuthToken:) withSignals: RACObserve(MMSession.sharedSession, currentCredentials.authToken), nil];
  • 52. CAN BIND UI COMPONENT VALUES TO MODEL VALUES, INCLUDING TRANSFORMATIONS ...
  • 53. ... WHICH LEADS TO: A REAL MVVM PARADIGM
  • 54. CAN CALL METHODS WITH MULTIPLE PARAMETERS WHEN SIGNALS FIRE IN A CERTAIN CONFIGURATION
  • 55. ELIMINATES THOSE ERROR-PRONE BOOL FLAGS YOU USE TO KEEP TRACK OF COMPLEX STATE
  • 56. CAN WAIT FOR MULTIPLE SIGNALS UNTIL IT DOES SOMETHING (TEDIOUS AND DANGEROUS TO DO WITH BOOL FLAGS)
  • 58. FORCES YOU TO THINK TWICE BEFORE INTRODUCING A SIDE-EFFECT.
  • 59. ENCOURAGES IMMUTABLE OBJECTS (BUT DOES NOT ENFORCE THEM).
  • 60. MAKES CODE EVEN MORE REUSABLE (E.G.NETWORK RESPONSE ERROR FILTER)
  • 61. NICE INTERFACE TO KVO AND NSNotificationCenter
  • 62. HAS NICE COLLECTION UTILS INDEPENDENT OF SIGNALS (MIGHT GET REMOVED SOMEDAY): RACSequence
  • 64. BLOCKS CAN EASILY CREATE RETAIN CYCLES ☞ ALWAYS USE @WEAKIFY AND @STRONGIFY
  • 65. IF YOU OVERDO IT, PERFORMANCE SUFFERS ☞ WATCH BINDINGS IN UITABLEVIEWCELLS!
  • 66. NO WAY FOR DISTINCTUNTILCHANGED TO NOT USE ISEQUAL !
  • 67. NO SPECIAL TREATMENT FOR MUTABLE ARRAYS
  • 68. [[[[[[[[CODE BECOMES] HARD] TO] UNDERSTAND] IF YOU] NEST] SIGNALS] TOO MUCH] ☞ USE INTERMEDIATE PROPERTIES!
  • 69. HOW DOES RAC DO ALL THIS?
  • 70. BLOCKS, KVO, METHOD SWIZZLING, MACROS, GCD, LOCKS,... (maybe every runtime feature there is)
  • 71. MEMORY MANAGEMENT just works™. BUT IT'S EASY TO CREATE SIGNALS THAT LIVE FOREVER!
  • 72. RAC'S CODE IS REALLY ADVANCED STUFF, BUT HAVING A LOOK AT IT IS WORTH IT.
  • 73. A WORD ABOUT SWIFT: RAC can be used with Swift (didn't test it yet), but a pure Swift implementation will take a while. Also, KVO will not work without NSObject anyway. Proof of concept is currently being merged into RAC: https://github.com/jspahrsummers/RxSwift
  • 74. IF YOU WANT TO LEARN RAC: 1. First have a look at how subscriptions work 2. Read through RAC's Github issues (mostly RAC Q/A) 3. Start slow, create a lot of intermediate properties 4. Go wild!
  • 75. IF YOU ARE STUCK, PING ME AT @MANUELMALY NO REALLY. DO IT!
  • 76. THANKS FOR LISTENING! COMING SOON: PART II INCLUDING MVVM PATTERN AND MORE CODE