Thu, 09 Jun 2011 10:19:00 GMT

ASI HTTP Request Library Review

ASI has a useful class library for wrapping around the CFNetwork framework, the networking Core Foundation framework designed by Apple as a programming interface to lower-level network capabilities of iOS and OS X; CFNetwork framework is available on both platforms.

But how useful does All-Seeing Interactive’s work prove to be for interacting with RESTful web services?

Pros

It works. That’s a good start. But not the only important thing. The codebase should provide a foundation, something to build on. Therefore working is one important quality, but it also needs to provide flexible building blocks on which to build higher level functions of different kinds.

Useful Features

They include:

  • Handles connection retries and redirections
  • Handles proxies and authentication
  • Has data compression and decompression capabilities
  • Has useful operation sub-class for interacting with Amazon S3 (simple static storage)

Extra Dependencies

Not too many. Apart from Apple’s Cocoa umbrella framework, run-time dependencies include:

  • libz
  • libxml2
  • libtidy

These libraries are part of the standard platform for both iOS and OS X.

For build-time and testing dependencies adds GHUnit framework.

Cons

Cons mainly concern implementational issues.

Request Is an Operation

ASIHTTPRequest is an operation to process a request, not the request itself. Hence the request has a delegate too. This jars with Foundation framework semantics where requests are the request objects not behavioural elements which make requests and collect responses. It’s a English language problem: “request” is a noun and a verb—a source of ambiguity.

Class Architecture

ASIHTTPRequest class carries an enormous amount of ‘state’ and sub-state, in the form of a whopping 141 instance variables! In addition, there is a considerable amount of static state: 35 statics.

In general, this indicates a lack of class-architecture decomposition. Such approaches throw functionality into the one class, making it easy to implement in the short run, but hard to maintain and error prone in the long run. Cross-coupling leads to unexpected and hard-to-debug side effects. You often find that this approach leaves the design with lots of class-scoped methods inappropriately hanging from classes and nested behaviours switching on various internal and typically undocumented states and sub-states.

This is the case with ASIHTTPRequest.

Threading and Locks

The implementation uses old-style threading and locks. Locks have a performance cost, introduce blocking, and scope for race conditions.

However, as of version 4.0, iOS support blocks and Grand Central Dispatch which makes better use of multi-cored hardware and multi-threading systems, and makes implementing concurrent operations more robust.

Other Noteworthy Cons

Other notes:

  • Uses a cascading tree of request operations. Every request has a main request.

  • Does not delineate public and private methods, e.g. using categories.

  • Seems to overlap built-in functionality to some extent. iOS and OS X support some functions such as caching, cookies and authentication at some level.

  • Request operations run in a single background thread.

Conclusions

The library has some useful functionality, but at mid-2011 needs some additional work. It does not including any kind of routing functionality for RESTful transactions. And at its core lies a heavy-weight HTTP request operation into which the developers have folded most of the available functionality. For ongoing development goals, it would be nice to see some of the class functionality teased apart with less coupling and more flexibility.

-sendAsynchronousRequest:queue:completionHandler:

As it turns out, much of the requirement for handling URL connections will be appearing in iOS 5.0; this includes queuing asynchronous request operations, which is the primary focus of ASI’s library. In the new version of the operating system, you can send -[NSURLConnection sendAsynchronousRequest: queue: completionHandler:] to run an asynchronous URL request in some operation queue. It invokes a completion handler on the main thread when the request completes. Your block receives the NSURLResponse and the data. This new API becomes available in OS X 10.7 Lion and iOS 5.0!

iOS 5.0 defines the following interface.

/*!
    @category NSURLConnection(NSURLConnectionQueuedLoading)

    The NSURLConnectionQueuedLoading category on NSURLConnection
    provides the interface to perform asynchronous loading of URL
    requests where the results of the request are delivered to a
    block via an NSOperationQueue.

    Note that there is no guarantee of load ordering implied by this
    method.
 */
@interface NSURLConnection (NSURLConnectionQueuedLoading)

/*!
    @method       sendAsynchronousRequest:queue:completionHandler:

    @abstract 
                  Performs an asynchronous load of the given
                  request. When the request has completed or failed,
                  the block will be executed from the context of the
                  specified NSOperationQueue.

    @discussion
                  This is a convenience routine that allows for
                  asynchronous loading of an url based resource.  If
                  the resource load is successful, the data parameter
                  to the callback will contain the resource data and
                  the error parameter will be nil.  If the resource
                  load fails, the data parameter will be nil and the
                  error will contain information about the failure.

    @param
         request   The request to load. Note that the request is
                   deep-copied as part of the initialization
                   process. Changes made to the request argument after
                   this method returns do not affect the request that
                   is used for the loading process.

    @param 
         queue     An NSOperationQueue upon which    the handler block will
                   be dispatched.

    @param
         handler   A block which receives the results of the resource load.
 */
+ (void)sendAsynchronousRequest:(NSURLRequest *)request
                          queue:(NSOperationQueue*) queue
              completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*)) handler NS_AVAILABLE(10_7, 5_0);
           
@end

Trackbacks

Use the following link to trackback from your own site:
http://blog.pioneeringsoftware.co.uk/trackbacks?article_id=28

Comments

  • nonamelive says

    Hi,

    I’m working on a project whose deployment target is 3.0, which means I have to support 3.0 and later iOS versions, so there are no blocks and GCD there. What do you think about using ASIHTTPRequest in this kind of project?

    Thank you in advance.

    Kai

Leave a comment

(never displayed)

Markdown enabled