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.
Related
I am fetching JSON values from the API...but it showing the values as null... I checked it in the postman it's working there and I have the response...I have listed my sample code below please mention my mistakes. I'm new to this development
- (IBAction)PaymentButtonTapped:(id)sender {
[self PayuMoneyAdminValues];
}
-(void)PayuMoneyAdminValues{
NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc]init];
NSString *urlstring = [NSString stringWithFormat:#"%#admindatas",restSiteURLServices];
NSURL *url = [NSURL URLWithString:urlstring];
NSString *userUpdate = [NSString stringWithFormat:#"%#",restAuth];
[urlRequest setHTTPMethod:#"POST"];
[urlRequest setURL:url];
//Convert the String to Data
NSData *data1 = [userUpdate dataUsingEncoding:NSUTF8StringEncoding];
//NSData *data1 = [NSData dataWithContentsOfURL:url];
//Apply the data to the body
[urlRequest setHTTPBody:data1];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if(data!=nil){
NSError *parseError = nil;
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (parseError) {
NSLog(#"Admin data: %#",responseDictionary);
}
}
}];
[dataTask resume];
}
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.
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)
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
I'm attempting to communicate with a backend using NSURLSession, however, the backend wasn't set up to properly read NSData, so it views the NSData login details I send over as false, I wanna know if its possible to get NSURLSession to send raw strings rather than NSData objects. I've looked in books and the webs and I've been stumped for weeks.
Redoing the backend is not an option, the engineer in charge of that left. Any help is welcome.
Thanks. Here's what I've done so far, in case anyone needs to see some code.
NSError *error;
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration ];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];
NSString *rawUrlString = #"backend_url";
NSURL *url = [NSURL URLWithString:rawUrlString];
NSLog(#"%#", url);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:
login data here
nil];
//NSLog(#"%#", parameters);
NSData *rawJson = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:&error];
NSString *myString = [[NSString alloc] initWithData:rawJson encoding:NSUTF8StringEncoding];
NSData *finalData = [myString dataUsingEncoding:NSUTF8StringEncoding];
NSMutableData *body = [NSMutableData data];
[body appendData:finalData];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:body];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"charset"];
[request setValue:#"XMLHttpRequest" forHTTPHeaderField:#"X-Requested-With"];
NSURLSessionDataTask *postTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
NSLog(#"%#", [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]);
}];
[postTask resume];
`
UPDATE: I've cleaned up the unnecessary bits this is the final code (still doesn't work though)
NSError *error;
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration ];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];
NSString *rawUrlString = #"backend_url";
NSURL *url = [NSURL URLWithString:rawUrlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:login details nil];
NSData *rawJson = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:&error];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:rawJson];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSURLSessionDataTask *postTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
NSLog(#"%#", [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]);
}];
[postTask resume];
Your backend is setup to handle NSData. It's impossible to send a string over an internet connection, you can only send NSData and all servers expect it.
This code here is wrong:
NSData *rawJson = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:&error];
NSString *myString = [[NSString alloc] initWithData:rawJson encoding:NSUTF8StringEncoding];
NSData *finalData = [myString dataUsingEncoding:NSUTF8StringEncoding];
Instead just do this:
NSData *finalData = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:&error];
The NSData object will contain a string in the correct format for the server to also recognise as a string. Note it will be in UTF-8 encoding, perhaps on some servers you will want to change that to something else.