Reputation: 16186
I'm implementing the dropbox api for my new project app. The api is based around delegates & callbacks, in pairs (success + fail) like:
- (void)restClient:(DBRestClient*)client loadedMetadata:(DBMetadata*)metadata;
- (void)restClient:(DBRestClient*)client loadMetadataFailedWithError:(NSError*)error;
- (void)restClient:(DBRestClient*)client loadedAccountInfo:(DBAccountInfo*)info;
- (void)restClient:(DBRestClient*)client loadAccountInfoFailedWithError:(NSError*)error;
I wonder if exist a way to turn that into a obj-c async block, so I could do this:
+ (void)loadMetadata:(DBRestClient *)client queue:(NSOperationQueue *)queue completionHandler:(void (^)(DBMetadata*, NSError*))handler
Exist a kind of pattern that could be used for this? Or is necessary that the library be build with blocks from the start?
Upvotes: 5
Views: 914
Reputation: 888
There is now an open source library called 'DropBlocks' that provides block-based versions of all the Dropbox iOS SDK functions.
https://github.com/natep/DropBlocks
Full disclosure: I am the author of this library. I wrote it after becoming frustrated with the delegate paradigm described in this question. Feel free to check out the source to see how I implemented it.
Upvotes: 7
Reputation: 55583
You can make a helper function for this:
-(void) loadMetadataOnQueue:(NSOperationQueue *) queue completion:(void (^)(DBMetadata*, NSError*))handler
{
// assuming this is a category on DBRestClient
AsyncDelegate *delegate = [AsyncDelegate new];
delegate.metadataBlock = handler;
self.delegate = delegate;
[self loadMetadata:queue];
}
@interface AsyncDelegate
@property(readwrite, copy) void (^metadataBlock)(DBMetadata*, NSError*);
@end
@implementation AsyncDelegate
@synthesize metadataBlock;
-(void)restClient:(DBRestClient*)client loadedMetadata:(DBMetadata*)metadata
{
metadataBlock(metadata, nil);
}
- (void)restClient:(DBRestClient*)client loadMetadataFailedWithError:(NSError*)error
{
metadataBlock(nil, error);
}
end
Upvotes: 2