I have been learning objective-C for a few months now. In that time i have been able to do a basic post request however i saw today a header of a post request that contains a nested dictionary. I am not sure how to pass data to such an API.
My question is how can i go about posting data to this API. I would appreciate if you could point to relevant reading material and tutorials with examples such as this complex API requests or give answers.
The API header looks like this:
{ "header":
{ "id": "2312b24c-5b83-46f0-8670-5edc2b1d1672",
"parentId": "3gyy-w325e-bebd-ddsfsdf",
"countryCode": "IRELAND",
"timestamp": "2017-10-13T08:39:14.638Z" },
"myinfo":
{ "User": "intro",
"contactPerson": "Newbee",
"contact": "00000000",
"notes": "hey guys i am new"
}
}
This is my code i need help with the multiple dictionaries.
__block NSMutableDictionary *resultsDictionary;
SMAMobileAPI *api = [SMAMobileAPI sharedSMAMobileAPI];
NSMutableDictionary *bodyParams = [[NSMutableDictionary alloc]init];
NSMutableDictionary *header = [[NSMutableDictionary alloc]init];
[header setValue:#"2312b23c-5b83-46f0-8670-5edc2b1d1672" forKey:#"id"];
[header setValue:#"2e3a015e-bebd-ddsfsdf" forKey:#"parentId"];
[header setValue:#“IRELAND" forKey:#"countryCode"];
[header setValue:#"2017-10-13T08:39:14.638Z" forKey:#"timeStamp"];
NSMutableDictionary *myinfo = [[NSMutableDictionary alloc]init];
[Case setValue:#“intro" forKey:#“User"];
[Case setValue:#“newbie" forKey:#"contactPerson"];
[Case setValue:#"+254 724474140" forKey:#"contactPersonNo"];
[Case setValue:#"iOS case" forKey:#"notes"];
[bodyParams setValue:header forKey:#"header"];
[bodyParams setValue:myinfo forKey:#“myinfo"];
if ([NSJSONSerialization isValidJSONObject:bodyParams]) {//validate it
NSError* error = nil;
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:bodyParams options:NSJSONWritingPrettyPrinted error: &error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData
encoding:NSUTF8StringEncoding];
NSURL* url = [NSURL URLWithString:#“my URL"];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
[request setHTTPMethod:#"POST"];//use POST
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:[NSString stringWithFormat:#"%lu",(unsigned long)[jsonData length]] forHTTPHeaderField:#"Content-length"];
[request setHTTPBody:jsonData];//set data
__block NSError *error1 = nil;
//use async way to connect network
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse* response,NSData* data,NSError* error)
{
if ([data length]>0 && error == nil) {
resultsDictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&error1];
NSLog(#"resultsDictionary is %#",resultsDictionary);
[self hideLoading];
} else if ([data length]==0 && error ==nil) {
NSLog(#" download data is null");
[self hideLoading];
} else if( error!=nil) {
NSLog(#" error is %#",error);
[self hideLoading];
}
}];
}
}
Seems like converting the NSDictionary to JSON is your actual problem. See documentation https://developer.apple.com/documentation/foundation/jsonserialization
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:yourDictionary
options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData
encoding:NSUTF8StringEncoding];
Hi i am very new for ios and in my app i have used ASIFormDataRequest earlier days for integrating the services
now i have changed format and i am using NSURLSession instead of ASIFormDataRequest
But when i request change password to server using ASIFormDataRequest success response is coming from server but when i use NSURLSession failed response coming from server please help what is wrong
NSURlsession:-
def = [NSUserDefaults standardUserDefaults];
NSString *myString = [def stringForKey:#"AccesToken"];
NSString *AccessToken = [NSString stringWithFormat:#"Bearer %#",myString];
NSString *Finalstr = [NSString stringWithFormat: #"MedicaidId=%#&OldPassword=%#&NewPassword=%#&ConfirmPassword%#", medicaId,self.CurPwdTxt.text,self.NewPwdTxt.text,self.ConfPwdTxt.text];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:mainurl,BaseURL]]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[Finalstr dataUsingEncoding:NSUTF8StringEncoding]];
[request addValue:AccessToken forHTTPHeaderField:#"Authorization"];
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(#"dataTaskWithRequest error: %#", error);
}
else if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
if (statusCode != 200) {
NSError *parseError;
id responseObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
NSLog(#"responseobject is %#",responseObject);
}else{
NSError *parseError;
id responseObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
NSLog(#"else condtion");
if (!responseObject) {
NSLog(#"JSON parse error: %#", parseError);
NSLog(#"responseobject is%#",responseObject);
} else {
NSLog(#"responseobject is %#",responseObject);
}
//if response was text/html, you might convert it to a string like so:
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"final responseString = %#", responseString);
}
}
}];
[task resume];
}
ASIFormDataRequest:-
NSString *urlStr = [NSString stringWithFormat:#"myurl",BaseURL];
NSLog(#"urlStr --->>> %#",urlStr);
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:urlStr]];
[request setRequestMethod:#"POST"];
def = [NSUserDefaults standardUserDefaults];
NSString *myString = [def stringForKey:#"AccesToken"];
NSString *str = [NSString stringWithFormat:#"Bearer %#",myString];
NSLog(#"token is %#",str);
[request setPostValue:medicaId forKey:#"MedicaidId"];
[request setPostValue:self.CurPwdTxt.text forKey:#"OldPassword"];
[request setPostValue:self.NewPwdTxt.text forKey:#"NewPassword"];
[request setPostValue:self.ConfPwdTxt.text forKey:#"ConfirmPassword"];
[request addRequestHeader:#"Authorization" value:str];
[request setDelegate:self];
[request startAsynchronous];
You are sending different requests there. In the 'new' code, you are constructing the POST data like this:
#"MedicaidId=%#&OldPassword=%#&NewPassword=%#&ConfirmPassword%#"
which looks like GET-parameters more than form-encoding (which you use on the 'old' request).
Tracking your request and checking out the actual request using something like Wireshark might help you out to spot the problem yourself next time.
I am new in iOS application development. I have one problem in login page.
Sometimes it will take long time for log in. I am using this code to send or receive a request from a httpserver.
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonData1
options:0 // Pass 0 if you don't care about the readability of the generated string
error:&error];
if (!jsonData) {
NSLog(#"Got an error: %#", error);
} else {
jsonString= [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"converted json string is %#",jsonString);
}
NSData *postData = [[[NSString alloc] initWithFormat:#"method=methodName&email=%#&password=%#", user_name, pass_word] dataUsingEncoding:NSASCIIStringEncoding ];
NSString *postLength = [NSString stringWithFormat:#"%ld",[postData length]];
jsonData=[jsonString dataUsingEncoding:NSASCIIStringEncoding];
NSLog(#"the final passing json data is %#",jsonData);
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"http:urladdress"]];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"\"Accept\""];
[request setValue:#"application/json" forHTTPHeaderField:#"\"Content-Type\""];
[request setValue:postLength forHTTPHeaderField:#"\"Content-Length\""];
[request setValue:#"application/x-www-form-urlencoded;" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:jsonData];
NSError *requestError = [[NSError alloc] init];
NSHTTPURLResponse *response = nil;
NSData *urlData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&requestError];
//if communication was successful
if ([response statusCode] >= 200 && [response statusCode] < 300) {
NSError *serializeError = nil;
NSString* newStr = [NSString stringWithString :[urlData bytes]];
NSDictionary *jsonData = [NSJSONSerialization
JSONObjectWithData:urlData
options:NSJSONReadingAllowFragments
error:&serializeError];
NSLog(#"recdata %#",jsonData);
}
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (connection)
{
NSLog(#"theConnection is succesful");
self.receivedData = [NSMutableData data];
}
[connection start];
[self readFromDataBase];
if (dataCheck==true) {
[self checkPassword];
}
is there any way to login faster.?
Maybe the connection is slow because your server or your connection quality.
Did you try with async? It won't freeze your app when waiting the respond
Asynchronous NSURLConnection Scheme Tutorial
For your program, replace the sendSync method:
NSData *urlData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&requestError];
by sendAsync method:
NSOperationQueue *mainQueue = [[NSOperationQueue alloc] init];
[mainQueue setMaxConcurrentOperationCount:5];
[NSURLConnection sendAsynchronousRequest:request queue:mainQueue completionHandler:^(NSURLResponse *response, NSData *urlData, NSError *requestError) {
// doing somethings ...
// if communication was successful ...
}];
I am trying to fetch json data from local host. I have done this so many times. But this time it is not fetching data.
Json data
{
"swimming_pool":"0",
"security":"0",
"lift":"0",
"gym":"0",
"reserved_parking":"0",
"visitor_parking":"0",
"power_backup":"0",
"servant_room":"0",
"tennis_court":"0",
"rainwater_harvesting":"0",
"waste_management":"0",
"club_house":"0",
"desc":"Dkkd",
"city":"City",
"pincode":"Pin Co",
"locality":"locality",
"no_of_beds":"1",
"no_of_baths":"4"
}
Client side code
{
NSString *selectQuery=[NSString stringWithFormat:#"http://localhost/FilterQuery.php?swimming_pool=%li&&security=%li&&lift=%li&&gym=%li&&visitor_parking=%li&&power_backup=%li&&servant_room=%li&&rainwater_harvesting=%li&&waste_management=%li&&clubhouse=%li&&Posdesc=%#&&no_of_baths=%li&&no_of_beds=%li&&pincode=%li&&locality=%#&&protypedesc=%#",(long)swimpoolb,(long)securityb,(long)liftb,(long)gymb,(long)visparkingb,(long)pbu,(long)servantroom,(long)rainwaterh,(long)wastemanagement,(long)clubHouse,possesion,(long)bathrooms,(long)bedrooms,(long)zipcode,locality,propertyType];
NSString *newInsrStr = [selectQuery stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSData *dataaa=[NSData dataWithContentsOfURL:[NSURL URLWithString:newInsrStr]];
NSString *rr=[[NSString alloc]initWithData:dataaa encoding:NSUTF8StringEncoding];
NSLog(#"%#",rr);
jsondataa=[NSJSONSerialization JSONObjectWithData:dataaa options:0 error:nil];
//jsondataa is dictionary
swimmingPool=#"";
swimmingPool=[jsondataa objectForKey:#"swimming_pool"];
security=#"";
security=[jsondataa objectForKey:#"security"];
lift=#"";
lift=[jsondataa objectForKey:#"lift"];
gym=#"";
gym=[jsondataa objectForKey:#"gym"];
reserved_parking=#"";
reserved_parking=[jsondataa objectForKey:#"reserved_parking"];
visitor_parking=#"";
visitor_parking=[jsondataa objectForKey:#"visitor_parking"];
power_backUp=#"";
power_backUp=[jsondataa objectForKey:#"power_backup"];
NSLog(#"%#,%#,%#,%#,%#,%#,%#",swimmingPool,security,lift,gym,reserved_parking,visitor_parking,power_backUp);
}
Output:
2015-06-29 15:20:51.874 NexGV1[1684:60b] Notice:
Undefined variable: tennis_court in
/Applications/XAMPP/xamppfiles/htdocs/FilterQuery.php on line
21
{"swimming_pool":"0","security":"0","lift":"0","gym":"0","reserved_parking":"0","visitor_parking":"0","power_backup":"0","servant_room":"0","tennis_court":"0","rainwater_harvesting":"0","waste_management":"0","club_house":"0","desc":"Dkkd","city":"City","pincode":"Pin
Co","locality":"locality","no_of_beds":"1","no_of_baths":"4"}
2015-06-29 15:20:51.875 NexGV1[1684:60b]
(null),(null),(null),(null),(null),(null),(null)
It is showing null value. Why?
This is suppose to be a comment but it's too long for a comment..
So, your approach is json request via url, it is not the ideal for something like this it is confusing and hard to read..
I'm so lazy checking that very long url, so i'll just introduce you to this kind of approach..
NSString *selectQuery=[NSString stringWithFormat:#"http://localhost/FilterQuery.php?swimming_pool=%li&&security=%li&&lift=%li&&gym=%li&&visitor_parking=%li&&power_backup=%li&&servant_room=%li&&rainwater_harvesting=%li&&waste_management=%li&&clubhouse=%li&&Posdesc=%#&&no_of_baths=%li&&no_of_beds=%li&&pincode=%li&&locality=%#&&protypedesc=%#",(long)swimpoolb,(long)securityb,(long)liftb,(long)gymb,(long)visparkingb,(long)pbu,(long)servantroom,(long)rainwaterh,(long)wastemanagement,(long)clubHouse,possesion,(long)bathrooms,(long)bedrooms,(long)zipcode,locality,propertyType];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:selectQuery]];
You can convert that url to request then use the NSURLConnection below..
__block NSMutableData *fragmentData = [NSMutableData data];
__block id serializedResponse;
[[NSOperationQueue mainQueue] cancelAllOperations];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
[fragmentData appendData:data];
if ([data length] == 0 && error == nil)
{
NSLog(#"No response from server");
}
else if (error != nil && error.code == NSURLErrorTimedOut)
{
NSLog(#"Request time out");
}
else if (error != nil)
{
NSLog(#"Unexpected error occur: %#", error.localizedDescription);
}
else if ([data length] > 0 && error == nil)
{
if ([fragmentData length] == [response expectedContentLength])
{
NSLog(#"Received %f of data from server.", (CGFloat)[response expectedContentLength]);
serializedResponse = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:&error];
NSLog(#"%#", serializedResponse);
// or
NSLog(#"%#", [[NSString alloc] initWithData:fragmentData encoding:NSUTF8StringEncoding]);
}
}
}];
And also if you like the easy way to make a request using the NSURLConnection above.
- (NSURLRequest *)convertToRequest:(NSString *)stringURL withDictionary:(NSDictionary *)dictionary
{
NSError *error = nil;
NSData *JSONData = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error];
NSURL *url = [NSURL URLWithString:stringURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setHTTPBody: JSONData];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept-Encoding"];
[request setValue:[NSString stringWithFormat:#"%lu", (unsigned long)[JSONData length]] forHTTPHeaderField:#"Content-Length"];
return request;
}
and using it like:
NSDictionary *jsonDictionary = #{
#"swimming_pool": [NSNumber numberWithLong:(long)swimpoolb],
#"security" : [NSNumber numberWithLong:(long)securityb],
.. and so on
};
NSURLRequest *request = [ImplementationClass convertToRequest:YourServerURL withDictionary: jsonDictionary];
and in the server it should be:
$handle = fopen('php://input','r');
$jsonInput = fgets($handle);
$json_decoded = json_decode($jsonInput,true);
$json_decoded['swimming_pool'];
$json_decoded['security'];
Hope this is informative and helpful...
Posted a query previously about JSON parsing not working properly. Did more looking into it with a packet sniffer and also with another client that works properly and found out it's a syntax thing, that I still can't seem to solve.
The code in the bottom makes the HTTP request to have the JSON in it as:
{"key":"value"}
And my server is actually looking for a JSON in the following syntax:
key=%22value%22
I tried to write some code that does this manually, but figured there must be something out of the box for iOS, and I don't want to have faults in the future.
I messed around with it for a while trying to find the right code for the job, but couldn't (you can see some code I tried commented out). Can anyone help me?
+ (NSString*)makePostCall:(NSString*)urlSuffix
keys:(NSArray*)keys
objects:(NSArray*)objects{
NSDictionary *params = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
// NSString *dataString = [self getDataStringFromDictionary:params];
// NSData *jsonData = [dataString dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params
options:0
error:&error];
// id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
// NSLog(#"%#", jsonObject);
if (!jsonData) {
// should not happen
NSError *error;
NSLog(#"Got an error parsing the parameters: %#", error);
return nil;
} else {
// NSString *jsonRequest = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
// NSLog(#"%#", jsonRequest);
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#", urlPrefix, urlSuffix]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20.0];
// NSData *requestData = [jsonRequest dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
// [request setValue:#"application/x-www-form-urlencoded;charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody: jsonData];
NSURLResponse * response = nil;
NSError * error = nil;
NSData * data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
// TODO: handle error somehow
NSString *returnString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return returnString;
}
}