Lê Khánh Vinh Lê Khánh Vinh - 1 year ago 94
Objective-C Question

IOS objective C write function with completionBlock

Hi I'm writing a

to call and API and get the
then store to
entity (Using magical record). My method simple take no input and return nothing (only call api and store data to
. My purpose is to execute completionBlock code when
and log an
(so that can call the function in a
. I'm still don't know how to write it properly. Anyhelp is much appreciate.

My Apiclient

typedef void (^ApiClientSuccess)(id responseObject);
typedef void (^ApiClientFailure)(NSError *error);

- (void)getSingpostContentsOnSuccess:(ApiClientSuccess)success onFailure:(ApiClientFailure)failure {

NSString *urlString = [NSString stringWithFormat:@"%@singpost-contents.php",CMS_BASE_URL];
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod:GET_METHOD URLString:urlString parameters:nil error:nil];

[self sendJSONRequest:request success:^(NSURLResponse *response, id responseObject) {
} failure:^(NSError *error) {
[self reportAPIIssueURL:[request.URL absoluteString] payload:nil message:[error description]];

My function (need to write it properly) so that I can call and write some code when function complete execute

+ (void)API_SingPostContentOnCompletion:(void)completionBlock {

[[ApiClient sharedInstance] getSingpostContentsOnSuccess:^(id responseJSON) {
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_rootSavingContext];
[responseJSON[@"root"] enumerateObjectsUsingBlock:^(id attributes, NSUInteger idx, BOOL *stop) {
Content *content = [Content MR_findFirstOrCreateByAttribute:@"name" withValue:attributes[@"Name"] inContext:localContext];
content.content = attributes[@"content"];

[localContext MR_saveToPersistentStoreWithCompletion:^(BOOL contextDidSave, NSError * _Nullable error) {
if (error) NSLog(@"Error save content to persistentStore");


// if (completionBlock) {
// dispatch_async(dispatch_get_main_queue(), ^{
// completionBlock();
// });
// }
} onFailure:^(NSError *error) {
// if (completionBlock) {
// dispatch_async(dispatch_get_main_queue(), ^{
// completionBlock(nil);
// });
// }
NSLog(@"Failed to get SingPost Content");


Answer Source

Declare the blocks :

  typedef void (^ SuccessBlock)(BOOL success, id response);
  typedef void (^ FailureBlock)(NSError *error, NSInteger statusCode);

Write the method that use these blocks, for example for a simple AFNetworking POST call:

+ (void)myFunction:(NSString*)function  success:(SuccessBlock)success failure:(FailureBlock)failure{

   AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
   [manager POST:functionURL parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
            if (operation.response.statusCode == 201 || operation.response.statusCode == 200) {
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            failure(error, operation.response.statusCode);

and you can call your method from other class:

[YourClass myFunction:@""  success:^(BOOL success, id response) {
            //my call is success
    } failure:^(NSError *error, NSInteger statusCode) {

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download