I am new on iOS development. I try to send POST JSON to my RoR server.
It is my code:
params - some NSDictionary -> { uid = 123 }
NSData *postData = [NSJSONSerialization dataWithJSONObject:params
options:NSJSONWritingPrettyPrinted error:&jsonSerializationError];
NSString *urlString = [[NSString alloc] initWithFormat:#"%#%#", API_URL, url];
NSURL *nsUrl = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:nsUrl];
[request setHTTPMethod:#"POST"];
[request setValue:[NSString stringWithFormat:#"%lu",
(unsigned long)postData.length] forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
At the end in the server I see:
{"uid"=>"123",
"action"=>"mAction",
"controller"=>"mController",
"token"=>{"uid"=>"123"}}
Why I see 'extra token' and how I can remove it ?
there is no reason I can see for the extra "token" to be there, so I would suggest that either the token was in the param all along, or that the receiving script (PHP?) on the server is adding the data someway.
I would suggest you to print the content of parameter with
NSLog(#"param: %#", param);
just to be sure, and also convert the postData to a NSString with something like:
NSString *myString = [[NSString alloc] initWithData:postData encoding:NSUTF8StringEncoding];
and print that too, just to be on the safe side and, once you have make certain that you aren't sending the "token" parameter, start to debug the receiving end.
Hope this helps
It is a magic problem with a NSDictionary. When I send as NSMutableString - no problems.
NSMutableString *stringData = [[NSMutableString alloc] init];
[params enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
[stringData appendString:[NSString stringWithFormat:#"%#=%#", key, value]];
[stringData appendString:[NSString stringWithFormat:#"&"]];
}];
NSData *postData = [stringData dataUsingEncoding:NSUTF8StringEncoding];
I don't know what happens and why :(
Related
I am developing an iOS app which required to send phone number on server.
When I pass number without "+" it is work fine, but when I pass number with "+" sign (+123456, +234567) then it send number like (" 123456"," 234567").
It replace "+" by " " (space).
I convert NSDictionary into JsonData .
NSError *err;
NSData *data=[NSJSONSerialization dataWithJSONObject:mdict options:0 error:&err];
NSString *str=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSString *strjson=[NSString stringWithFormat:#"GetData=%#",str];
NSLog(#"strjson=%#",strjson);
My code to build NSMutableRequest object.
NSURL *url = [NSURL URLWithString:urlString];
__weak NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[soadMessage length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:[soadMessage dataUsingEncoding:NSUTF8StringEncoding]];
[request addValue: #"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField: #"Content-Type"];
_connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
[_connection start];
Any help will be appreciated.
Try to escape your string with the CFURLCreateStringByAddingPercentEscapes
+ (NSString *)escapeValueForURLParameter:(NSString *)valueToEscape {
if (![valueToEscape isKindOfClass:[NSString class]]) {
valueToEscape = [(id)valueToEscape stringValue];
}
return (__bridge_transfer NSString *) CFURLCreateStringByAddingPercentEscapes(NULL, (__bridge CFStringRef) valueToEscape,
NULL, (CFStringRef) #"!*'();:#&=+$,/?%#[]", kCFStringEncodingUTF8);
}
You need to format the value of mdict to take out the + character. Or you could also trim it from the JSON at the end. Either way you will get the desired result.
Something like this:
mdict["Phone"].value = [mdict["Phone"].value stringByReplacingOccurrencesOfString:#"+"
withString:#""];
This is pseudocode but you get the idea. After doing this you can do the serialization and it should be fine.
I'm new to iOS and i'm using the following code to make API Calls.
-(NSData *)sendDataToServer:(NSString*)url :(NSString*)params
{
NSString *postDataString = [params stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"postDataString :%#",postDataString);
NSData *postData = [postDataString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d",[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
NSString *urlReq = [NSString stringWithFormat:#"%#", url];
[request setURL:[NSURL URLWithString:urlReq]];
[request setTimeoutInterval:180];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"response in Server: %#",responseString);
return responseData;
}
I'm sending the following string as params to the above method. If I send the following data without special characters, I'm getting the success response.
If i Add any special charters as like (&) with json I'm always getting the invalid response, that is the server always returns null.
So Can anyone please provide any suggestion to get the right response when using json string with Special characters like '&' etc.,
submited_data={"safty_compliance_fields":[{"safty_compliance_id":"641","fieldName":"sc1","fieldType":"editText","fieldValue":"wedgies Ig"},{"safty_compliance_id":"642","fieldName":"sc2","fieldType":"editText","fieldValue":"het &"}],"status_id":"2","product_detail":[{"dynamic_fields_id":"639","fieldName":"p1","fieldType":"editText","fieldValue":"data1"},{"dynamic_fields_id":"640","fieldName":"p2","fieldType":"editText","fieldValue":"data2"}],"inspection_id":"3","second_level":[{"questions":[{"checkListValue":"NO","checkListCommentValue":"Jgkjgjkj","sub_category_id":"452","checkListName":"sl1"},{"checkListValue":"YES","checkListCommentValue":"jk","sub_category_id":"453","checkListName":"sl2"},{"checkListValue":"YES","checkListCommentValue":"gh","sub_category_id":"455","checkListName":"sl3"},{"checkListValue":"YES","checkListCommentValue":"nm","sub_category_id":"456","checkListName":"sl4"}],"title":"sl1","entity_second_level_entry_id":"130"},{"questions":[{"checkListValue":"YES","checkListCommentValue":"Bonn","sub_category_id":"454","checkListName":"s22"}],"title":"s211","entity_second_level_entry_id":"131"}],"comment":"Jgkjgjkj","status":"Ongoing"}
You didn't post the percent encoded string, but the original string.
This might be a repeated question but I can't find anything about what is wrong about it, I have been trying to generate a session via QuickBlox's rest API, it has consumed 5 days but I can't get it through. Please help me out
Setting the body
NSString *strNonceValue = [NSString stringWithFormat:#"%d", arc4random() % 1000000];
NSString *timeStampValue = [NSString stringWithFormat:#"%ld", (long)[[NSDate date] timeIntervalSince1970]];
NSMutableDictionary *dictSessionInfo = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
applicationID, #"application_id",
_pAuthorizationKey, #"auth_key",
timeStampValue, #"timestamp",
strNonceValue, #"nonce", nil];
NSString *signature = [self generateSignatureWithText:dataVal andKey:_pAuthorizationKey];
[dictSessionInfo setObject:signature forKey:#"signature"];
NSData *data = [NSJSONSerialization dataWithJSONObject:dictSessionInfo options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
Getting Signature
- (NSString *)generateSignatureWithText:(NSData *)data andKey:(NSString *)secret {
NSData *secretData = [secret dataUsingEncoding:NSUTF8StringEncoding];
NSData *clearTextData = data;
uint8_t digest[CC_SHA1_DIGEST_LENGTH] = {0};
CCHmacContext hmacContext;
CCHmacInit(&hmacContext, kCCHmacAlgSHA1, secretData.bytes, secretData.length);
CCHmacUpdate(&hmacContext, clearTextData.bytes, clearTextData.length);
CCHmacFinal(&hmacContext, digest);
NSData *result = [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
NSString *hash = [result description];
hash = [hash stringByReplacingOccurrencesOfString:#" " withString:#""];
hash = [hash stringByReplacingOccurrencesOfString:#"<" withString:#""];
hash = [hash stringByReplacingOccurrencesOfString:#">" withString:#""];
return hash;
}
Generating URLRequest
requestURL = [requestURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url=[NSURL URLWithString:requestURL];
NSString *postLength=#"";
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setTimeoutInterval:60];
[request setURL:url];
NSLog(#"HTTP body Fields : %#", combinedDataStr);
if([requestType isEqualToString:#"POST"]) {
NSData *postData = [combinedDataStr dataUsingEncoding:NSASCIIStringEncoding
allowLossyConversion:YES];
postLength = [NSString stringWithFormat:#"%ld", (unsigned long)[postData length]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
}
else
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"0.1.0" forHTTPHeaderField:#"QuickBlox-REST-API-Version"];
The response I am receiving is :
response dict : {
errors = {
base = (
"Unexpected signature"
);
};
}
Please look into this and let me know what I am doing wrong
Same issue I have faced. I have tried to solve this issue please try below step
Uninstall
pod 'QuickBlox'
Reinstall Quickblox pod file it will take Latest framework and Rebuild projects,
You will see the magic of this issue by solved :)
Please let me know above steps are worked for you?
Thanks
As far as I understand, the problem is with this line
NSString *signature = [self generateSignatureWithText:dataVal andKey:_pAuthorizationKey];
you use auth key to create a signature, but you should pass here secret key
so, try to replace _pAuthorizationKey with secret key
Currently I have a string that I want to POST to a URL.
It works perfectly fine except when it encounters special characters like "&", and "?". It will not POST any data that comes after that. For example, if I have a string "I am something & something?", it will only POST "I am something". As for "?", it will be converted to '2' after it has been posted.
reason = 'What see see! Are you sure'2''
I am pretty sure that it must have something to do with encoding as I can see "I am something & something?" as it is just before I set the encoding:
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding];
I have also tried the encodings below with no success:
NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding];
NSData *postData = [post dataUsingEncoding:NSNonLossyASCIIStringEncoding];
NSData *postData = [post dataUsingEncoding:NSISOLatin1StringEncoding];
Below are my codes from postData onwards:
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding];
//NSLog(#"PostData: %#", postData);
NSString *check = [[NSString alloc] initWithData:postData encoding:NSASCIIStringEncoding];
NSLog(#"check string = %#", check);
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:strURLQueryString]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
NSURLResponse *response;
NSError *err=nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSString *strResponse = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"Response: %#", strResponse);
if(err!=nil) {
NSLog(#"Error: %#", [err description]);
}
Please assist.
Your help(s) are appreciated.
There's probably a better answer out there somewhere, but this class extension has been working for me for awhile. I cobbled together the % escapes by looking at a few posts...
// NSString+URLEncoding.h
#interface NSString (NSString_URLEncoding)
- (NSString *)urlEncodeUsingEncoding:(CFStringEncoding)encoding;
- (NSString *)urlEncode;
#end
// NSString+URLEncoding.m
#implementation NSString (NSString_URLEncoding)
- (NSString *)urlEncodeUsingEncoding:(CFStringEncoding)encoding {
return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(__bridge CFStringRef)self,
NULL,
CFSTR("!*'();:#&=+$,/?%#[]"),
encoding));
}
- (NSString *)urlEncode {
return [self urlEncodeUsingEncoding:kCFStringEncodingUTF8];
}
Then in somer other class to send a string...
// SomeOtherClass.m
#import "NSString+URLEncoding.h"
NSString *encodedString = [#"This & this? are 'challenging' to !% encode" urlEncode];
In calling apexrest webservice for uploading attachment to specific record by calling method. So for this I hardcoded Json.
-(void)uploadToSalesforce
{
NSData *imagedata = UIImageJPEGRepresentation(imagePreview.image, 1.0);
int datalength = [imagedata length];
NSString *filename = [NSString stringWithFormat:#"Supload_iPhone_%d.jpg",datalength];
NSString *req = [NSString stringWithFormat:#"{\n\"name\":\"%#\",\n\"Body\": \"%#\"\n,\"ParenId\":%#\"\n}",filename,imagedata,receivedrecordid];
const char *utfString = [req UTF8String];
NSData *postData = [NSData dataWithBytes:utfString length:strlen(utfString)];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *requestUrl = [[NSMutableURLRequest alloc] init ];
[requestUrl setURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#/services/apexrest/Account/",receivedinstanceurl]]];
[requestUrl setHTTPMethod:#"POST"];
[requestUrl setValue:postLength forHTTPHeaderField:#"Content-length"];
[requestUrl setValue:[NSString stringWithFormat:#"Bearer %#",receivedaccesstoken] forHTTPHeaderField:#"Authorization"];
[requestUrl setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[requestUrl setHTTPBody:postData];
NSURLResponse *response;
NSError *err;
NSData *reponseData = [NSURLConnection sendSynchronousRequest:requestUrl returningResponse:&response error:&err];
NSString *res = [[NSString alloc] initWithData:reponseData encoding:NSASCIIStringEncoding];
}
In response it says there is
[{"message":"Unexpected parameter encountered during deserialization: Name at [line:2, column:9]","errorCode":"JSON_PARSER_ERROR"}]
In console JSON seems correct but cannot parse parameter "Name".I think this is not by IOS code. Or is there some different format.
In the line
NSString *req = [NSString stringWithFormat:#"{\n\"name\":\"%#\",\n\"Body\": \"%#\"\n,\"ParenId\":%#\"\n}",filename,imagedata,receivedrecordid];
JSON is missing " character for ParentId key value. It should be:
NSString *req = [NSString stringWithFormat:#"{\n\"name\":\"%#\",\n\"Body\": \"%#\"\n,\"ParenId\":\"%#\"\n}",filename,imagedata,receivedrecordid];
Therefore Salesforce webservice deserialization was throwing exception.