AFnetworking 2.2.0 upload image on server issues

2019-01-15 11:32发布

问题:

The reason why ask you have to do it because I confuse about params.

As I understood there one way how to do it using multi part request.

This way offers us two concepts as I understood upload from file that can be stored in Document directory or using NSData object.

Upload from the file:

So I have saved test.jpg to the document directory. Then I make NSURL instance to use it in multi part request. The code below shows how I create NSURL instance:

NSString *fileName = @"test.jpg";
NSString *folderPath = [documentsDirectory stringByAppendingPathComponent:fileName];
NSURL *filePath = [NSURL fileURLWithPath:folderPath];

When I print file path:

file:///Users/mac/Library/Application%20Support/iPhone%20Simulator/7.0.3/Applications/F732FCF6-EAEE-4E81-A88B-76ADB75EDFD1/Documents/test.jpg

Then I set my parameters and using formData to attach my file as below:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = @{@"foo": @"bar"};
NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"];
[manager POST:@"http://example.com/resources.json" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
    [formData appendPartWithFileURL:filePath name:@"image" error:nil];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"Success: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

Is this correct? or maybe I miss something because the response is not success?

The second concept - work directly with data:

[formData appendPartWithFileData:imageData name:@"image" fileName:@"test.jpg" mimeType:@"image/jpeg"];

but when the app invokes this line of code I got the error:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: body'

The reason I suppose that the imageData defined outside the manager block is nil on this line. So I need help here as well how to pass it into the block.

Please can you correct me what's wrong in my steps maybe I miss something.

Also when I comment the line

[formData appendPartWithFileData:imageData name:@"image" fileName:@"test.jpg" mimeType:@"image/jpeg"];

or

[formData appendPartWithFileURL:filePath name:@"image" error:nil];

then everything works fine and I get success response in rerun.

回答1:

Have you confirmed that the file is found at that location in your Documents folder? I'm also having trouble reconciling your programmatically determined file path (which is correct) with your string literal file path (which can easily be problematic). You should always programmatically determine the path, not using string literals (because when you reinstall the app, that path will change). What I think you need is something like:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = @{@"foo": @"bar"};
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"image.png"];
NSURL *fileURL = [NSURL fileURLWithPath:filePath];

[manager POST:@"http://example.com/resources.json" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
    NSError *error;
    BOOL success = [formData appendPartWithFileURL:fileURL name:@"image" fileName:filePath mimeType:@"image/png" error:&error];
    if (!success)
        NSLog(@"appendPartWithFileURL error: %@", error);
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"Success: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

Note, this programmatically determines the filePath (which is a path, not a URL), and then uses fileURLWithPath to convert that to a file URL. It also confirms whether it was successful or not, logging the error if not successful.

Also note that this assumes your server is returning its response as JSON. If not, you'd have to change the responseSerializer.