AFNetworking - 发布 http 数据后卡住

AFNetworking - stuck after posting http data

我从 2013 年继承了一些 Objective-C 代码:太旧了,以至于它使用了 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];  
}

在这个 class 的相应头文件中,AFClaimNotificationAPIClient 是这样定义的:

@interface AFClaimNotificationAPIClient : AFHTTPClient

并且 AFHTTPClient 不再存在。它在 AFNetworking 2.0 中被删除,在编写这段代码后不久就出现了。

经过大量论坛搜索后,我实际上已经通过升级到 AFNetworking 2.0 并将 AFClaimNotificationAPIClient 重新定义为 AFHTTPSessionManager 使其再次部分工作:

@interface AFClaimNotificationAPIClient : AFHTTPSessionManager

我的提交按钮代码现在如下所示:

- (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  
}

我选择 AFHTTPSessionManager 作为我 class 的新类型,因为它是我能找到的唯一包含 constructingBodyWithBlock 定义的类型,并且我试图使代码尽可能接近原始代码。

令人惊讶的是,我重新编写的代码实际上将数据发送到服务器并得到回复。但是,应用程序此时挂起,因为调用代码(此处未显示)未收到成功(或失败)消息。我可以看到我已经从原始代码中删除了整个步骤 - operation 变量的设置,然后触发其 setCompletionBlockWithSuccess 方法。

你需要根据响应传递一个responseObject或者一个error对应的操作来执行block

试试这个

- (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  
}

您也可以使用 AFHTTPRequestOperation,这将 return 您的回调中需要的两个参数