2016-08-08 38 views
0

Hallo Ich schreibe ein function zu rufen und API und erhalten Sie die response dann speichern coredata Einheit (mit magischen Rekord). Meine Methode einfach keine Eingabe und nichts zurück (nur Anruf api und speichern Daten auf entity. Mein Ziel ist, completionBlock Code ausführen, wenn success und log error (so dass die Funktion in einem viewController aufrufen kann. Ich bin immer noch nicht wissen, wie es richtig zu schreiben. Anyhelp ist viel zu schätzen wissen.IOS-Objektiv C Schreibfunktion mit completionBlock

Mein 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) { 
     success(responseObject); 
    } failure:^(NSError *error) { 
     failure(error); 
     [self reportAPIIssueURL:[request.URL absoluteString] payload:nil message:[error description]]; 
    }]; 
} 

Meine Funktion (müssen es richtig schreiben), so dass ich anrufen kann und einige Code schreiben, wenn die Funktion vervollständigen ausführen

+ (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"); 
    }]; 

} 

Antwort

2

Deklarieren Sie die Blöcke:

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

die Methode schreiben, die diese Bausteine ​​zu verwenden, zum Beispiel für einen einfachen AFNetworking POST Aufruf:

+ (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) { 
       success(YES,responseObject); 
      }else{ 
       success(NO,responseObject); 
      } 
     } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
      failure(error, operation.response.statusCode); 
     }]; 
    } 

und Sie Ihre Methode aus anderen Klasse aufrufen können:

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

    }]; 
+0

Danke, ich werde versuchen zu schreiben, wie Ihre Vorschläge vorschlagen. In der Zwischenzeit habe ich es geschafft, so zu schreiben: + (void) API_SingPostContentOnCompletion: (void (^) (BOOL Erfolg)) completionBlock {}. Kann das benutzt werden? –

+0

Wenn Sie block als typedef void deklarieren, dann müssen Sie nicht void^(... in der Methode als Parameter verwenden. Wenn Sie die direkte Deklaration übergeben möchten, können Sie etwas tun wie: - (void) myFunction: (void (^) (id, int)) myBlock; –

+0

Ist das AFNetworking, das Sie oben geschrieben haben, für 2.x, das ich für 3.x benutze, müssen Sie vielleicht etwas ändern? –