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?
Asynchronous callbacks are functions passed to another function that starts executing code in the background. Typically, when the code in the background finishes, the async callback function is called as a way of notifying and passing on data to the callback function that the background task is finished.
A callback function executes when an asynchronous operation completes. Here is an example of how a setTimeout function works: function printMe() { console.
To convert a callback into a promise, you need to return a promise. You run the code with the callback inside the promise. const readFilePromise = () => { return new Promise((resolve, reject) => { fs. readFile(filePath, options, (err, data) => { // ... }) }) }
js applications. Async functions return a Promise by default, so you can rewrite any callback based function to use Promises, then await their resolution.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With