27
Pavlo Zakharov Reactive Cocoa: Paradigm shift. - What is Reactive functional Paradigm? - Why consider using ReactiveCocoa? - RAC Signal.Unifying all of Cocoa’s common patterns. - RAC and concurrency. - Implementing MVVM design pattern on iOS with RAC.

Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Embed Size (px)

Citation preview

Page 1: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Pavlo Zakharov

Reactive Cocoa: Paradigm shift.

- What is Reactive functional Paradigm?- Why consider using ReactiveCocoa?- RAC Signal.Unifying all of Cocoa’s common patterns.- RAC and concurrency.- Implementing MVVM design pattern on iOS with RAC.

Page 2: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

What is Reactive Functional Programming?

Page 3: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Functional reactive programming (FRP) is a programming paradigm for reactive programming (asynchronous dataflow programming) using

the building blocks of functional programming (e.g. map, reduce, filter). FRP has been used for programming graphical user interfaces (GUIs), robotics, and music, aiming to simplify these problems by explicitly

modelling time. (c) Wikipedia

Page 4: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Reactive+Functional:

❖ Static/Dynamic data flow.(Programming based on Events)

❖ (Functional Blocks) Functions passed as arguments to functions.

Page 5: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Cocoa Events

❖ Delegation❖ KVO❖ Target - Action❖ Callback Blocks❖ NSNotifications}RacSignal

Page 6: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

RACSignal

❖ Next❖ Error❖ Completed

Ray Signal emits:

[self.searchText.rac_textSignal subscribeNext:^(id x) { NSLog(@"Next ocured"); }error:^(NSError *error) { NSLog(@"Error ocured"); }completed:^{ NSLog(@"Completed"); }];

Signal can have one or multiple subscribers

Page 7: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

EventsEvent flow:

CompletedCompleted

NextNext

NextNext

NextNext ErrorError

NextNext NextNext …

Page 8: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Reactive Operations

❖ Map❖ Throttle❖ Skip❖ Filter❖ DeliverOn❖ more…

Page 9: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Operations don’t care about signal source.

Page 10: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Map

❖ Transforms the value of the event(As transformed value as input signal can be literally anything)

RACSignal *mySignal = [textSignal map:^id(NSString *text) { return @(text.length>3); }];[mySignal subscribeNext:^(NSNumber* x) { if ([x boolValue]) { //... } }];

Page 11: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Combine

❖ Combines two RAC Events(Next Emits when one of combined events occurs).

RACSignal *switch1Signal = … RACSignal *switch2Signal = …

RACSignal *both = [RACSignal combineLatest:@[switch1Signal,switch2Signal] reduce:^id(NSNumber *switch1, NSNumber *switch2){ return @([switch1 boolValue] && [switch2 boolValue]); }]; [both subscribeNext:^(id x) { if([x boolValue]){ NSLog(@"Both"); } }];

Page 12: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Filter

❖ Event will be emitted only if the condition is satisfied.

[[self.usernameTextField.rac_textSignal filter:^BOOL(id value) { return (((NSString*)value).length>3); }]subscribeNext:^(id x) { NSLog(@"do stuff"); }];

Page 13: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Throttle

❖ If event occurrence once more within time interval specified event wouldn’t be emitted.(Extremely useful for locking buttons to prevent speed clicking)

[[[self.usernameTextField.rac_textSignal filter:^BOOL(id value) { return (((NSString*)value).length>3); }]throttle:0.5]subscribeNext:^(id x) { NSLog(@"do stuff"); }];

Page 14: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Deliver On

❖ The block will be executed on thread specified (For example for UI stuff on main thread)

[[[self.usernameTextField.rac_textSignal filter:^BOOL(id value) { return (((NSString*)value).length>3); }] deliverOn:[RACScheduler mainThreadScheduler]]subscribeNext:^(id x) { NSLog(@"do UI stuff"); }];

Page 15: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

How to mix reactive code with non-reactive?

Page 16: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Option one: doNext block

❖ doNext Block will be executed before subscriberBlock will be called.This is the good place for reactive code.

[[[self.signInButton rac_signalForControlEvents:UIControlEventTouchUpInside] doNext:^(id x) { //put your non-reactive code here }] subscribeNext:^(NSNumber *signedIn) { //do stuff }];}

Page 17: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Wrap non-reactive code to reactive

❖ Method will create signal which can emit next/error/completed event based on your non-reactive conditions.

-(RACSignal *)switchSignal{ return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { (self.switch1.isOn)?[subscriber sendNext:@(YES)] : [subscriber sendNext:@(NO)]; return nil; }];} //. //. //. [[self switchSignal]subscribeNext:^(id x) { //doStuff }];

Page 18: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Bind Signal to UIEvent

❖ Every time touchUpInside event occurs next event will be emitted;

RACSignal *mySignal = [self.getButton rac_signalForControlEvents:UIControlEventTouchUpInside]

Page 19: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Avoid Retain cycles

❖ Accessing self in block can cause retain cycle and memory leak.Use __weak self to prevent it.

@weakify(self); [self.searchText.rac_textSignal subscribeNext:^(id x) { @strongify(self); // self.smth = smth }error:^(NSError *error) { @strongify(self); // self.smthElse = smth }completed:^{ @strongify(self); // self.smthReallyDifferent = smth }];

Page 20: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

ModelViewViewModel

Page 21: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

ViewModel

❖ ViewModel which is a special type of model that represents the UI state of the application

ViewView ViewModeViewModell ModelModel

ViewView ViewModeViewModell ModelModel

ControllControllerer

Page 22: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Binding

❖ Binds textField.text to the property in ViewModel. Every time property changes text will change as well. (WPF implementation is shown on the right)

RAC(self.searchText,text) = self.myString;

 <TextBlock TextContent=”{Binding Path=Description}” />~

Page 23: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Why should i use RAC?

❖ Unified interface for all Cocoa events.❖ Less code in comparison with non-reactive code.❖ No massive ViewControllers with complicated

relationships.❖ Easy work with concurrency.❖ No complicated “States” needed.

Page 24: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Some Disadvantages❖ Debug Hell.❖ Little overhead❖ Weird syntax.(But you will get used to it)

Page 25: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Resources

❖ https://github.com/ReactiveCocoa/ReactiveCocoa

❖ http://www.raywenderlich.com❖ http://blog.scottlogic.com/2014/07/24/mvvm-rea

ctivecocoa-swift.html❖ https://www.youtube.com/watch?v=DgdISd1Qc4

8❖ https://www.youtube.com/watch?v=fWV7xyN5C

R8❖ https://github.com/ZakharovPaul/RacDemo.git

Page 26: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Questions?

Page 27: Lviv MD Day 2015 Павло Захаров "Reactive cocoa: paradigm shift"

Thank you Skype: c1ark.E-mail: [email protected]