0

I am using AFNetworking and would like to upload an NSData object to my server. I am trying to upload to our SOAP server, so I have XML that I have converted to an NSData object. For some reason, the follow does NOT work:

// Back to NSData
    NSData *convertedFile = [xml dataUsingEncoding:NSUTF8StringEncoding];

    NSURL *url = [NSURL URLWithString:siteConfiguration.soapURL];
    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
    NSMutableURLRequest *request = [httpClient multipartFormRequestWithMethod:@"POST" path:@"" parameters:nil constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
        [formData appendPartWithFormData:convertedFile name:assetCreation.name];
    }];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {

        // Progress
        float totalProgress = (float)totalBytesWritten/(float)totalBytesExpectedToWrite;
        progress(totalProgress, totalBytesWritten, totalBytesExpectedToWrite);
        if (totalBytesExpectedToWrite == totalBytesWritten) {

            completion();

        }
    }];
    [operation start];

But when not using the multipartFormRequestWithMethod block, it DOES work and the file is correctly uploaded, but there is NO progress shown, as the callback is only called once:

// Back to NSData
NSData *convertedFile = [xml dataUsingEncoding:NSUTF8StringEncoding];

NSURL *url = [NSURL URLWithString:siteConfiguration.soapURL];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod: @"POST"];
[request setHTTPBody:convertedFile];

AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {

    // Progress
    float totalProgress = (float)totalBytesWritten/(float)totalBytesExpectedToWrite;
    progress(totalProgress, totalBytesWritten, totalBytesExpectedToWrite);
    if (totalBytesExpectedToWrite == totalBytesWritten) {

        MatrixAsset *asset = [[MatrixAsset alloc] init];
        completion(asset);

    }
}];
[operation start];

It seems that my server really wants to be sent the HTTPBody with my NSData object. Is it possible to do the same with the AFNetworking progress callback?

Nic Hubbard
  • 41,587
  • 63
  • 251
  • 412
  • have you tried `[formData appendPartWithFileData:convertedFile name:assetCreation.name];` instead of `[formData appendPartWithFormData:convertedFile name:assetCreation.name];` ? – mkral Nov 07 '12 at 22:24
  • also i'd set the `mimeType:` to `text/xml` – mkral Nov 07 '12 at 22:29
  • There isn't a method called [formData appendPartWithFileData:convertedFile name:assetCreation.name], at least not in the newest version of AFNetworking. I need to send it as a form I think since it is to our SOAP server and there is other field data being sent. – Nic Hubbard Nov 08 '12 at 00:28
  • Setting the content type to text/xml doesn't help. I used: [request setValue:@"text/xml" forHTTPHeaderField:@"Content-type"]; and it stopped the progress callback from working. – Nic Hubbard Nov 08 '12 at 00:35

2 Answers2

0

Ok, I got it working. Looks like I was going about it wrong:

// Setup the connection
    NSString *wsdlURL = [NSString stringWithFormat:@"%@?WSDL", siteConfiguration.soapURL];
    NSURL *serviceUrl = [NSURL URLWithString:wsdlURL];
    NSMutableURLRequest *serviceRequest = [NSMutableURLRequest requestWithURL:serviceUrl];
    [serviceRequest setValue:@"text/xml" forHTTPHeaderField:@"Content-type"];
    [serviceRequest setHTTPMethod:@"POST"];
    [serviceRequest setHTTPBody:[xml dataUsingEncoding:NSUTF8StringEncoding]];

    // Operation
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:serviceRequest];
    [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {

        // Progress
        float totalProgress = (float)totalBytesWritten/(float)totalBytesExpectedToWrite;
        progress(totalProgress, totalBytesWritten, totalBytesExpectedToWrite);

    }];
    [operation  setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"Success");
        MatrixAsset *asset = [[MatrixAsset alloc] init];
        completion(asset);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"error: %@", error.localizedDescription);
        NSLog(@"error: %@", error.localizedFailureReason);
    }];
    [operation start];
Nic Hubbard
  • 41,587
  • 63
  • 251
  • 412
0

You need SOAPAction to continue:

[serviceRequest setValue:@"SOAP_ACTION_URL" forHTTPHeaderField:@"SOAPAction"];
thienlode
  • 68
  • 1
  • 8