Giter Site home page Giter Site logo

rebelle's Introduction

Rebelle

Rebelle is an Objective-C implementation of Promises/A+ with a rebel syntax for an Objective-c project: the classical call syntax used in C, C++ and other languages and which allow you to chain your calls while still having your code readable.

You can follow project changes here and/or coming features here

Any contribution is welcomed!

What is a Rebelle promise

A promise represents the eventual result of an asynchronous operation. The primary way of interacting with a promise is through its then method, which registers callbacks to receive either a promise's eventual value or the reason why the promise cannot be fulfilled (promises documentation)

That is, a promise allows you to execute actions (blocks) attached to it asynchronously.

How to use it

Rebelle comes with a sample project. You can check it to see how things work. Or you can read below explanations.

Basic usage

Creating a promise is quite simple:

RBPromise *promise = [RBPromise new];
      
promise.then(^id(NSString *result) {
  // execute any code when succeeded
  NSLog(@"success with result %@", result);
        
  return result;
        
}, ^id(NSException *exception) {
  // handle any exception
  NSLog(@"failed with exception %@", result);

  return exception;
});
    
[promise.resolve:@"hello world"]; // Rebelle will automatically call your success or exception callbacks

Now that you know how works a RBPromise, you can actually use it inside your code and return it so that any asynchronous code got executed once resolved.

(This is quick code to show how and when to use promises, but obviously this is not "clean" code)

@implementation WebService
      
- (RBPromise *)getUser(int id) {
  self.promise = [RBPromise new];
        
  NSURLRequest aRequest = // request to server;
        
  // Call the server and get data about user
  // If you use classes that use delegates instead of callbacks, then you'll need
  // to save your promise inside a class attribute, otherwise just call it inside your blocks
        
  NSURLConnection *connection = [NSURLConnection connectionWithRequest:aRequest delegate:self];
        
  // this promise result (when succeeded) should be a User object
  return self.promise; // Return your promise so you can add chain blocks on it !
}
      
- (RBPromise *)getTweets:(User *)user {
  // Same idea than in getUser
  // This promise result is an NSArray of Tweet objects
}
      
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
  [self.promise resolve: // result from the response];
}
      
@end
      
@implementation  MyApp

- (RBPromise *)sample {
  WebService *ws = [WebService new];
      
  // you 
  RBPromise *promise = [ws getUser];
        
  promise.then(^id(User *user) { user.lastLoggedIn = new Date(); return user; }, nil)
         .then(^id(User *user) { return [ws getTweets:user]; }, nil);
         .then(^id(NSArray *tweets) { // This code is executed only when tweets have been downloaded }, nil);
      
  return promise; // You can either return once again your promise so that any upper code chain on it too...
  // Everyhing will be resolved in the order when previous code has been executed !
}
      
@end

So what does this code ?

  1. We're calling an asynchronous webservice getUser
  2. Once user data is collected, we're setting some date on the user
  3. Then we're calling another asynchronous webservice getTweets
  4. Once tweets are collected, we're executing another block
  5. And so go on...

For more information about then and the chain syntax used by Rebelle, check the wiki Promise chaining page

What about NSError ?!

Your promise will be marked as failed/rejected if you resolve it with either a NSError or NSException object. The only difference is that NSError objects are wrapped into a RBErrorException when passed to the failure block whose signature is (^id(NSException *exception)).

/// NSError example
NSError *error = [NSError errorWithDomain:@"FileDomain" code:0 userInfo:nil];

[promise resolve:error]
.then(nil, ^(RBErrorException *e) { NSLog(@"Domain error is %@", e.error.domain); return e; });


/// NSException example
NSException *e = [NSException exceptionWithName:@"FileNotFoundException" reason:nil userInfo:nil];

[promise resolve:e].then(nil, ^(NSException *e) { NSLog(@"Exception is %@", e.name); return e; });

Install

To install Rebelle the easiest (and preferred way) is through CocoaPods:

  1. Add the project inside your Podfile

     pod Rebelle, '~> 1.0.x'
    
  2. Update your installation

     pod install
    

Under the hood

Chainable syntax secret

To be able to have a chainable syntax Rebelle is massively using blocks as properties on RBPromise object instances. So when you're calling then(SuccessBlock, FailureBlock) you're in fact calling a NSBlock by passing it 2 arguments.

Promises

For more information on Promises/A+, check the documentation repository

Promises/A+ logo

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.