Coder Social home page Coder Social logo

iasynclite's Introduction

iAsyncLite

A better dispatch_async() with functional programming in mind.

This library is a fork of iAsync. 

iAsync repository has grown too much and contains lots of utility functions not needed by most of the developers. This fork is an attempt of creating a lightweigt, modular and well documented library.

The primary goal of the project :

  1. Full support of functional programming features from the original library
  2. Small footprint
  3. All public API must have appledoc reference.

iAsync - a better dispatch_async()

iAsync is a set of IOS libraries that aims to make asychronous programming easy for for Objective-C developers. It uses functional programming ideas to solve Callback Hell problem.

It has been designed as a more convenient dispatch_async() with task dependencies and functional programming values in mind.

License : BSD
Supports iOS versions 4.0 and higher. Builds using IOS SDK ver. 5.0

Contacts

  • google group : https://groups.google.com/forum/#!forum/iasync-users
  • skype chat (mostly, russian speaking) : skype:?chat&blob=8WfBM4NDRJZwtFEjtCR69UxYie9KVzZqp0pPogEOUHQGBbvMnxo4IxSHdusKsg8dfhFYYb5vKB2PSkJbfb72_bgSDfanudA7xIjsZORHA6FxPUaLhb7JXI1eFOnIo7l8C4pxHdpIeQipTw

Callback Hell Problem

You are suffering from the callback hell if you have a lot of nested asynchronous calls in your project. For example : Callback Hell

This makes your code hard error prone. It is hard to debug and maintain such codebase. There is a nice blogpost and a webinar by Miguel de Icaza .

Let's compare iAsync and the traditional approach

Weather application core task

This library aims to provide a more convenient task scheduler. Its main advantage is more elegant processing of operations with dependencies.

Let's consider an example weather application core. In order to get the weather by address we should perform the following actions :

  1. Query location from the geocoding service
  2. Parse latitude and longitude data
  3. Query weather using latitude and longitude data
  4. Parse weather info
  5. Update UI

Traditional approach with dispatch_async() and AFNetworking

NSString* geolocationUrl = [ NSString stringWithFormat: @"http://maps.googleapis.com/maps/api/geocode/json?sensor=true&address=%@", @"Kiev"];

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:geolocationUrl parameters:nil success:^(AFHTTPRequestOperation *operation, id jsonLocation) {
    dispatch_async( myBackgroundQueue, ^{
            NSError* parseError;
    
            id<AWCoordinatesParser> parser = [ AWParserFactory jsonCoordinatesParser ];
            AWCoordinates* coordinates = [ parser parseData: jsonLocation
                                                      error: &parseError ];
            if ( !coordinates )                                          
            {
                 [ self handleError: parseError ];
            }                                          
                                                     
            NSString* weatherUrl = [ NSString stringWithFormat: @"http://api.openweathermap.org/data/2.5/weather?lat=%1.2f&lon=%1.2f", coordinates.latitude, coordinates.longitude ];
            
            
            [manager GET:weatherUrl parameters:nil success:^(AFHTTPRequestOperation *operation, id jsonWeather) {
                  dispatch_async( myBackgroundQueue, ^{
                        NSError* parseError;
                        id<AWWeatherParser> parser = [ AWParserFactory jsonWeatherParser ];
                        AWWeatherInfo* weather = [ parser parseData: weatherJson
                                                              error: &parseError ];
                        if ( !weather )                                          
                        {
                            [ self handleError: parseError ];
                        }                                          
                        
                        dispatch_async( dispatch_get_main_queue(), ^{
                           [ self updateGuiWithWeatherInfo: weather ];
                        });
                  });
            } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                 [ self handleError: error ];
            }];
    });
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
     [ self handleError: error ];
}];

As you can see, this code has 4 levels of nested callbacks and is hard to maitain. Let's see how iAsync will help you dealing with this complexity.

iAsync approach

Using iAsync you can rewrite the code above in functional programming manner. In our example we use a waterfall flow that ensures execution order and passes results of the previous asynchronous function to the one being executed.

Waterfall flow

So, the code above can be rewritten in a declarative manner :

+(JFFAsyncOperation)asyncWeatherForAddress:( NSString* )userInput
{
   return bindSequenceOfAsyncOperationsArray
   (
      [ self asyncLocationForAddress: userInput ],
     @[
         [ self parseRawAddressBinder ],
         [ self getWeatherBinder      ],
         [ self parseWeatherBinder    ]
      ]
   );
}

And it is as easy to use as built-in dispatch_async() routines :

-(IBAction)getWeatherButtonTapped:(id)sender
{
   [ self.txtAddress resignFirstResponder ];
   
   NSString* address = self.txtAddress.text;
   if ( ![ self validateAddress: address ] )
   {
	  // Handle validation error and show alert
      return;
   }
   
   
   JFFAsyncOperation loader = [ AWOperationsFactory asyncWeatherForAddress: address ];
   
   
   __weak ESViewController* weakSelf = self;
   JFFCancelAsyncOperationHandler onCancel = ^void(BOOL isOperationKeepGoing)
   {
      [ weakSelf onWeatherInfoRequestCancelled ];
   };
   JFFDidFinishAsyncOperationHandler onLoaded = ^void(id result, NSError *error)
   {
      [ weakSelf onWeatherInfoLoaded: result
                           withError: error ];
   };
   JFFCancelAsyncOperation cancelLoad = loader( nil, onCancel, onLoaded );
   self->_cancelLoad = cancelLoad;
   
   self.activityIndicator.hidden = NO;
   [ self.activityIndicator startAnimating ];
}

-(IBAction)cancelButtonTapped:(id)sender
{
   if ( nil != self->_cancelLoad )
   {
      self->_cancelLoad( YES );
   }
   
   [ self.activityIndicator stopAnimating ];
   self.activityIndicator.hidden = YES;
   self.resultView.hidden = YES;
}

Of course, we should implement download and parsing routines. Full source code of the sample can be found at the repository below : https://github.com/dodikk/weather-iasync

iAsync flow control operators

iAsync has the following flow control for operations for your asynchronous blocks :

  • sequence - operations are executed one after another.
  • sequence of attempts - operations are executed one after another until one of them succeeds
  • group - operations are executed in parallel. A single callback is triggered when all of them are finished.
  • waterfall - operations are executed one after another. Results of the previous operation are passed to the one under execution as input.

The library has many more features to explore. See the readme in the "lib" directory for details.

iasynclite's People

Contributors

dodikk avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

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.