ReactiveCocoa	
@iacisclo
Programación imperativa.
• Describe detalladamente los
pasos a seguir.
• Continuos cambios de
estado.
• El orden de ejecuc...
Programación declarativa
• Tu describes directamente los
resultados.
• El orden de ejecución no
importa.
• Sin apenas cond...
ReactiveCocoa
• Compatible desde iOS 5.0+ y OS X 10.7+.
• Versión actual 2.2.4.
• Combina declarativa y funcional.
• Compa...
¿Como?	
NSString *name = @"Belén";
NSString *surname = @“_Esteban”;
NSString *completeName = [name stringByAppendingString...
[self.textField.rac_textSignal subscribeNext:^(NSString *value) {
self.lblValue.text = value;
}];
// Imperative
!
for (NSString *device in devices)
if ([device isEqualToString:@"iPod"]) {
self.name = device;
}
}
!
// Rea...
Clases
• RACStream
• RACSignal
• RACSubscriber
• RACSubject
• RACCommand
• RACMulticastConnection
• RACSequence
• RACDispo...
RACStream
• El padre de Todos.
• Es un conjunto de valores.
• Las señales contienen RACStreams.
• Los valores se recuperan...
RACCommand
• Crea y se subscribe a una señal, generalmente
iniciada por UI.
self.button.rac_command = [[RACCommand alloc] ...
RACSignal
• Envian 3 tipos de eventos: NEXT, ERROR, COMPLETED.
[signal subscribeNext:^(id x) {
NSLog(@"en la subscripción"...
RACSignal
RACSignal *executing = [racCommand.executing deliverOn:RACScheduler.mainThreadScheduler];
!
RACSignal *fieldText...
RACSignal
!
RACSignal *formValid = [RACSignal
combineLatest:@[
self.firstNameField.rac_textSignal,
self.lastNameField.rac_...
RACSubject
• Señal que se puede controlar.
RACSubject *letters = [RACSubject subject];
[letters subscribeNext:^(NSString *...
rac_liftSelector:withSignals:
!
self.delegate = [RACSubject subject];
!
[self.navigationController rac_liftSelector:@selec...
RACSubscriber
• Todo objeto que espera o es capaz de
subscribirse a una señal
[[self saveImage:[UIImage imageNamed:@"image...
RACSequence
• Colecciones, señales guiadas.
RACSequence *devices = @[@"iPhone",@"iPad",@"iPod"].rac_sequence;
RACSequence ...
RACSequence
• Colecciones, señales guiadas.
RACSignal *devices = @[@"iPhone",@"iPad",@"iPod"].rac_sequence.signal;
RACSign...
do…
RACSignal *sequenced = [[[[devices
doNext:^(NSString *device) {
!
NSLog(@“antes de la subscripción %@“,device);
!
}]do...
RACDisposable
• Baja o limpieza de señales.
RACDisposable *subscription =
[self.textField.rac_textSignal
subscribeNext:^(N...
Delegados
• Podemos sustituir delegados facilmente
self.textView.delegate = self;
[[self rac_signalForSelector:@selector(t...
Eventos de control
• UIControlEvetTouchDown
• UIControlEventTouchDownRepeat
• UIControlEventTouchDragInside
• UIControlEve...
Eventos de control
[[stepper rac_signalForControlEvents:UIControlEventAllTouchEvents]
subscribeNext:^(UIStepper *stepper) ...
RACSheduler
• GCD en RAC.
[[self.textField.rac_textSignal deliverOn:[RACScheduler mainThreadScheduler]]
subscribeNext:^(NS...
RACSheduler
//////
!
[[[self signalForLoadingImage:tweet.profileImageUrl]
deliverOn:[RACScheduler mainThreadScheduler]]
su...
Memoria
__weak ViewController *bself = self;
[[self.searchText.rac_textSignal
map:^id(NSString *text) {
return [self isVal...
Memoria
#import "RACEXTScope.h"
!
!
@weakify(self)
[[self.searchText.rac_textSignal
map:^id(NSString *text) {
return [self...
RACObserve(TARGET, KEYPATH)
@weakify(self)
[RACObserve(self, modelArray) subscribeNext:^(id x) {
@strongify(self)
[self.co...
RAC(TARGET, …)
RAC(self,dateAdded) = [RACObserve(self.model,dateAdded)map:^(NSDate*date){
return [[ViewModel dateFormatter...
return;
Upcoming SlideShare
Loading in …5
×

Reactive cocoa

811 views

Published on

slides about my talk reactiveCocoa

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
811
On SlideShare
0
From Embeds
0
Number of Embeds
23
Actions
Shares
0
Downloads
9
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Reactive cocoa

  1. 1. ReactiveCocoa @iacisclo
  2. 2. Programación imperativa. • Describe detalladamente los pasos a seguir. • Continuos cambios de estado. • El orden de ejecución es vital. • Muchos condicionales.
  3. 3. Programación declarativa • Tu describes directamente los resultados. • El orden de ejecución no importa. • Sin apenas condicionales. • No hay que estar pendiente del estado.
  4. 4. ReactiveCocoa • Compatible desde iOS 5.0+ y OS X 10.7+. • Versión actual 2.2.4. • Combina declarativa y funcional. • Compatible con código no RAC.
  5. 5. ¿Como? NSString *name = @"Belén"; NSString *surname = @“_Esteban”; NSString *completeName = [name stringByAppendingString:surname]; surname = @“_Esteban, háztelo mirar”; NSLog(@"%@",completeName); El resultado sería “Belén_Esteban” pero con programación reactiva sería “Belén_Esteban, háztelo mirar”.
  6. 6. [self.textField.rac_textSignal subscribeNext:^(NSString *value) { self.lblValue.text = value; }];
  7. 7. // Imperative ! for (NSString *device in devices) if ([device isEqualToString:@"iPod"]) { self.name = device; } } ! // Reactive RAC(self, name) = [devices.rac_sequence.signal filter:^BOOL(NSString *device) { return [device isEqualToString:@"iPod"]; }];
  8. 8. Clases • RACStream • RACSignal • RACSubscriber • RACSubject • RACCommand • RACMulticastConnection • RACSequence • RACDisposable • RACSheduler
  9. 9. RACStream • El padre de Todos. • Es un conjunto de valores. • Las señales contienen RACStreams. • Los valores se recuperan de forma secuencial.
  10. 10. RACCommand • Crea y se subscribe a una señal, generalmente iniciada por UI. self.button.rac_command = [[RACCommand alloc] initWithSignalBlock:^(id _) { self.lblValue.text = @"Button tapped"; return [RACSignal empty]; }]; RACCommand *createAccount = [[RACCommand alloc]initWithEnabled:formValid signalBlock:^RACSignal *(id input) { BOOL success = [IACClient logggin]; return [RACSignal return:@(success)]; }]; ! self.createButton.rac_command = createAccount;
  11. 11. RACSignal • Envian 3 tipos de eventos: NEXT, ERROR, COMPLETED. [signal subscribeNext:^(id x) { NSLog(@"en la subscripción"); } error:^(NSError *error) { NSLog(@"ha ocurrido un error."); } completed:^{ NSLog(@"señal completa"); }];
  12. 12. RACSignal RACSignal *executing = [racCommand.executing deliverOn:RACScheduler.mainThreadScheduler]; ! RACSignal *fieldTextColor = [executing map:^(NSNumber *x) { return x.boolValue ? [UIColor lightGrayColor] : [UIColor blackColor]; }]; RACSignal *signal = @[@"iPhone",@"iPad",@"iMac",@"iPod"].rac_sequence.signal; [[signal filter:^BOOL(NSString *value) { return [value isEqualToString:@"iPad"]; }]subscribeNext:^(NSString *filterValue) { self.lblValue.text = filterValue; }];
  13. 13. RACSignal ! RACSignal *formValid = [RACSignal combineLatest:@[ self.firstNameField.rac_textSignal, self.lastNameField.rac_textSignal, self.emailField.rac_textSignal, ] reduce:^(NSString *firstName, NSString *lastName, NSString *email){ return @(firstName.length > 0 && lastName.length > 0 && email.length > 0); }];
  14. 14. RACSubject • Señal que se puede controlar. RACSubject *letters = [RACSubject subject]; [letters subscribeNext:^(NSString *letter) { NSLog(@"%@",letter); } completed:^{ NSLog(@"complete"); }]; [letters sendNext:@"A"]; [letters sendNext:@"B"]; [letters sendCompleted];
  15. 15. rac_liftSelector:withSignals: ! self.delegate = [RACSubject subject]; ! [self.navigationController rac_liftSelector:@selector(pushViewController:animated:) withSignals:self.delegate,[RACSignal return:@YES], nil]; ! ///// ! IACDetailViewController *detailVC = [self.storyboard instantiateViewControllerWithIdentifier:@"IACDetailViewController"]; ! [self.delegate sendNext:detailVC]; !
  16. 16. RACSubscriber • Todo objeto que espera o es capaz de subscribirse a una señal [[self saveImage:[UIImage imageNamed:@"image1"] withName:@"image1"]then:^RACSignal *{ NSLog(@"image guardada correctamente"); return nil; }]; ! ///////// ! -(RACSignal *)saveImage:(UIImage *)image withName:(NSString *)name{ return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:@"savedImage.png"]; NSData *imageData = UIImagePNGRepresentation(image); BOOL error = [imageData writeToFile:savedImagePath atomically:NO]; if (error) { [subscriber sendError:nil]; }else{ [subscriber sendCompleted]; } return nil; }]; }
  17. 17. RACSequence • Colecciones, señales guiadas. RACSequence *devices = @[@"iPhone",@"iPad",@"iPod"].rac_sequence; RACSequence *computers = @[@"iMac",@"Mac Mini",@"Macbook Air",@"Macbook Pro"].rac_sequence; RACSequence *concatenated = [devices concat:computers]; [concatenated.signal subscribeNext:^(id x) { NSLog(@"%@",x); }];
  18. 18. RACSequence • Colecciones, señales guiadas. RACSignal *devices = @[@"iPhone",@"iPad",@"iPod"].rac_sequence.signal; RACSignal *sequenced = [[devices doNext:^(NSString *device) { NSLog(@"trabajamos con el objeto %@", device); }] then:^{ return @[@"iMac",@"Mac Mini",@"Macbook Air",@"Macbook Pro"].rac_sequence.signal; }]; [sequenced subscribeNext:^(NSString *computer) { NSLog(@"%@",computer); }];
  19. 19. do… RACSignal *sequenced = [[[[devices doNext:^(NSString *device) { ! NSLog(@“antes de la subscripción %@“,device); ! }]doError:^(NSError *error) { ! NSLog(@"antes del error: %@", error); ! }]doCompleted:^{ ! NSLog(@"señal antes de ser completada”); ! }]then:^{ ! NSLog(@"señal ya completada”); ! }];
  20. 20. RACDisposable • Baja o limpieza de señales. RACDisposable *subscription = [self.textField.rac_textSignal subscribeNext:^(NSString *text) { self.lblValue.text = text; }]; // en un futuro; [subscription dispose];
  21. 21. Delegados • Podemos sustituir delegados facilmente self.textView.delegate = self; [[self rac_signalForSelector:@selector(textViewDidChange:)fromProtocol: @protocol(UITextViewDelegate)]subscribeNext:^(RACTuple *arguments) { UITextView *textview = arguments.first; }]; UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Alert" message:@"message" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"ok", nil]; [alert show]; [alert.rac_buttonClickedSignal subscribeNext:^(NSNumber *index) { NSLog(@"%@",index); }];
  22. 22. Eventos de control • UIControlEvetTouchDown • UIControlEventTouchDownRepeat • UIControlEventTouchDragInside • UIControlEventTouchDragOutside • UIControlEventTouchDragEnter • UIControlEventTouchDragExit • UIControlEventTouchUpInside • UIControlEventTouchUpOutside • UIControlEventTouchCancel • UIControlEventValueChanged • UIControlEventEditingDidBegin • UIControlEventEditingChanged • UIControlEventEditingDidEnd • UIControlEventEditingDidEndOnExit • UIControlEventAllTouchEvents • UIControlEventAllEditingEvents • UIControlEventApplicationReserved • UIControlEventSystemReserved
  23. 23. Eventos de control [[stepper rac_signalForControlEvents:UIControlEventAllTouchEvents] subscribeNext:^(UIStepper *stepper) { self.lblValue.text = [NSString stringWithFormat:@"%f",stepper.value]; }]; RAC(self.textField, textColor) = [[self.textField rac_signalForControlEvents: UIControlEventAllEvents]map:^id(UITextField *textfield) { if (textfield.text.length >3) { return [UIColor blackColor]; }else{ return [UIColor redColor]; } }];
  24. 24. RACSheduler • GCD en RAC. [[self.textField.rac_textSignal deliverOn:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSString *value) { self.lblValue.text = value; }]; RACScheduler *scheduler = [RACScheduler schedulerWithPriority:RACSchedulerPriorityBackground]; [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { return nil; }]subscribeOn:scheduler];
  25. 25. RACSheduler ////// ! [[[self signalForLoadingImage:tweet.profileImageUrl] deliverOn:[RACScheduler mainThreadScheduler]] subscribeNext:^(UIImage *image) { cell.twitterAvatarView.image = image; }]; ! /////// ! -(RACSignal *)signalForLoadingImage:(NSString *)imageUrl { RACScheduler *scheduler = [RACScheduler schedulerWithPriority:RACSchedulerPriorityBackground]; return [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]]; UIImage *image = [UIImage imageWithData:data]; [subscriber sendNext:image]; [subscriber sendCompleted]; return nil; }]subscribeOn:scheduler]; }
  26. 26. Memoria __weak ViewController *bself = self; [[self.searchText.rac_textSignal map:^id(NSString *text) { return [self isValidSearchText:text] ? [UIColor whiteColor] : [UIColor yellowColor]; }] subscribeNext:^(UIColor *color) { bself.searchText.backgroundColor = color; }];
  27. 27. Memoria #import "RACEXTScope.h" ! ! @weakify(self) [[self.searchText.rac_textSignal map:^id(NSString *text) { return [self isValidSearchText:text] ? [UIColor whiteColor] : [UIColor yellowColor]; }] subscribeNext:^(UIColor *color) { @strongify(self) self.searchText.backgroundColor = color; }];
  28. 28. RACObserve(TARGET, KEYPATH) @weakify(self) [RACObserve(self, modelArray) subscribeNext:^(id x) { @strongify(self) [self.collectionView reloadData]; }]; [[[RACObserve(photoModel, imageData)filter:^BOOL(id value) { return value != nil; }]map:^id(id value) { return [UIImage imageWithData:value]; }]setKeyPath:@keypath(self.imageView, image) onObject:self.imageView];
  29. 29. RAC(TARGET, …) RAC(self,dateAdded) = [RACObserve(self.model,dateAdded)map:^(NSDate*date){ return [[ViewModel dateFormatter] stringFromDate:date]; }]; ! RAC(self, name) = self.textField.rac_textSignal;
  30. 30. return;

×