ChillyPenguin
ChillyPenguin

Reputation: 1180

AFNetworking - stuck after posting http data

I've inherited some Objective-C code from 2013: so old that it used AFNetworking 1.0!

@implementation AFClaimNotificationAPIClient

+ (AFClaimNotificationAPIClient *)sharedClient {
    static AFClaimNotificationAPIClient *_sharedClient = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedClient = [[AFClaimNotificationAPIClient alloc] initWithBaseURL:[NSURL URLWithString:kClaimNotificationURL]];
    });

    return _sharedClient;
}

- (void) submit:(ClaimNotification *) claimNotification
      success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
      failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure {

    NSMutableURLRequest *request = [self multipartFormRequestWithMethod:@"POST" path:kClaimNotificationURL parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {

        [self populateFormDataForJson:formData andClaimNotification:claimNotification];
        [self populateFormDataWithAttachemnts:formData andClaimNotification:claimNotification];

    }];

    AFJSONRequestOperation *operation = [[AFJSONRequestOperation alloc] initWithRequest:request];
    DDLogVerbose(@"%@", request.HTTPBody);
    [operation setCompletionBlockWithSuccess:success failure:failure];

    [operation start];  
}

In the corresponding header file for this class, the AFClaimNotificationAPIClient is defined thus:

@interface AFClaimNotificationAPIClient : AFHTTPClient

and AFHTTPClient no longer exists. It was dropped in AFNetworking 2.0, which came out shortly after this code was written.

After much forum searching, I've actually managed to get it partially working again by upgrading to AFNetworking 2.0, and redefining AFClaimNotificationAPIClient as an AFHTTPSessionManager:

@interface AFClaimNotificationAPIClient : AFHTTPSessionManager

My submit button code now looks like this:

- (void) submit:(ClaimNotification *) claimNotification
      success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
      failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure {

    NSURLSessionDataTask *request = [self POST:kClaimNotificationURL parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        [self populateFormDataForJson:formData andClaimNotification:claimNotification];
        [self populateFormDataWithAttachemnts:formData andClaimNotification:claimNotification];
    } success:^(NSURLSessionDataTask *task, id responseObject) {
        DDLogVerbose(@"Post success");
        // handle success
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        DDLogVerbose(@"Post error");

    }];
//    [operation start];
    [request resume];  // [request start] doesn't work  
}

I chose AFHTTPSessionManager as the new type for my class because it's the only one that I could find that contains the constructingBodyWithBlock definition, and I was trying to keep the code as close to the original as possible.

Amazingly enough, my reworked code actually posts data to the server and gets a reply. However, the app hangs at that point because the calling code (not shown here) is not receiving a success (or failure) message. I can see that I've removed a whole step from the original code - the setting up of the operation variable and then the triggering of its setCompletionBlockWithSuccess method.

Upvotes: 2

Views: 115

Answers (1)

Reinier Melian
Reinier Melian

Reputation: 20804

You need to execute the block according to the response passing a responseObject or an error with the corresponding operation

try this

- (void) submit:(ClaimNotification *) claimNotification
      success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
      failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure {

    NSURLSessionDataTask *request = [self POST:kClaimNotificationURL parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        [self populateFormDataForJson:formData andClaimNotification:claimNotification];
        [self populateFormDataWithAttachemnts:formData andClaimNotification:claimNotification];
    } success:^(NSURLSessionDataTask *task, id responseObject) {
        DDLogVerbose(@"Post success");
        // handle success
        success(nil,responseObject);
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        DDLogVerbose(@"Post error");
        failure(nil, error);
    }];
//    [operation start];
    [request resume];  // [request start] doesn't work  
}

You can use AFHTTPRequestOperation as well and this will return both parameters needed in your callbacks

Upvotes: 1

Related Questions