Skip to content
Andreas Grosam edited this page May 31, 2013 · 1 revision

Since the concept of Promises might be quite new to Objective-C developers, a few use cases might be helpful which demonstrate how they work and what one can do with them.

Wrapping a potentially lengthy synchronous method call into an asynchronous method returning a promise:

- (RXPromise*) asyncParseJSON:(NSData*)json
{
    RXPromise* promise = [[RXPromise alloc] init];
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSError* __autoreleasing error;
        id jsonResult = [NSJSONSerialization JSONObjectWithData:json options:0 error:&error];
        if (jsonResult != nil) {
            [promise fulfillWithValue:jsonResult];
        }
        else {
            [promise rejectWithReason:error];
        }
    });
        
    return promise;
}

Discussion:

NSJSONSerialization class has been used as an example whose methods are all synchronous. Basically, every method having this form with an NSError parameter can be wrapped like this.

Whether or not scheduling a method onto another queue makes sense or not depends on how long this methods takes to execute and whether this should be scheduled off from the main thread. For example, an iPad 3 would take about 35 ms to parse a 250kByte JSON file with NSJSONSerialization and returning a representation.

One caveat is that the invoked method JSONObjectWithData:options:error: is not cancelable and thus cannot benefit from the cancellation feature implemented in RXPromise.

Example usage:

Given an asynchronous method asyncLoadUsersJSONWithURL: which handles our network request and loads a JSON text, we could use the wrapped JSON parser as follows:

// Returns a promise whose value is JSON loaded from the net
-(RXPromise*) asyncLoadUsersJSONWithURL:(NSURL*)url {
    RXPromise* promise = [[RXPromise alloc] init];
    ...
    return promise;
}


// Returns a promise whose value is a JSON representation (here, probably an 
// `NSArray` containing a number of `NSDictionary` representing a User)
- (RXPromise*) asyncLoadUsersFromURL:(NSURL*) url {
    return [self asyncLoadUsersJSONWithURL:url].then(^id(id jsonData){
        return [self asyncParseJSON:jsonData];
    }, nil );
}