Blocks are a powerful C-language feature that is part of Cocoa application development. They are similar to “closures” and “lambdas” you may find in scripting and programming languages such as Ruby, Python, and Lisp. For a more in-depth review of blocks, see “a short practical guide to blocks”. A Backendless user has recently asked us about the ability to handle asynchronous APIs via block-based callbacks. Since this is a very reasonable request, we added support for blocks and it is available in the latest version of the Backendless SDK for iOS. Below is an example of using the new feature with the user registration and login APIs (btw, the feature is available for ALL Backendless APIs):
-(viod)registerUserAsync { NSString *userName =@"user2"; NSString *password = @"87654321"; BackendlessUser *user = [BackendlessUser new]; user.email = [NSString stringWithFormat:@"%@@foo.com", userName]; user.password = password; user.name = userName; [backendless.userService registering:user response:^(BackendlessUser *registeredUser) { [self onRegister:registeredUser]; [backendless.userService login:registeredUser.email password:password response:^(BackendlessUser *response) { [self onLogin:backendless.userService.currentUser]; [backendless.userService logout:^(id response) { [self onLogout:backendless.userService.currentUser]; } error:^(Fault *fault){ [self onError:fault]; } ]; } error:^(Fault *fault){ [self onError:fault]; } ]; } error:^(Fault *fault){ [self onError:fault]; } ]; }
By the way, here is an example of code that does the same thing, but synchronously:
-(viod)registerUserSync { @try { NSString *userName = @"user1"; NSString *password = @"12345678" BackendlessUser *user = [BackendlessUser new]; user.email = [NSString stringWithFormat:@"%@@foo.com", userName]; user.password = password; user.name = userName; BackendlessUser *registeredUser = [backendless.userService registering:user]; [self onRegister:registeredUser]; [backendless.userService login:registeredUser.email password:password]; [self onLogin:backendless.userService.currentUser]; [backendless.userService logout]; [self onLogout:backendless.userService.currentUser]; } @catch (Fault *fault) { [self onError:fault]; } }
The example below demonstrates the usage of block callbacks with the Data Service API in order to:
-(void)entitySaveAsync { __block Weather *entity = [Weather new]; [backendless.persistenceService save:entity response:^(id response) { entity = (Weather *)response; [self onResponse:entity action:@"BLOCKS!!! entitySave (save)"]; [backendless.persistenceService findByClassId:[entity class] sid:entity.objectId response:^(id response) { entity = (Weather *)response; [self onResponse:entity action:@"BLOCKS!!! entitySave (findByClassId)"]; [backendless.persistenceService first:[entity class] response:^(id response) { entity = (Weather *)response; [self onResponse:entity action:@"BLOCKS!!! entitySave (first)"]; [backendless.persistenceService last:[entity class] response:^(id response) { entity = (Weather *)response; [self onResponse:entity action:@"BLOCKS!!! entitySave (last)"]; [backendless.persistenceService remove:[entity class] sid:entity.objectId response:^(NSNumber *response) { [self onResponse:response action:@"BLOCKS!!! entitySave (remove)"]; } error:^(Fault *fault){ [self onError:fault]; } ]; } error:^(Fault *fault){ [self onError:fault]; } ]; } error:^(Fault *fault){ [self onError:fault]; } ]; } error:^(Fault *fault){ [self onError:fault]; } ]; } error:^(Fault *fault){ [self onError:fault]; } ]; }
If you prefer to use the synchronous (blocking) API, the follow code does the same thing as the example above (but synchronously):
-(void)entitySaveSync { Weather *entity = [Weather new]; @try { entity = [backendless.persistenceService save:entity]; [self onResponse:entity action:@"SYNC!!! entitySave (save)"]; entity = [backendless.persistenceService findByClassId:[entity class] sid:entity.objectId]; [self onResponse:entity action:@"SYNC!!! entitySave (findByClassId)"]; entity = [backendless.persistenceService first:[entity class]]; [self onResponse:entity action:@"SYNC!!! entitySave (first)"]; entity = [backendless.persistenceService last:[entity class]]; [self onResponse:entity action:@"SYNC!!! entitySave (last)"]; NSNumber *result = [backendless.persistenceService remove:[entity class] sid:entity.objectId]; [self onResponse:result action:@"SYNC!!! entitySave (remove)"]; } @catch (Fault *fault) { [self onError:fault]; } }
Enjoy!