Image Posting is failing with Type Encoding Issue - afnetworking

I am trying to upload a picture from an iPhone to a Django Web Service and I keep getting a 400 with this specific message :
error: {"image": ["No file was submitted. Check the encoding type on the form."]}.
I have sat up for hours trying to figure this out and i believe that somehow, the mime-type is not being sent properly.
Would you have any ideas, or better ways to upload an image than my code below :
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:#"http://MYADDRESS"]];
[manager setRequestSerializer:[AFHTTPRequestSerializer serializer]];
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:#"user" password:#"pass"];
NSData *imageData = UIImageJPEGRepresentation(image, 1);
NSDictionary *parameters = #{#"image" : imageData, #"name" : #"MyImage" , #"Content-Type" : #"image/jpeg"};
AFHTTPRequestOperation *op = [manager POST:#"/api/photo/" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:imageData name:#"MyImage" fileName:#"MyImage.jpg" mimeType:#"image/jpeg"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success: %# ***** %#", operation.responseString, responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %# ***** %#", operation.responseString, error);
}];
[op setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
NSLog(#"%f%% Uploaded", round(((float)totalBytesWritten / (float)totalBytesExpectedToWrite) * 100.));
}];
[op start];

Related

access the web service and send data using iOS Objective C

I have string objects and image stored in nsdata. How can i send it to a server by accessing the url? I have seen examples .but its not working.Can someone tell me
Thanks in Advance!!
You could use AFNetworking to easily send string and image to server using url.
Here is a link of tutorial how to use AFNetworking framework.
AFNetworking Tutorial
AFNetworking is the best way to do that. and there are so much tutorials out there.
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *params = #{#"username": _username.text,
#"password": passwordMD5
};
[manager POST:#"http://example.com/ws/test.php" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject); //This is the Response
}else{
//if you didnt get expected output then handle it here
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
//Handle any network errors here. ex: if internet disconnected.
}];
Here is an example how to upload an image with string objects as a dictionary to a server using AFNetworking.
- (void)uploadPhoto {
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:#"http://server.url"]];
NSData *imageData = UIImageJPEGRepresentation(self.avatarView.image, 0.5);
NSDictionary *parameters = #{#"username": self.username, #"password" : self.password};
AFHTTPRequestOperation *op = [manager POST:#"rest.of.url" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
//do not put image inside parameters dictionary as I did, but append it!
[formData appendPartWithFileData:imageData name:paramNameForImage fileName:#"photo.jpg" mimeType:#"image/jpeg"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success: %# ***** %#", operation.responseString, responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %# ***** %#", operation.responseString, error);
}];
[op start];
}

Uploading image to server (Objective C)

