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
ReactiveCocoa
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Robert Böhnke
May 02, 2013
Programming
19
2.8k
ReactiveCocoa
My talk for UIKonf 2013 about ReactiveCocoa and how to get rid of state
Robert Böhnke
May 02, 2013
Tweet
Share
More Decks by Robert Böhnke
See All by Robert Böhnke
Brooklyn iOS Developer Meetup February 2014
robb
8
3.2k
Cocoa Kucha Berlin 2013
robb
2
2.1k
ReactiveCocoa NSSpain
robb
18
2.5k
Underscore.m + Asterism
robb
4
1.3k
Super Mario Masterclass
robb
2
350
Tetris Masterclass
robb
0
540
Other Decks in Programming
See All in Programming
Rで始めるML・LLM活用入門
wakamatsu_takumu
0
150
株式会社 Sun terras カンパニーデック
sunterras
0
2k
CopilotKit + AG-UIを学ぶ
nearme_tech
PRO
1
120
ベクトル検索のフィルタを用いた機械学習モデルとの統合 / python-meetup-fukuoka-06-vector-attr
monochromegane
2
280
朝日新聞のデジタル版を支えるGoバックエンド ー価値ある情報をいち早く確実にお届けするために
junkiishida
1
350
日本だけで解禁されているアプリ起動の方法
ryunakayama
0
370
並行開発のためのコードレビュー
miyukiw
2
2.2k
atmaCup #23でAIコーディングを活用した話
ml_bear
4
730
DevinとClaude Code、SREの現場で使い倒してみた件
karia
1
890
受け入れテスト駆動開発(ATDD)×AI駆動開発 AI時代のATDDの取り組み方を考える
kztakasaki
2
520
nilとは何か 〜interfaceの構造とnil!=nilから理解する〜
kuro_kurorrr
3
1.6k
Claude Code、ちょっとした工夫で開発体験が変わる
tigertora7571
0
190
Featured
See All Featured
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
63
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
280
Art, The Web, and Tiny UX
lynnandtonic
304
21k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
231
22k
Designing Powerful Visuals for Engaging Learning
tmiket
0
260
Chasing Engaging Ingredients in Design
codingconduct
0
130
Crafting Experiences
bethany
1
75
Making Projects Easy
brettharned
120
6.6k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
180
The Curse of the Amulet
leimatthew05
1
9.5k
Mind Mapping
helmedeiros
PRO
1
110
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.4k
Transcript
ReactiveCocoa OR: How I stopped worrying about state and love
FRP
✉ robb
[email protected]
tmp ceterum_censeo
Let’s talk about State
evil √
Have you tried turning it off and on again?
Have you tried turning it off and on again? Have
you tried turning it off and on again?
state
@property (readwrite, …) BOOL quacksLikeADuck; @property (readwrite, …) BOOL walksLikeADuck;
@property (readonly, …) BOOL probablyADuck;
+ (NSSet *)keyPathsForValuesAffectingProbablyADuck { return [NSSet setWithObjects:@”walksLikeADuck”, @”quacksLikeADuck”, nil]; }
- (BOOL)isProbablyADuck { return _quacksLikeADuck && _walksLikeADuck; }
ReactiveCocoa
RAC(self.probablyADuck) = [RACSignal combineLatest:@[ RACAbleWithStart(self.walksLikeADuck), RACAbleWithStart(self.quacksLikeADuck) ] reduce:^(NSNumber *walks, NSNumber
*quacks) { return @(walks.boolValue && quaks.boolValue); }];
None
[self.usernameField addTarget:self action:@selector(textFieldDidUpdate:) forControlEvents:UIControlEventEditingChanged]; [self.emailField addTarget:self action:@selector(textFieldDidUpdate:) forControlEvents:UIControlEventEditingChanged]; - (void)textFieldDidUpdate:(UITextField
*)textField { BOOL validUsername = self.usernameField.text.length > 0; BOOL validEmail = [self.emailField.text uik_isEmail]; self.signupButton.enabled = validEmail && validUsername; }
because programming
[self.usernameField addTarget:self action:@selector(textFieldDidUpdate:) forControlEvents:UIControlEventEditingChanged]; [self.emailField addTarget:self action:@selector(textFieldDidUpdate:) forControlEvents:UIControlEventEditingChanged]; - (void)textFieldDidUpdate:(UITextField
*)textField { BOOL validUsername = self.usernameField.text.length > 0; BOOL validEmail = [self.emailField.text uik_isEmail]; self.signupButton.enabled = validEmail && validUsername; }
RAC(self.signupButton.enabled) = [RACSignal combineLatest:@[ self.usernameField.rac_textSignal, self.emailField.rac_textSignal ] reduce:^(NSString *username, NSString
*email) { BOOL validUsername = username.length > 0; BOOL validEmail = [email uik_isEmail]; return @(validUsername && validEmail); }];
FRP
None
None
ReactiveCocoa
@YES @NO @YES RACSignal
<UIControlEventEditingChanged> RACSignal
{“json_string”: “ohai”} RACSignal
RACSignal - (void)sendNext:(id)value; - (void)sendCompleted; - (void)sendError:(NSError *)error;
so, what?
map, reduce, filter
Let’s talk about Asynchrony
None
Blocks are awesome
void (^cb)(id operation, id result); void (^cb)(id operation, NSError *error);
void (^cb)(id result, NSError *error); void (^cb)(NSError *error, id result);
[client logIn:^{ [client loadMeUser:^(UIKUser *user) { [client loadNewslettersForUser:user success:^(NSArray *result)
NSLog(@"Your newsletters: %@", array); } failure:^(NSError *error) { // … }]; } failure:^(NSError *error) { // … }]; } failure:^(NSError *error) { // … }];
RACSignal
- (RACSignal *)logIn; - (RACSignal *)loadMeUser; - (RACSignal *)loadNewslettersForUser:(…)user;
[[[[client logIn] sequenceNext:^{ return [client loadMeUser]; }] flattenMap:^(UIKUser *user) {
return [client loadNewslettersForUser:user]; }] subscribeNext:^(NSArray *newsletters) { NSLog(@"Your newsletters: %@", newsletters); } error:^(NSError *error) { // … }];
None
- (RACSignal *)validateEmail:(NSString *)email;
RACSignal *validEmail = [[self.emailField.rac_textSignal map:^(NSString *email) { return [[client validateEmail:email]
startWith:@NO]; }] switchToLatest]; RACSignal *validForm = [RACSignal combineLatest:@[ validUsername, validEmail ] reduce:^(NSNumber *a, NSNumber *b) { return @(a.boolValue && b.boolValue); }]; RAC(self.signupButton.enabled) = validForm;
None
where's the catch?
•conceptual overhead •debugging can get tricky (logAll is your friend)
•forces you to think
should I use it?
Probably!
state
None