Send UIImage POST to server from UIImagePickerController? - ios

I am trying to send a UIImage take with the UIImagePickerController to a server POST along with other pertinent values. But I get at the line that tries to set the dictionary value #"image" to UIImageJPEGRepresentation(image, 1.0):
-(void)sendImageToServer:(UIImage *)image
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 4;
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration] delegate:nil delegateQueue:queue];
NSURL *uploadURL = [NSURL URLWithString:#"http://...."];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:uploadURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:30.0];
[request addValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setHTTPMethod:#"POST"];
NSData *postData = [[NSData alloc] init];
[postData setValue:UIImageJPEGRepresentation(image, 1.0) forKey:#"image"];
[postData setValue:#"1" forKey:#"categories[0]"];
[postData setValue:#"4" forKey:#"categories[1]"];
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request
fromData:postData
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (!error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse.statusCode == 200) {
dispatch_async(dispatch_get_main_queue(), ^{
NSError *err;
NSDictionary *JSONDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&err];
NSLog(#"HTTP 200 response: %#", JSONDict);
});
} else {
NSLog(#"HTTP %ld status!", (long)httpResponse.statusCode);
}
} else {
NSLog(#"HTTP post image error: %#", error);
}
}];
[uploadTask resume];
}
JSON serialization does not work here, because images are not valid JSON values. If on the other hand I try:
...
NSMutableData *postData = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:postData];
[archiver encodeObject:UIImageJPEGRepresentation(image, 1.0) forKey:#"image"];
[archiver encodeObject:#"1" forKey:#"categories[0]"];
[archiver encodeObject:#"4" forKey:#"categories[1]"];
[archiver finishEncoding];
//NSData *postData = [NSJSONSerialization dataWithJSONObject:dataDict options:NSJSONWritingPrettyPrinted error:&jsonError];
//Now you can post the json data
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request
fromData:postData
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {...
The key:value pairs archived do not seem to get to the server as such. This must be a routinely iOS coding task.
Even if I just try:
NSError *jsonError;
NSData *postData = [NSJSONSerialization dataWithJSONObject:#{#"image":#"123",#"categories[0]":#"1",#"categories[1]":#"4"} options:NSJSONWritingPrettyPrinted error:&jsonError];
The server does not get any keys at all...

That's not the proper usage of NSData. It's crashing right now because NSData does not have key named image (..or the other two after that). What you need to do is create an NSDictionary and then convert that to NSData.
Do something like this instead:
NSDictionary *dictionary = [NSDictionary alloc]initWithObjectsAndKeys:image,#"image",#(1),#"categories[0]",#(4),#"categories[1]", nil];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:dictionary]; //Not currently using NSJSONSerialization since you want to post a Dictionary with an invalid NSJSONSerialization type in it.
//Now you can post the json data

Give a try with AFNetworking, it have a great way to make uploads, you can find the samples here: https://github.com/AFNetworking/AFNetworking#creating-an-upload-task
I personally recommend everyone to use it, since I started to use I didn't have any trouble to communicate my apps with webservers.

Use AFNetworking and the multi-part form post. Here is a rough example (note I am passing in a block so your implementation will vary):
AFHTTPRequestOperation *operation = [self POST:FullURLString parameters:Params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:fileData name:fileName fileName:fileName mimeType:mimeType];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSData *responseData = [operation responseData];
id retObj;
NSError *error = nil;
if (responseData) {
retObj = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];
}
// Pass back the serialized object (either an NSArray of type NSDictionaries or an NSArray of type customClass)
block(retObj);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failed with error = [Error]: %#", error);
block(nil);
}];

Related

How to post string data to API

I wanted to post a string data to API, I try to send it to server by using the below code. I've check api there by using the postman, it did not pass in the string data into the server. I do not know what is the problem and need help on this.
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:reqURLStr]];
[request setHTTPMethod:#"POST"];
**//Pass The String to server**
NSString *userUpdate =[NSString stringWithFormat:#"service_type=%#&ParcelSize=%#&ReceiverName=%#&MobileNumber=%#&Email=%#&DropOffHub=%#&PickupHub=%#" ,serviceType,pSize,rName,rMobile,rEmail,dropHubID,pickHubID];
NSData *data1 = [userUpdate dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:data1];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:[data makeRestAPICall:reqURLStr] forHTTPHeaderField:#"Authorization"];
NSError *err;
NSURLResponse *response;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSString *resSrt = [[NSString alloc]initWithData:responseData encoding:NSASCIIStringEncoding];
NSLog(#"got response==%#", resSrt);
if(resSrt)
{
NSLog(#"got response");
}
else
{
NSLog(#"fail to connect");
}
return resSrt;
Simple answer
-(void)postJsonDataToServer{
NSDictionary *parameters = #{
#"service_type": serviceType,
#"ParcelSize": pSize,
#"ReceiverName": rName,
#"MobileNumber": rMobile,
#"Email" : rEmail,
#"DropOffHub" : dropHubID,
#"PickupHub" : pickHubID
};
NSData *data = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http:/api/order/add"]];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json;charset=UTF-8" forHTTPHeaderField:#"content-type"];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSURLSessionUploadTask *dataTask = [session uploadTaskWithRequest: request
fromData:data completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if(data != nil)
{
NSError *parseError = nil;
//If the response is in dictionary format
NSDictionary *res = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
//OR
//If the response is in array format
NSArray *res = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
NSLog(#"The res is - %#",res);
}
else
NSLog(#"Data returned the parameter is nil here");
}];
[dataTask resume];
}

AFNETWORKING 3.0 Data Parameter Nil Error

I am getting the JSON back that I need, then I segue to another view controller to populate the data into a table view. The data populates, but the app crashes 2 minutes later with a data parameter is nil error.
Is there a way for me to stop the session from running after it completes? It appears to keep running non stop.
My header and implementation file code on pasteBin: https://pastebin.com/M11EF7Yp
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSDictionary *body = #{#"search": self.searchBar.text};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:body options:0 error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSString *url = #"https://iosdevfitbody.herokuapp.com/fitbodylocations/search.json";
NSMutableURLRequest *request = [[AFJSONRequestSerializer serializer] requestWithMethod:#"POST" URLString:url parameters:nil error:nil];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:[jsonString dataUsingEncoding:NSUTF8StringEncoding]];
[[manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if (!error) {
if ([responseObject isKindOfClass:[NSDictionary class]]) {
self.results = [[NSMutableArray alloc] initWithArray:[responseObject objectForKey: #"message"]];
}
} else {
NSLog(#"Error: %#, %#, %#", error, response, responseObject);
}
}]resume];

How to add Dictionary as a Request Parameter For HTTPBody in NSJSONSerialization?

I am creating one demo Web Services Code without using AFNetworking Framework.
My HTTP Request Parameter in Dictionary.
How can I set it on HTTPBody?
MY Code is as follow
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl];
[request setHTTPMethod:#"POST"];
NSString *postString = "Request Parameter";
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
// NSLog(#"requestReply: %#", requestReply);
NSError *jsonError;
NSData *objectData = [requestReply dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:objectData
options:NSJSONReadingMutableContainers
error:&jsonError];
NSLog(#"requestReply: %#", json);
}] resume];
You Can Do like that With AFnetworking and Without Af Networking.
NSString *stringUrl = #"xxx";
NSURLSessionConfiguration *myConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFHTTPSessionManager *myManager = [[AFHTTPSessionManager alloc]initWithSessionConfiguration:myConfiguration];
AFHTTPResponseSerializer *mySerilizer = [[AFHTTPResponseSerializer alloc]init];
[myManager setResponseSerializer:mySerilizer];
NSDictionary *param = [[NSDictionary alloc]initWithObjectsAndKeys:#"value==",#"Token", nil];
NSData *data = [NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingPrettyPrinted error:nil];
NSString *string = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *requestParameter = [NSDictionary dictionaryWithObject:string forKey:#"request"];
[manager POST:stringUrl parameters:requestParameter progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSError *error;
if(!error)
{
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:&error];
NSLog(#"%#",dict);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];
Without Dictionary
NSString *urlString = #"xxxx";
// Do any additional setup after loading the view, typically from a nib.
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithSessionConfiguration:configuration];
AFHTTPResponseSerializer *serilizer = [[AFHTTPResponseSerializer alloc]init];
[manager setResponseSerializer:serilizer];
NSDictionary *dict = [[NSDictionary alloc]initWithObjectsAndKeys:#"value",#"key", nil];
[manager POST:urlString parameters:dict progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSError *error;
if(!error)
{
NSDictionary *finalData = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:&error];
NSLog(#"Final Data is %#",finalData);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];
Without AFNetworking
NSString *MyUrlString = #"xxxx";
NSURL *url = [NSURL URLWithString:MyUrlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
NSString *postString = #"key=value";
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSError *jsonError;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&jsonError];
NSLog(#"requestReply: %#", json);
}] resume];
Note:-Do not forget to put resume
Thank you
Check your condition with my working code,
NSMutableURLRequest *_request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:URL]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:50.0];
[_request addValue:#"application/json" forHTTPHeaderField:#"Content-Type"]; // Interact your backend developer for header
[_request addValue:#"application/json" forHTTPHeaderField:#"Accept"];// Interact your backend developer for header
[_request setHTTPMethod:#"POST"];
NSError *error;
NSData *_inputData = [NSJSONSerialization dataWithJSONObject:inputDictionary options:0 error:&error];
[_request setHTTPBody:_inputData];
NSURLSessionDataTask *_fetchData = [[[self class] session] dataTaskWithRequest:_request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if(!error) {
NSError* error;
completionBlock(data,error,1);
} else {
completionBlock(data,error,0);
}
}];
[_fetchData resume];
Got The Data
NSURL *stringwithUrl = [NSURL URLWithString:#"XXXX"];
NSMutableURLRequest *requestUrl = [NSMutableURLRequest requestWithURL:stringwithUrl];
[requestUrl setHTTPMethod:#"POST"];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:#"Value==",#"Key", nil];
NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
NSString *mainString = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSString *requestString = #"request=";
NSString *finalString = [requestString stringByAppendingString:mainString];
[requestUrl setHTTPBody:[finalString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSession *sesion = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[sesion dataTaskWithRequest:requestUrl completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSLog(#"%#",dict);
}]resume];

Post Image Using multiPart To URL

Actually i have json parameter
[dictionary setObject:_dateOfBirth.text forKey:#"birth_date"];
[dictionary setObject:_tfCountry.text forKey:#"country"];
[dictionary setObject:_tfEmail.text forKey:#"email"];
[dictionary setObject:#"" forKey:#"fromLogin"];
[dictionary setObject:#1 forKey:#"gender"];
[dictionary setObject:#"signup" forKey:#"methodName"];
[dictionary setObject:_tfContact.text forKey:#"mobile"];
[dictionary setObject:_tfName.text forKey:#"name"];
[dictionary setObject:_tfNickName.text forKey:#"nickname"];
[dictionary setObject:_tfPassword.text forKey:#"password"];
[dictionary setObject:_tfPinCode.text forKey:#"pincode"];
There Is also a Image that i have to set profile_pic as a Key.
Now I have Converted all Parameter as a data and POst That Data lie This
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:kNilOptions error:nil];
// this is your service request url
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://proteen2.inexture.com/webservice"]];
// set the content as format
[request setHTTPMethod:#"POST"];
[request setHTTPBody: jsonData];
// this is your response type
[request setValue:#"application/json;charset=UTF-8" forHTTPHeaderField:#"content-type"];
NSError *err;
NSURLResponse *response;
// send the synchronous connection
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
// here add your server response NSJSONSerialization
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:responseData options: NSJSONReadingMutableContainers error: &err];
It's Works fine for Text, Now how to attach Image to that Parameter, I am only aware with Multi Part but not getting that Point. Please Help
You need to manage many thing here, like set boundry append image data etc etc.
You should use AFNetworking to make is very simple. Download from github and just drag and drop library to your project and import AFNetworking.h in your class and then you can do something like,
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer]multipartFormRequestWithMethod:#"POST" URLString:#"urlstring" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
//Append image here for example;
UIImage *img = tempImageView.image;
NSData *imgData = UIImageJPEGRepresentation(img, 0.5);
[formData appendPartWithFileData:imgData name:#"imagename/serversideparameter" fileName:#"imagename" mimeType:#"image/jpeg"];
} error:nil];
//Send this request to server. Something like,
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc]initWithSessionConfiguration:configuration];
[[manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if (!error) {
NSLog(#"success!!");
NSLog(#"here is the response : %#",responseObject);
}
else{
NSLog(#"Error Occured : %#",error.localizedDescription);
}
}]resume];
You shouldn't use NSUrlConnection because it is deprecated now. It's better to use NSUrlSession which i have used in answer via AFNetworking.
If you don't want to use AFNetworking then refer this stackoverflow post. It have great explanation step by step in answer.

How to Post JSON Data in synchronously way?

How to post JSON Data in synchronously way? Can use NSURLSession or AFNetworking or other way?
Sample basic code for posting data to server using synchronous
//PASS YOUR URL HERE
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"your URL"]];
//create the Method "POST" for posting data to server
[request setHTTPMethod:#"POST"];
//Pass The String to server like below
NSString *strParameters =[NSString strin gWithFormat:#"user_email=%#&user_login=%#&user_pass=%#& last_upd_by=%#&user_registered=%#&",txtemail.text,txtuser1.text,txtpass1.text,txtuser1.text,datestr,nil];
//Print the data that what we send to server
NSLog(#"the parameters are =%#", strParameters);
//Convert the String to Data
NSData *data1 = [strParameters dataUsingEncoding:NSUTF8StringEncoding];
//Apply the data to the body
[request setHTTPBody:data1];
//Create the response and Error
NSError *err;
NSURLResponse *response;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSString *resSrt = [[NSString alloc]initWithData:responseData encoding:NSASCIIStringEncoding];
//This is for Response
NSLog(#"got response==%#", resSrt);
if(resSrt)
{
NSLog(#"got response");
}
else
{
NSLog(#"faield to connect");
}
In user3182143's answer, sendSynchronousRequest is deprecated in latest version iOS 9.
You can use NSURLSession
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:londonWeatherUrl]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
NSString *strResult = [[NSString alloc]initWithData:data encoding:NSASCIIStringEncoding];
}] resume];
Here is my solution:
- (IBAction)postJSONSynchronization:(id)sender {
__block BOOL success = NO;
__block NSDictionary *jsonDic = nil;
NSURLSession *session = [NSURLSession sharedSession];
// 创建请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.url]];
request.HTTPMethod = #"POST"; // 请求方法
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
[parameters setObject:#13577766655 forKey:#"phoneNumber"];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];
request.HTTPBody = jsonData; // 请求体
NSCondition *condition = [[NSCondition alloc] init];
// 创建任务
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(#"Child Thread:%#",[NSThread currentThread]);
if (!error) {
jsonDic = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
success = YES;
} else {
NSLog(#"%#",error);
}
[condition lock];
[condition signal];
[condition unlock];
}];
[task resume];
// 启动任务
NSLog(#"Main Thread:%#",[NSThread currentThread]);
[condition lock];
[condition wait];
[condition unlock];
NSLog(#"测试时机");
NSLog(#"josnDic:%#",jsonDic);}

Resources