SlideShare une entreprise Scribd logo
1  sur  25
Télécharger pour lire hors ligne
Les Promesses
Une introduction aux Promesses en Objective-C
Un design pattern
Blocks
Blocks
Callback hell :(
Les Promesses : origine
•

« The Impact of Applicative Programming on
Multiprocessing »

Daniel P. Friedman and David Wise, 1976

•

Parfois appelées Futures, Deferred ou Tasks
Encore un truc ésotérique ?
LISP
Haskell
Erlang
Pas trop, non.

C#
Une Promesse

•

Un objet qui représente une valeur à venir

•

Des callbacks pour réagir aux changements
Déclaration
@interface Promise : NSObject {
id _value;
id (^)(id value) _onFulfilled;
id (^)(id reason) _onRejected;
}
!
!
!
!
!

@end
Déclaration
@interface Promise : NSObject {
id _value;
id (^)(id value) _onFulfilled;
id (^)(id reason) _onRejected;
}
!
! (Promise*)thenOnFulfilled:(^…)onFulFilled
!
onRejected:(^…)onRejected
! (void)resolve(id value);
!

@end
Utilisation
[[self retrieveDataAsync]
thenOnFulfilled:(id(^)(id value) {
// do something with value
}
onRejected:(id(^)(id reason) {
// present the error
}];
Quel intérêt ?

•

Réifier les callbacks

•

Standardiser les callbacks

les rendre
manipulables
Trois intérêts pratiques
1. Simplifier les signatures des méthodes
2. Chaîner les callbacks
3. Tester le code asynchrone
Exemple

•

navitia.io

•

Récupérer une liste de lieux en JSON
1. Simplifier les signatures
Sans Promesses :
@interface NavitiaClient : NSObject
!

- (void) placesForQuery:(NSString*)query
completion:(void (^)(id jsonObject,
NSError *error))
completionBlock;
!

@end
1. Simplifier les signatures
Avec Promesses :

@interface NavitiaClient : NSObject
!

- (Promise*) placesForQuery:(NSString*)query;
!

@end
2. Chaîner les callbacks
Sans Promesses :
// ViewController.m

!

[_navitiaClient placesForQuery:text
completion:^(NSArray *places, NSError *error)
{
if (!error) {
[_navitiaClient coordinatesForPlaces:places
completion:^(NSArray *coordinates,
NSError *error2)
{
if (!error2) {
// display places coordinates
} else {
// handle error2
}
}
} else {
// handle error
}
}];
2. Chaîner les callbacks
Avec Promesses :
// ViewController.m
!
[[[_navitiaClient placesForQuery:text]
!
thenOnFulfilled:(id(^)(NSArray *places) {
return [_navitiaClient coordinatesForPlaces:places];
}]
!
thenOnFulfilled:(id(^)(NSArray *coordinates) {
// display places coordinates
}
!
onRejected:(id(^)(NSError *error) {
// handle error
}];
3.Tester le code asynchrone
Sans Promesses :
// ViewControllerTests.m
!
[[[navitiaClientMock stub]
andDo:^(NSInvocation *inv) {
id (^completion)(NSArray *, NSError *);
[inv getArgument:&completion atIndex:3];
completion(placesFixture, nil);
}]
placesForQuery:@"foo" completion:OCMARG_ANY];
!
[viewController updatePlacesWithQuery:@"foo"];
!
STAssertEqualObjects(viewController.places,
placesFixture,
nil);
3.Tester le code asynchrone
Avec Promesses :
// ViewControllerTests.m
!
[[[navitiaClientMock stub]
andResolvePromiseWithValue:placesFixture]
placesForQuery:@"foo"];
!
[viewController updatePlacesWithQuery:@"foo"];
!
STAssertEqualObjects(viewController.places,
placesFixture,
nil);
Démo
github.com/kemenaran/Rebelle
Références
Introduction aux Promesses (en Javascript)!
•

http://blog.parse.com/2013/01/29/whats-so-great-about-javascriptpromises/

•

http://fr.slideshare.net/domenicdenicola/callbacks-promises-andcoroutines-oh-my-the-evolution-of-asynchronicity-in-javascript

Implémentations!
•

https://github.com/kemenaran/Rebelle

•

https://github.com/mproberts/objc-promise

•

https://github.com/ReactiveCocoa/ReactiveCocoa

Concepts ou langages similaires!
•

https://github.com/nevyn/SPAsync (inspiré de C#)
Au fait…
www.capitainetrain.com

Contenu connexe

Plus de CocoaHeads France

Plus de CocoaHeads France (20)

iOS App Group for Debugging
iOS App Group for DebuggingiOS App Group for Debugging
iOS App Group for Debugging
 
Asynchronous swift
Asynchronous swiftAsynchronous swift
Asynchronous swift
 
Visual accessibility in iOS11
Visual accessibility in iOS11Visual accessibility in iOS11
Visual accessibility in iOS11
 
My script - One year of CocoaHeads
My script - One year of CocoaHeadsMy script - One year of CocoaHeads
My script - One year of CocoaHeads
 
Ui testing dealing with push notifications
Ui testing dealing with push notificationsUi testing dealing with push notifications
Ui testing dealing with push notifications
 
CONTINUOUS DELIVERY WITH FASTLANE
CONTINUOUS DELIVERY WITH FASTLANECONTINUOUS DELIVERY WITH FASTLANE
CONTINUOUS DELIVERY WITH FASTLANE
 
L'intégration continue avec Bitrise
L'intégration continue avec BitriseL'intégration continue avec Bitrise
L'intégration continue avec Bitrise
 
Super combinators
Super combinatorsSuper combinators
Super combinators
 
Design like a developer
Design like a developerDesign like a developer
Design like a developer
 
Handle the error
Handle the errorHandle the error
Handle the error
 
Quoi de neuf dans iOS 10.3
Quoi de neuf dans iOS 10.3Quoi de neuf dans iOS 10.3
Quoi de neuf dans iOS 10.3
 
IoT Best practices
 IoT Best practices IoT Best practices
IoT Best practices
 
SwiftyGPIO
SwiftyGPIOSwiftyGPIO
SwiftyGPIO
 
Présentation de HomeKit
Présentation de HomeKitPrésentation de HomeKit
Présentation de HomeKit
 
Programme MFI retour d'expérience
Programme MFI retour d'expérienceProgramme MFI retour d'expérience
Programme MFI retour d'expérience
 
How to communicate with Smart things?
How to communicate with Smart things?How to communicate with Smart things?
How to communicate with Smart things?
 
Build a lego app with CocoaPods
Build a lego app with CocoaPodsBuild a lego app with CocoaPods
Build a lego app with CocoaPods
 
Let's migrate to Swift 3.0
Let's migrate to Swift 3.0Let's migrate to Swift 3.0
Let's migrate to Swift 3.0
 
Project Entourage
Project EntourageProject Entourage
Project Entourage
 
What's new in iOS9
What's new in iOS9What's new in iOS9
What's new in iOS9
 

Slide de Promises par Pierre de la Morinerie

  • 1. Les Promesses Une introduction aux Promesses en Objective-C
  • 6. Les Promesses : origine • « The Impact of Applicative Programming on Multiprocessing »
 Daniel P. Friedman and David Wise, 1976 • Parfois appelées Futures, Deferred ou Tasks
  • 7. Encore un truc ésotérique ? LISP Haskell Erlang
  • 9. Une Promesse • Un objet qui représente une valeur à venir • Des callbacks pour réagir aux changements
  • 10. Déclaration @interface Promise : NSObject { id _value; id (^)(id value) _onFulfilled; id (^)(id reason) _onRejected; } ! ! ! ! ! @end
  • 11. Déclaration @interface Promise : NSObject { id _value; id (^)(id value) _onFulfilled; id (^)(id reason) _onRejected; } ! ! (Promise*)thenOnFulfilled:(^…)onFulFilled ! onRejected:(^…)onRejected ! (void)resolve(id value); ! @end
  • 12. Utilisation [[self retrieveDataAsync] thenOnFulfilled:(id(^)(id value) { // do something with value } onRejected:(id(^)(id reason) { // present the error }];
  • 13. Quel intérêt ? • Réifier les callbacks • Standardiser les callbacks les rendre manipulables
  • 14. Trois intérêts pratiques 1. Simplifier les signatures des méthodes 2. Chaîner les callbacks 3. Tester le code asynchrone
  • 16. 1. Simplifier les signatures Sans Promesses : @interface NavitiaClient : NSObject ! - (void) placesForQuery:(NSString*)query completion:(void (^)(id jsonObject, NSError *error)) completionBlock; ! @end
  • 17. 1. Simplifier les signatures Avec Promesses : @interface NavitiaClient : NSObject ! - (Promise*) placesForQuery:(NSString*)query; ! @end
  • 18. 2. Chaîner les callbacks Sans Promesses : // ViewController.m ! [_navitiaClient placesForQuery:text completion:^(NSArray *places, NSError *error) { if (!error) { [_navitiaClient coordinatesForPlaces:places completion:^(NSArray *coordinates, NSError *error2) { if (!error2) { // display places coordinates } else { // handle error2 } } } else { // handle error } }];
  • 19. 2. Chaîner les callbacks Avec Promesses : // ViewController.m ! [[[_navitiaClient placesForQuery:text] ! thenOnFulfilled:(id(^)(NSArray *places) { return [_navitiaClient coordinatesForPlaces:places]; }] ! thenOnFulfilled:(id(^)(NSArray *coordinates) { // display places coordinates } ! onRejected:(id(^)(NSError *error) { // handle error }];
  • 20. 3.Tester le code asynchrone Sans Promesses : // ViewControllerTests.m ! [[[navitiaClientMock stub] andDo:^(NSInvocation *inv) { id (^completion)(NSArray *, NSError *); [inv getArgument:&completion atIndex:3]; completion(placesFixture, nil); }] placesForQuery:@"foo" completion:OCMARG_ANY]; ! [viewController updatePlacesWithQuery:@"foo"]; ! STAssertEqualObjects(viewController.places, placesFixture, nil);
  • 21. 3.Tester le code asynchrone Avec Promesses : // ViewControllerTests.m ! [[[navitiaClientMock stub] andResolvePromiseWithValue:placesFixture] placesForQuery:@"foo"]; ! [viewController updatePlacesWithQuery:@"foo"]; ! STAssertEqualObjects(viewController.places, placesFixture, nil);
  • 23. Références Introduction aux Promesses (en Javascript)! • http://blog.parse.com/2013/01/29/whats-so-great-about-javascriptpromises/ • http://fr.slideshare.net/domenicdenicola/callbacks-promises-andcoroutines-oh-my-the-evolution-of-asynchronicity-in-javascript Implémentations! • https://github.com/kemenaran/Rebelle • https://github.com/mproberts/objc-promise • https://github.com/ReactiveCocoa/ReactiveCocoa Concepts ou langages similaires! • https://github.com/nevyn/SPAsync (inspiré de C#)