Search code examples
iosobjective-crestafnetworkingafnetworking-2

multipart PUT request using AFNetworking


What's the correct way to code a multipart PUT request using AFNetworking on iOS? (still Objective-C, not Swift)

I looked and seems like AFNetworking can do multipart POST but not PUT, what's the solution for that?

Thanks


Solution

  • You can use multipartFormRequestWithMethod to create a multipart PUT request with desired data.

    For example, in AFNetworking v3.x:

    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
    NSError *error;
    NSURLRequest *request = [manager.requestSerializer multipartFormRequestWithMethod:@"PUT" URLString:@"http://example.com/rest/api/" parameters:@{@"foo" : @"bar"} constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        NSString *value = @"qux";
        NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding];
        [formData appendPartWithFormData:data name:@"baz"];
    } error:&error];
    
    NSURLSessionDataTask *task = [manager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
        if (error) {
            NSLog(@"%@", error);
            return;
        }
    
        // if you want to know what the statusCode was
    
        if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
            NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
            NSLog(@"statusCode: %ld", statusCode);
        }
    
        NSLog(@"%@", responseObject);
    }];
    [task resume];
    

    If AFNetworking 2.x, you can use AFHTTPRequestOperationManager:

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    
    NSError *error;
    NSURLRequest *request = [manager.requestSerializer multipartFormRequestWithMethod:@"PUT" URLString:@"http://example.com/rest/api/" parameters:@{@"foo" : @"bar"} constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        NSString *value = @"qux";
        NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding];
        [formData appendPartWithFormData:data name:@"baz"];
    } error:&error];
    
    AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"%@", responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"%@", error);
    }];
    
    [manager.operationQueue addOperation:operation];
    

    Having illustrated how one could create such a request, it's worth noting that servers may not be able to parse them. Notably, PHP parses multipart POST requests, but not multipart PUT requests.