I try to send image as byte[] to server.
When I sent it from POST-MAN, like html will send files, it works.
But when I try to send from Objective C code, it sents different array of bytes:
+ (void)uploadPhoto:(UIImage*)photo withCompletionBlock:(responceBlock)block
{
AFHTTPRequestOperationManager* manager = [[AFHTTPRequestOperationManager alloc] init];
NSData* imageData = UIImageJPEGRepresentation(photo, 6);
[manager.requestSerializer setValue:[UserDefaultsHelper getToken] forHTTPHeaderField:#"X-AUTH-TOKEN"];
AFHTTPRequestOperation* op = [manager POST:#"http://localhost:8080/image/save"
parameters:#{}
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:imageData name:#"ParamFiles" fileName:#"photo2131231.jpg" mimeType:#"image/jpeg"];
}
success:^(AFHTTPRequestOperation* operation, id responseObject) {
NSLog(#"Success: %# ***** %#", operation.responseString, responseObject);
}
failure:^(AFHTTPRequestOperation* operation, NSError* error) {
NSLog(#"Error: %# ***** %#", operation.responseString, error);
}];
[op start];
}
Answer: Sorry for stupid question. Problem, that on server I handle just binary image. Objective C code send me multipart files, so it contains binary image with filename, mimetype and other fields. I converted everything to bytes and tried to save this like image. Of course server can't do that.
Try this out
+ (void)uploadPhoto:(UIImage*)photo withCompletionBlock:(responceBlock)block
{
AFHTTPRequestOperationManager* manager = [[AFHTTPRequestOperationManager alloc] init];
NSData* imageData = UIImageJPEGRepresentation(photo, 6);
[manager.requestSerializer setValue:[UserDefaultsHelper getToken] forHTTPHeaderField:#"X-AUTH-TOKEN"];
NSMutableURLRequest * request = [manager.requestSerializer
multipartFormRequestWithMethod:#"POST"
URLString:#"http://localhost:8080/image/save"
parameters:nil
constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
{
UIImage *image = [page.imageVersionObject imageForVersion:page.imageVersionObject.selectedVersion];
if (image) {
[formData appendPartWithFileData:UIImageJPEGRepresentation(image, (CGFloat)0.85)
name:#"file"
fileName:#"fileName.jpg"
mimeType:#"image/jpeg"];
}
}
error:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
//SUCCESS HERE!!!
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//FAILURE HERE
}];
[manager.operationQueue addOperation:operation];
}
Do not forget to use your filename and name.... I have used mine for testing

Multipart/form-data POST request gets timeout and is never sent using AFNetworking

I am posting a JPEG image with some textual data to my server using AFNetworking:
- (NSArray *)postPhoto:(NSData *)jpegData withRoomType:(NSString *)roomType andDescription:(NSString *)description {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_queue_t queue = dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0);
__block NSArray *returnedMetaData;
AFHTTPRequestOperation *operation = [self.requestManager POST:[Constants postPhotoURLString] parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
NSLog(#"Room: %#", roomType);
[formData appendPartWithFormData:[roomType dataUsingEncoding:NSUTF8StringEncoding]
name:#"room"];
NSLog(#"Description: %#", description);
[formData appendPartWithFormData:[description dataUsingEncoding:NSUTF8StringEncoding]
name:#"description"];
[formData appendPartWithFileData:jpegData
name:#"image"
fileName:#"photo.jpg"
mimeType:#"image/jpeg"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
returnedMetaData = (NSArray *)responseObject;
dispatch_semaphore_signal(semaphore);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"%#", error.description);
dispatch_semaphore_signal(semaphore);
}];
operation.completionQueue = queue;
[operation setUploadProgressBlock:^(NSUInteger __unused bytesWritten,
long long totalBytesWritten,
long long totalBytesExpectedToWrite) {
NSLog(#"Wrote %lld/%lld", totalBytesWritten, totalBytesExpectedToWrite);
}];
[operation start];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
return returnedMetaData;
}
Every request results in a timeout after 60 seconds:
Error Domain=NSURLErrorDomain Code=-1001 "Time-out van het verzoek." UserInfo=0x15d28d30
Judging from Wireshark, the POST request never even leaves the simulator, and Xcode indicates bandwidth usage is 0. Some other POST requests in my app work fine. Doing the exact same thing in curl as in the code above also works just fine.
Also I checked the URL and no trailing slashes are missing, whatsoever. Copy-pasting the URL to curl and doing a multipart/form-data request does produce the desired outcome.
Am I missing something here?
Thanks!
NSData *imageData = UIImageJPEGRepresentation(YOURIMAGE, 0.5);
NSDictionary * dicParamsToSend = #{#"room" : room,
#"description" : description };
AFHTTPRequestOperation *op = [manager POST:#"rest.of.url" parameters:dicParamsToSend constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
//do not put image inside parameters dictionary as I did, but append it!
[formData appendPartWithFileData:imageData name:#"image" fileName:#"photo.jpg" mimeType:#"image/jpeg"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success: %# <=> %#", operation.responseString, responseObject);
}failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %# <=> %#", operation.responseString, error);
}];
[op start];
This might helps you :)

How to Upload Images Using AFNetworking directly from iPad app

I am totally new to iOS.I want to upload images to my server using AFNetworking.
I tried it but it still not done. Please Help me, thanks in advance
try with this its work for me
-(void) uplodeImages{
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:#"url where to upload images"]];
    NSData *imageData = UIImagePNGRepresentation([UIImage imageNamed:#"cat1.png"]);
    NSDictionary *parameters = #{#"username": #"", #"password" : #""};
    AFHTTPRequestOperation *op = [manager POST:#"cat1.png" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        //do not put image inside parameters dictionary as I did, but append it!
        [formData appendPartWithFileData:imageData name:#"userfile" fileName:#"cat1.png" mimeType:#"image/png"];
    } success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(#"Success: %# ***** %#", operation.responseString, responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(#"Error: %# ***** %#", operation.responseString, error);
    }];
    [op start];
}

Uploading image with AFNetworking 2.0

I'm banging my head against the wall with this one. I want to select UIImage from library and upload it to server, like on could do with <form action="http://blabla.request.cfm" method="post" enctype="multipart/form-data">. Instead of success I got this error:
error = Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x145e5d90 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
I tried this way:
-(void)uploadPhoto{
NSString *path = #"http://blabla.request.cfm";
NSData *imageData = UIImageJPEGRepresentation(self.imageView.image, 0.9);
int priv = self.isPrivate ? 1 : 0;
NSDictionary *parameters = #{#"username": self.username, #"password" : self.password, #"private" : #(priv), #"photo" : imageData};
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:path parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
if(self.imageView.image){
[formData appendPartWithFileData:imageData name:#"avatar" fileName:#"avatar.jpg" mimeType:#"image/jpeg"];
}
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"[UploadVC] success = %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"[UploadVC] error = %#", error);
}];
[self blockView:self.view block:YES];
}
but it's not working... server says that there is no file. Not sure if encrypting is wrong, mime type or what?
Tried also this:
[manager POST:path parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"[UploadVC] success = %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"[UploadVC] error = %#", error);
}];
and this:
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager POST:path parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFormData:imageData name:#"photo"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"[UploadVC] success = %#", responseObject);
[self blockView:self.view block:NO];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"[UploadVC] error response.object = %#", operation.responseObject);
[self blockView:self.view block:NO];
}];
nothing is working. Hope someone can help, 'cause I'm stuck with it and circling from question to question here on SO
tia
EDIT: new attempt
1) first was multi-part form
2) creating upload task
none of them worked for me, so I'm still trying to cope with that, but cannot see any solution
I'm not sure which part (I think that some details were missing) was responsible, but I did it finally :) here you go:
-(void)uploadPhoto{
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:#"http://server.url"]];
NSData *imageData = UIImageJPEGRepresentation(self.avatarView.image, 0.5);
NSDictionary *parameters = #{#"username": self.username, #"password" : self.password};
AFHTTPRequestOperation *op = [manager POST:#"rest.of.url" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
//do not put image inside parameters dictionary as I did, but append it!
[formData appendPartWithFileData:imageData name:paramNameForImage fileName:#"photo.jpg" mimeType:#"image/jpeg"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success: %# ***** %#", operation.responseString, responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %# ***** %#", operation.responseString, error);
}];
[op start];
}
Works like a charm :)
You can upload an image with AFNetworking using Swift like this...
let compression = 0.5
let imageData = UIImageJPEGRepresentation("image", CGFloat(compression))
if imageData != nil{
var manager = AFHTTPRequestOperationManager()
manager.responseSerializer.acceptableContentTypes = NSSet(array: ["text/html", "application/json"]) as Set<NSObject>
var dictParams = [
"familyId":"10000",
"contentBody" : "Some body content for the test application",
"name" : "the name/title",
"typeOfContent":"photo"
]
let url = "http://...."
manager.POST(url, parameters: dictParams, constructingBodyWithBlock: { (formData: AFMultipartFormData!) -> Void in
//code
formData.appendPartWithFileData(imageData, name: "file", fileName: "filename", mimeType: "image/png")
}, success: { (operation:AFHTTPRequestOperation!, responseObject:AnyObject!) -> Void in
println(responseObject)
}, failure: { (operation:AFHTTPRequestOperation!, error:NSError!) -> Void in
println(error)
})
}
UIImage *image = [UIImage imageNamed:#"decline_clicked.png"];
NSData *imageData = UIImageJPEGRepresentation(image,1);
NSString *queryStringss = [NSString stringWithFormat:#"http://your server/uploadfile/"];
queryStringss = [queryStringss stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:#"text/html"];
[manager POST:queryStringss parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
{
[formData appendPartWithFileData:imageData name:#"fileName" fileName:#"decline_clicked.png" mimeType:#"image/jpeg"];
}
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSDictionary *dict = [responseObject objectForKey:#"Result"];
NSLog(#"Success: %# ***** %#", operation.responseString, responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error: %# ***** %#", operation.responseString, error);
}];

Resources