Sunday, November 10, 2013

Dropbox Core API with blocks

I've been adding support for Dropbox to FTP On The Go!  Because it needs full access so you can upload any file from your Dropbox, or download a file to any folder, it has to use the low level "Core"API.

The code from Dropbox is good, but uses delegates for everything.  I didn't want to have lots of checks for "file download complete" to see what to do with it next--edit/view, email it, upload it to an FTP server, or any of the other things.  With several operations potentially happening at the same time, that could get confusing :)

So I made a little wrapper for the DBRestClient to do Blocks.  The code for getting the metadata, like a folder's contents or details about a file, is below.  There are similar functions for all the other things, uploading or downloading files, etc.  I'll post all that once the new version of FTP is out.  (But as you can see it's a dozen or so lines of code for each one you'd want to do so pretty easy to add yourself.)


The .h
@interface DBRestClientBlock : DBRestClient 

@property (nonatomic, copy)  void (^loadedMetadata)(DBMetadata *metadata, NSError *error);

+ (DBRestClientBlock*)dbClient;

@end


The .m
@implementation DBRestClientBlock //DBRestClientDelegate

+ (DBRestClientBlock*)dbClient {
    DBRestClientBlock    *dbBlock = [[[DBRestClientBlock alloc] initWithSession:[DBSession sharedSession]] autorelease];
    dbBlock.delegate = dbBlock;
    return dbBlock;
}

//Metadata Downloading...
- (void)restClient:(DBRestClient *)client loadedMetadata:(DBMetadata *)metadata {
    NSLog(@"loadedMetadata");
    if (self.loadedMetadata) {
        self.loadedMetadata(metadata, nil);
    }
}
- (void)restClient:(DBRestClient*)client loadMetadataFailedWithError:(NSError*)error {
    NSLog(@"loadMetadataFailedWithError");
    if (self.loadedMetadata) {
        self.loadedMetadata(nil, error);
    }
}
@end


Then you get to do nice bits like:

DBRestClientBlock   *dbClient = [[DBRestClientBlock dbClient] retain];
dbClient.loadedMetadata = ^(DBMetadata *metadata, NSError *error) {
        if (metadata) {   
     //Do something with the results
        }
        if (error) {
            NSLog(@"loadedMetadataError: %@", error);
        }
        [dbClient release];
};
 
[dbClient loadMetadata:pathToLoad];


(I've also got a manager class, that caches these DBRestClientBlock objects too.)

No comments: