How to send base64 string through NSUrlSession IOS - ios

As I'm converting images to base64 string and uploading it to serer using NSURLSessionsDataTask for example-
NSString *encodedString = [[self encodeToBase64String:imgParcel]stringByReplacingOccurrencesOfString:#"+" withString:#"%2B"];
[self.package.arrParcelImages addObject:encodedString]
and sending it like this...
NSDictionary *postParameters = #{#"userID":#"1",#"images":self.package.arrParcelImages}
NSData *postData = [NSJSONSerialization dataWithJSONObject:postParameters options:NSJSONWritingPrettyPrinted error:&error];
NSString *dataString = = [[NSString alloc] initWithData:postData encoding:NSUTF8StringEncoding];
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request addValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request addValue:#"image/png" forHTTPHeaderField:#"Content-Type"];
NSString *strValue = [NSString stringWithFormat:#"%#",[USER_DEFAULTS objectForKey:UD_X_API_VALUE]];
if (strValue != nil) {
[request addValue:strValue forHTTPHeaderField:[USER_DEFAULTS objectForKey:UD_X_API_KEY]];
}
[request setHTTPMethod:#"POST"];
[request setHTTPBody:postData];
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *taskData, NSURLResponse *taskResponse, NSError *taskError) {
//NSLog(#"Start - Response:%# %#\n", taskResponse, taskError);
dispatch_async(dispatch_get_main_queue(), ^{
if (taskError) {
NSLog(#" Error = %#",[taskError localizedDescription]);
completionBlock(nil,taskError,task);
}
else {
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:taskData options:kNilOptions error:&error];
if (json) {
NSLog(#" JSON = %#",json);
}
else {
NSString* newStr = [[NSString alloc] initWithData:taskData encoding:NSUTF8StringEncoding];
NSLog(#"Error: %#",newStr);
}
completionBlock(json,nil,task);
}
});
}];
[postDataTask resume];
But This is not uploading base64 string to server what i'm doing wrong please help

If you're including the base64 image in JSON, you should not percent escape the + characters. You only do that if you are creating x-www-form-urlencoded requests.
So, do not replace the + characters with %2B.
You are setting the Content-Type header twice. Your request is JSON, so remove the image/png header. Some web services will just blithely assume the content type, but perhaps yours is getting confused by the incorrect Content-Type header.
If it's still not working, the problem could either be how you created the base64 rendition of the image or the request is not formatted correctly. It's hard to know without seeing (a) what the final request looked like; and (b) precisely what the server is looking for.

Related

How to send base64 string to server in iOS?

I am working in an application in which I have to send image to the server, I am trying to send Image to server but in return I am getting
BAD REQUEST 400
. Please tell me how do I resolve this error.
This method is use to convert image into base64 string
NSData * imagedata = UIImageJPEGRepresentation(chosenImage, 0.5);
NSString * base64String = [imagedata base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength
-(void)temp
{
NSString * str=[self base64return];
NSDictionary* jsonDict = #{
#"name": #"image_name",
#"img_data":str
};
NSData * postData = [NSJSONSerialization dataWithJSONObject:jsonDict
options:kNilOptions error:nil];
NSURL * url=[NSURL URLWithString:#"http://xxxxxx/finalresult1"];
NSMutableURLRequest *request=[[NSMutableURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:120.0];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
NSURLSessionDataTask* task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
if (error == nil)
{
// Success
NSLog(#"URL Session Task Succeeded: HTTP %ld", ((NSHTTPURLResponse*)response).statusCode);
NSString * text = [[NSString alloc] initWithData: data encoding:
NSUTF8StringEncoding];
NSLog(#"Data = %#",text);
NSLog(#"erroer is %#",error);
}
else
{
// Failure
NSLog(#"URL Session Task Failed: %#", [error localizedDescription]);
}
}];
[task resume];
}
Change request Content-Type, Use:
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];

POSTING DATA TO A WS

I'm trying to post new data to a ws but im geting error each time
I need to
1-pass a username and password each time
2-code the data with AES256 WITH THE API KEY
Code:
- (IBAction)AddTicket:(id)sender {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *URL = [[NSURL alloc] initWithString:#"http://dev.enano-tech.com/api/Ticket"];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:#"1",#"id",#"1",#"idProject",#"1",#"idTicketType",#"nameo",#"name",#"nameo",#"description", #"1",#"idStatus",#"2016-06-23 15:20:49",#"creationDateTime", nil];
NSData *dataToPost = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
NSData *final =[dataToPost AES256EncryptWithKey:#"02b6e206868660a0d59d2e51a11fdcd6"];
//
NSLog(#"postData1e == %#",final);
NSLog(#"final %#",dataToPost);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
[request setHTTPMethod:#"POST"];
[request addValue:#"CURLAUTH_BASIC" forHTTPHeaderField:#"CURLOPT_HTTPAUTH"];
[request addValue:#"Basic YWRtaW46YWRtaW5hZG1pbg==" forHTTPHeaderField:#"authorization"];
[request addValue:#"admin:adminadmin" forHTTPHeaderField:#"CURLOPT_USERPWD"];
[request addValue:#"true" forHTTPHeaderField:#"CURLOPT_RETURNTRANSFER"];
[request addValue:#"false" forHTTPHeaderField:#"CURLOPT_SSL_VERIFYPEER"];
[request addValue:#"POST" forHTTPHeaderField:#"CURLOPT_CUSTOMREQUES"];
[request addValue:#"true" forHTTPHeaderField:#"CURLOPT_POST"];
[request addValue:#"false" forHTTPHeaderField:#"CURLOPT_POSTFIELDS"];
[request setHTTPBody:final];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSString *result = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSString *str = [[NSString alloc]initWithData:final encoding:NSUTF8StringEncoding];
NSLog(#"data %#",data);
NSLog(#"respoce %#",response);
NSLog(#"result == %#",result);
}];
[postDataTask resume];
}
Response:
2016-08-02 15:06:47.768 Projector[3936:1619429] result == {"error":"invalid API query", "message":"'data' is not correctly encoded for method POST. Request for correct API KEY"}
this is the documentation of api:
enter image description here
Your webserver is missing "data" from the website. To fix it, you'll need to add that field to your form or find the correct field name (case sensitive)

Objective c post request not sending the data

Good day.Im trying to send simple post data to server.This is the code how i do it.
-(void)makeRequest:(NSString*)stringParameters{
NSError *error;
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSURL *url = [NSURL URLWithString:#"http://vaenterprises.webatu.com/Authentication.php"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
[request addValue:#"application/text" forHTTPHeaderField:#"Content-Type"];
[request addValue:#"application/text" forHTTPHeaderField:#"Accept"];
[request setHTTPMethod:#"POST"];
NSString* postData = #"tag=hello&username=yo&something=something";
[request setHTTPBody:postData];
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
[self parseJson:data];
}];
[postDataTask resume];
}
It looks great till i echo the whole post from php side like this
echo json_encode($_POST);
and i print the result in the iOS like this
-(void)parseJson:(NSData*) data{
NSString *myString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSError *jsonError = nil;
NSDictionary* jsonObject= [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
NSLog(#"%#",myString);
}
this issue is that i get empty string..so it means that post data not being send and that is 10000 percent objective c side issue and i have no clue why its so as in this method we only got setHttpBody with the actual string which contains key and value separated by & but that data not being send as you can see.So what am i doing wrong?Please tell somebody
Http body has to be of type NSData. Try out following code
NSString* stringData = #"tag=hello&username=yo&something=something";
NSData* data = [stringData dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:data];

POST base 64 image string to a server on iOS

To my understanding, to use this website I have to convert an image to a base64 encoded image and then send it to this website. The website will then send me back a number (as a decimal).
https://docs.indico.io/docs/rest-api-image-analysis
I've tried using a number of steps, namely trying to alter a similar process used for sending text and receiving a number. Any tips?
UPDATE:
- (IBAction)press:(id)sender {
//UIImage *imager = photos.image;
NSData *imageData = UIImageJPEGRepresentation(photos.image, 1.0);
NSString *base64Img = [imageData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
//not sure if #"data" or #"data.json" and whether the base64img should be behind it
NSDictionary *parameters = #{#"data":base64Img};
NSMutableString *parameterString = [NSMutableString string];
for (NSString *key in [parameters allKeys]) {
if ([parameterString length]) {
[parameterString appendString:#"&"];
}
[parameterString appendFormat:#"%#=%#", key, parameters[key]];
NSURL *url = [NSURL URLWithString:#"http://apiv2.indico.io/contentfiltering?key='17767cb46eb4b4f568832be2c953022b"];
NSURLSession *session = [NSURLSession sharedSession];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[parameterString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (!error) {
if ([data length]) {
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
//GET RESULT;
NSLog(#"A %#", parameters[#"results"]);
}
} else {
NSLog(#"%#", error);
}
}];
[task resume];
}
the results I get usually return as (null)
maybe try going
NSDictionary *parameters = #{#"data":base64Img};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameters
options:nil
error:&error];
//do some error checking
NSURL *url = [NSURL URLWithString:#"http://apiv2.indico.io/contentfiltering?key='17767cb46eb4b4f568832be2c953022b"];
NSURLSession *session = [NSURLSession sharedSession];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:jsonData];
//...
just doing this off the top of my head so may need some tweaking
If I had to guess it looks like you've accidentally added a typo to your API key. In the line above:
http://apiv2.indico.io/contentfiltering?key='17767cb46eb4b4f568832be2c953022b
should instead read:
http://apiv2.indico.io/contentfiltering?key=17767cb46eb4b4f568832be2c953022b
Since URL parameters are sometimes quoted and I'm not extremely familiar with objective-c's internal request handling I would guess that that is leading to the strange behavior you're seeing.

iOS Today Extension POST request to Google Directions API

I don't know whether I missed something obvious or not but what should appear correct is not working. Maybe I need a pair of fresh eyes ?
I am testing Today Extension (widget) for one of my app and in this widget, I am trying to make a request to Google Directions API.
My normal app itself has no problem making and receiving the request but the widget itself is not playing right.
In my normal app, I'm using AFNetworking but AFNetworking has some problems with [UIApplication sharedApplication] not being accessible inside a widget, so I am resorting to using NSURLSession to make my POST request:
NSError *error;
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSString *directionsURL = [#"https://maps.googleapis.com/maps/api/" stringByAppendingString:#"directions/json"];
NSURL *url = [NSURL URLWithString:directionsURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
[request addValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request addValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setHTTPMethod:#"POST"];
// ------------------------------------------------------------------
// setup params
// ------------------------------------------------------------------
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
NSString *strOrigin = [[NSString alloc] initWithFormat:#"%lf,%lf", fromLocation.latitude, fromLocation.longitude];
NSString *strDestination = [[NSString alloc] initWithFormat:#"%lf,%lf", toLocation.latitude, toLocation.longitude];
[params setValue:strOrigin forKey:#"origin"];
[params setValue:strDestination forKey:#"destination"];
[params setValue:#"transit" forKey:#"mode"];
[params setValue:#"true" forKey:#"alternatives"];
NSString *GoogleAPIBrowserKey = [[NSBundle mainBundle] objectForInfoDictionaryKey:#"GoogleAPIBrowserKey"];
[params setValue:GoogleAPIBrowserKey forKey:#"key"];
[params setValue:#"fewer_transfers" forKey:#"transit_routing_preference"];
DLog(#"widget params = %#", params);
NSData *postData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
if(error)
{
DLog(#"error setting up PostData: %#", error.localizedDescription);
}
[request addValue:[NSString stringWithFormat:#"%d", postData.length] forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if(error)
{
DLog(#"Widget Error requesting route: %#", error.localizedDescription);
}
else
{
NSError *jsonError = nil;
NSDictionary* responseDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];
if(error)
{
DLog(#"Error converting widget response data: %#", error.localizedDescription);
}
DLog(#"Widget Google Response = %#", responseDict);
}
}];
[postDataTask resume];
My Xcode console outputs the following:
widget params = {
alternatives = true;
destination = "-31.834382,115.804225";
key = **********************;
mode = transit;
origin = "-31.833961,115.806565";
"transit_routing_preference" = "fewer_transfers";
}
Widget Google Response =
{
"error_message" = "Invalid request. Missing the 'origin' parameter.";
routes = (
);
status = "REQUEST_DENIED";
}
Which leads me to believe the HTTP Body of my request is lost somehow during the network request operation. How can 'origin' be missing when the log shows it as part of my params dictionary ?
I've tried po data to see if the data variable was nil but it was not nil.
I'm scratching my head over this one. If anyone can see where I've gone wrong and point it out to me, I'll be one happy chap.
Why do I always do this to myself ?
Short Answer
Use GET Request lad, not POST.
Long Answer
Went for a walk, came back home, 1 hour later. Problem solved.
Upon looking at my normal app version of my code that uses AFNetworking, I realised my noobness mistake.
I was using POST request in my Today Extension when I should be using GET request like how I was doing it in my AFNetworking code.
For that reason, the new params needs to be URL encoded instead of being part of HTTP Body, so new code is now:
NSError *error;
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
// ------------------------------------------------------------------
// setup URL params
// ------------------------------------------------------------------
NSMutableString *urlParams = [[NSMutableString alloc] initWithString:#"?"];
NSString *strOrigin = [[NSString alloc] initWithFormat:#"%lf,%lf", fromLocation.latitude, fromLocation.longitude];
NSString *strDestination = [[NSString alloc] initWithFormat:#"%lf,%lf", toLocation.latitude, toLocation.longitude];
NSString *GoogleAPIBrowserKey = [[NSBundle mainBundle] objectForInfoDictionaryKey:#"GoogleAPIBrowserKey"];
[urlParams appendFormat:#"origin=%#&destination=%#&mode=transit&alternatives=true&key=%#&transit_routing_preference=fewer_transfers", strOrigin, strDestination, GoogleAPIBrowserKey];
NSString *directionsURL = [[NSString alloc] initWithFormat:#"https://maps.googleapis.com/maps/api/%#%#", #"directions/json", urlParams];
NSURL *url = [NSURL URLWithString:directionsURL];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:#"GET"];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if(error)
{
DLog(#"Widget Error requesting route: %#", error.localizedDescription);
}
else
{
NSError *jsonError = nil;
NSDictionary* responseDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];
if(jsonError)
{
DLog(#"Error converting widget response data: %#", error.localizedDescription);
}
DLog(#"Widget Google Response = %#", responseDict);
}
}];
[dataTask resume];
Terribad. I'm sorry, I've been staring at the screen for hours today :D

Resources