Sending JSON to Schematic Ipsum - ios

I'trying to get some random JSON from http://schematic-ipsum.herokuapp.com/ but I'm getting a response code 400.
Here is the code I'm using
+ (NSArray *)postData:(NSDictionary *)arguments toServer:(NSString *)urlString
{
NSArray *dataToReturn;
// if urlString is nil, we default it to our server
if(!urlString) urlString = JSON_SERVER;
// of course we need to turn the string into a valid array
NSURL *url = [NSURL URLWithString:urlString];
/*
prepare the post
*/
// we need to catch possible errors
NSError *error;
// turn our arguments into NSData
NSData *postData = [NSJSONSerialization dataWithJSONObject:arguments options:0 error:&error];
// we need the post' length
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[postData length]];
// create the url request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded;charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
// here we'll check the server response
NSHTTPURLResponse *response = nil;
// here's our data from the server
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if ([response statusCode] >=200 && [response statusCode] <300)
{
// all good, let's see what we've got
NSString *responseData = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
NSLog(#"Response ==> %#", responseData);
// parse the response into a friendly format
dataToReturn = [[NSArray alloc] initWithArray:[self returnJSONFromData:urlData]];
} else {
// somethin went wrong
NSLog(#"Response code: %ld", (long)[response statusCode]);
// check if it's our fault
if (error) {
NSLog(#"Server error: %#", [error localizedDescription]);
}
}
// return our formatted array or nil
return dataToReturn;
}
+ (NSArray *)returnJSONFromData:(NSData *)urlData
{
NSArray *dataToReturn;
NSError *e = nil;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData: urlData options: NSJSONReadingMutableContainers error: &e];
if (!jsonArray) {
NSLog(#"Error parsing JSON: %#", [e localizedDescription]);
dataToReturn = #[e];
} else {
dataToReturn = [[NSArray alloc] initWithArray:jsonArray];
NSLog(#"data from json: %#", dataToReturn);
}
return dataToReturn;
}
and I'm calling it like this, using a demo JSON from their website:
NSDictionary *post = #{ #"type": #"object", #"properties": #{ #"id": #{ #"type": #"string", #"ipsum": #"id" }, #"name": #{ #"type": #"string", #"ipsum": #"name" }, #"email": #{ #"type": #"string", #"format": #"email" } }};
[RetrieveDataFromServer postData:post toServer:#"http://schematic-ipsum.herokuapp.com/"];

You need to respect the syntax of "Form Data" that the server takes. To obtain this, you can use Google Chrome "Inspect Element", choose "Network" tab then do a request and you'll see this:
Look at "Form Data" section and you'll find out your problem, it's because you didn't pass the right structure to server so that the server doesn't understand.
I took the defaults parameters of server which is:
{
"type": "object",
"properties": {
"id": {
"type": "string",
"ipsum": "id"
},
"name": {
"type": "string",
"ipsum": "name"
},
"email": {
"type": "string",
"format": "email"
},
"bio": {
"type": "string",
"ipsum": "sentence"
},
"age": {
"type": "integer"
},
"avatar": {
"type": "string",
"ipsum": "small image"
}
}
}
So the data must be structured like this:
type:object
properties[id][type]:string
properties[id][ipsum]:id
properties[name][type]:string
properties[name][ipsum]:name
properties[email][type]:string
properties[email][format]:email
properties[bio][type]:string
properties[bio][ipsum]:sentence
properties[age][type]:integer
properties[avatar][type]:string
properties[avatar][ipsum]:small image
And don't forget to encode with percentage before sending it to server or you will fail again.
I tried to implement a method that take your dictionary and return the formatted form data, it works fine for this case but I'm not sure in a more general context. I'll post it here for you as a reference, it's really a mess, sorry for that but I don't have enough time for commenting.
- (NSString *)formatFormData:(NSDictionary *)dictionary
{
NSMutableArray *arrayPrefix = [NSMutableArray array];
NSMutableArray *arrayResult = [NSMutableArray array];
[self structureString:dictionary arrayPrefix:arrayPrefix arrayResult:arrayResult];
return [arrayResult componentsJoinedByString:#"&"];;
}
- (void)structureString:(NSDictionary *)dictionay arrayPrefix:(NSMutableArray *)arrayPrefix arrayResult:(NSMutableArray *)arrayResult
{
for(NSString *key in dictionay.allKeys)
{
NSObject *obj = [dictionay objectForKey:key];
if([obj isKindOfClass:[NSDictionary class]])
{
[arrayPrefix addObject:key];
[self structureString:(NSDictionary *)obj arrayPrefix:arrayPrefix arrayResult:arrayResult];
}
else
{
NSMutableString *string = [[NSMutableString alloc] initWithString:#""];
for(int i = 0; i < arrayPrefix.count; i++)
{
NSString *eachPrefix = arrayPrefix[i];
if(i == 0)
{
[string appendString:eachPrefix];
}
else
{
[string appendString:[NSString stringWithFormat:#"[%#]", eachPrefix]];
}
}
if(arrayResult.count == 0)
{
[string appendString:[NSString stringWithFormat:#"%#=%#", key, obj]];
}
else
{
[string appendString:[NSString stringWithFormat:#"[%#]=%#", key, obj]];
}
[arrayResult addObject:string];
}
}
}
And in your current method, add these lines:
- (NSArray *)postData:(NSDictionary *)arguments toServer:(NSString *)urlString
{
// omitted
// turn our arguments into NSData
NSData *postData = [NSJSONSerialization dataWithJSONObject:arguments options:0 error:&error];
NSString *stringTemp = [[NSString alloc] initWithData:postData encoding:NSUTF8StringEncoding];
stringTemp = [self formatFormData:arguments];
// encode form date before sending to server
stringTemp = [stringTemp stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
postData = [stringTemp dataUsingEncoding:NSUTF8StringEncoding];
// omitted
}

Related

Parsing JSON object and sub-elements

I just need to know proper method to parse the JSON string.
Here is my sample JSON response:
[
{
"my_response": [
{
"name": "XXX",
"Area": "XXX",
"Num": 123
}
]
},
{
"other_response": [
{
"message": "Hello",
"status": "Success",
"flag_value": "1"
}
]
}
]
I want to parse flag_value in a String
I tried this method
NSString *str1 = [json valueForKeyPath:#"other_response. flag_value"];
NSLog(#"str %#",str1);
And my output is some what like this
str (
"<null>",
(
1
)
)
But I want my output to be a string like this:
1
[{"my_response":[{"name":"XXX","Area":"XXX","Num":123}]},{"other_response":[{"message":"Hello","status":"Success","flag_value":"1"}]}]
actually your Json response Start in Array so follow this step
Step-1
NSArray *jsonDict = [NSJSONSerialization JSONObjectWithData:yourData options:Kniloptions error:nil];
Step-2
in here you are get 2 Dictionaries
NSString *FlagStr;
for (NSMutableDictionary *temp in jsonDict)
{
NSArray *secondOption=[temp objectForKey:#"other_response"];
for (NSMutableDictionary *second in secondOption)
{
FlagStr=[second objectForKey:#"flag_value"];
}
}
Choice no-2
I am not try this but May be it work for you , once check
Step-1
NSArray *jsonDict = [[[NSJSONSerialization JSONObjectWithData:yourData options:Kniloptions error:nil]objectAtIndex:1] objectForKey:#"other_response"];
Step-2
NSString *FlagStr;
for (NSMutableDictionary *second in secondOption)
{
FlagStr=[temp objectForKey:#"flag_value"];
}
Choice no-3
you can directly fetch the string value I am not try this but May be it work for you , once check
NSString *flage = [[[NSJSONSerialization JSONObjectWithData:yourData options:Kniloptions error:nil]objectAtIndex:1] objectForKey:#"other_response"]objectAtIndex:0] objectForKey:#"flag_value"];
First of all, I think your JSON would be better formatted like the following:
{
"my_response": {
"name": "XXX",
"area": "XXX",
"num": "XXX"
},
"other_response": {
"message": "Hello",
"status": "success",
"flag_value": "1"
}
}
Then you can use the following code to access your data:
NSString *jsonString = #"{\"my_response\": {\"name\": \"XXX\",\"area\": \"XXX\",\"num\": \"XXX\"},\"other_response\": {\"message\": \"Hello\",\"status\": \"success\",\"flag_value\": \"1\"}}";
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:nil];
NSLog(#"str: %#", [jsonDict valueForKeyPath:#"other_response.flag_value"]);
Format your Json array like this way.
{
"my_response": {"name": "XXX","area": "XXX","num": "XXX"
},
"other_response": {"message": "Hello","status": "success","flag_value": "1"
}
}
**Step : 2**
Use AFNetworking for HTTP Client
- (void)yourMethod{
NSString *urlString = [NSString stringWithFormat:#"%#", your_service_url];
NSURL *url = [NSURL URLWithString:urlString];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
[AFJSONRequestOperation addAcceptableContentTypes:[NSSet setWithObject:#"text/html"]];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
your_parameters_list,
nil];
NSMutableURLRequest *jsonRequest = [httpClient requestWithMethod:#"POST"
path:urlString
parameters:params];
AFJSONRequestOperation *operation =
[AFJSONRequestOperation JSONRequestOperationWithRequest:jsonRequest success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(#" Success %#", JSON);
NSDictionary *jsonDictionary1 = [JSON valueForKey:#"my_response"];
NSDictionary *jsonDictionary2 = [JSON valueForKey:#"other_response"];
NSString* name = [jsonDictionary1 valueForKey:#“name”];
NSString* area = [jsonDictionary1 valueForKey:#"name"];
NSString* num = [jsonDictionary1 valueForKey:#"num"];
} failure: ^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(#"Fail %#", [error userInfo]);
NSLog(#“Error %#", [error localizedRecoverySuggestion]);
}];
[operation start];
}
As accepted above brother Anbu.Karthick answer.But I want to give answer for this
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:yourResponseData options: NSJSONReadingMutableContainers error: &err];
for (int i =0; i<[jsonArray count]; i++)
{
NSMutableDictionary *dict = [[jsonArray objectAtIndex:i] mutableCopy];
NSString *strFlag = [NSString stringWithFormat:#"%#",[[[dict objectForKey:#"other_response"] objectAtIndex:0] valueForKey:#"flag_value"]];
NSLog(#"The strFlag is-%#",strFlag);
}

Getting value from JSON stored as NSString for iOS in xCode

I have some JSON stored as an NSString and I am trying to convert this to a NSDictionary and get the value of 'EndDate' in my JSON.
I wanted to retrieve 'EndDate' from the JSON but due to the amount of levels i'm not quite sure how I should be achieving it.
Here is the JSON:
{ "GetResponse":{ "GetResult":{ "Faults":null, "Response":{ "Asset":{ "AssetParts":{ "#nil":"true" }, "CountryLookupCode":808, "Number”:24234, "Duplicate":"false", "Code":"`123”, "Channel”:”SR”, “Desc”:”Test”, "Number”:123, “Mandate”:{ "#nil":"true" }, “TestTime”:”True”, “Date”:”2010-08-12T19:00:00", “Results”:{ “Details”:[ { "EndDate":"2013-08-13T18:59:59", “Type”:”Taken”, "Item”:”902”, “Level”:”SL”, “Description”:”Timed”, “Group”:1, “Prov”:{ "#nil":"true" }, "StartDate":"2010-08-12T19:00:00" }, { "EndDate":"2013-08-13T18:59:59", “Machine”:”Dated”, “Country”:”UK”, "Code":"CCDD”, “Description”:”Addressed”, “Level”:2, "Provider":{ "#nil":"true" }, "StartDate":"2010-08-12T19:00:00" }, { "EndDate":"2013-08-13T18:59:59", "Type”:”Title”, "ItemNumber”:”1253”, "Service":"NEDD”, “Desc”:”Down”, “Grp”:5, "Provider":{ "#nil":"true" }, "StartDate":"2010-08-12T19:00:00" } ] } } } } } }
Here is my code:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"https://192.168.0.20/test.json"]];
[request setHTTPMethod:#"GET"];
NSURLResponse *requestResponse;
NSData *requestHandler = [NSURLConnection sendSynchronousRequest:request returningResponse:&requestResponse error:nil];
NSString *requestReply = [[NSString alloc] initWithBytes:[requestHandler bytes] length:[requestHandler length] encoding:NSASCIIStringEncoding];
//NSLog(#"requestReply: %#", requestReply);
//End
NSData *data = [requestReply dataUsingEncoding:NSUTF8StringEncoding];
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSArray *performersArray = [json objectForKey:#"GetResponse"];
for (NSDictionary *performerDic in performersArray) {
NSLog(#"%#", [performerDic objectForKey:#"EndDate"]);
}
Thanks
NSArray *detailsArray = json[#"GetResponse"][#"GetResult"][#"Response"][#"Asset"][#"Results"][#"Details"];
for (NSDictionary *detailsDict in detailsArray){
NSLog(#"%#",detailsDict[#"EndDate"]);
}
this should work

NSMutableURLRequest returning JSON with empty sub-arrays

I have created a method that uses NSMutableURLRequest to request and receive JSON from a RESTful API running on a remote machine. The request successfully returns some JSON, but the returned sub-arrays in the JSON (see tasks: []) are empty.
The JSON returned from the API is:
{
"error":false,
"tasks":[
{
"id":1,
"task":"Get Milk",
"status":0,
"createdAt":"2014-08-09 12:29:15"
},
{
"id":2,
"task":"Call Mom",
"status":0,
"createdAt":"2014-08-09 12:46:52"
},
{
"id":3,
"task":"Call Dad",
"status":0,
"createdAt":"2014-08-09 12:47:04"
},
{
"id":4,
"task":"Study",
"status":0,
"createdAt":"2014-08-09 12:47:08"
}
]
}
The method that utilizies NSMutableURLRequest (proper parameters being passed is assumed) is:
-(NSDictionary *) apiRequestWithEndpoint:(NSString *) endpoint
withParams:(NSDictionary *) params
withHTTPHeaders:(NSDictionary *) headers
withHTTPMethod:(NSString *) method
{
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:endpoint]];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPMethod:method];
//set headers
for (id key in headers) {
[request setValue:[headers valueForKey:key] forHTTPHeaderField:key];
}
//set paramaters in request body
NSMutableString *requestBody = [[NSMutableString alloc] init];
int keyIndex = 0;
for (id key in params) {
if (keyIndex == 0) {
[requestBody appendFormat:#"%#=%#", key, [params valueForKey:key]];
} else {
[requestBody appendFormat:#"&%#=%#", key, [params valueForKey:key]];
}
keyIndex++;
}
[request setHTTPBody:[requestBody dataUsingEncoding:NSUTF8StringEncoding]];
NSURLResponse *response;
NSError *NSURLError = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&NSURLError];
if (NSURLError) {
NSLog(#"Error: %# Cancelling operation.", NSURLError);
return nil;
}
NSError *NSJSONSerializationError = nil;
NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&NSJSONSerializationError];
if (NSJSONSerializationError) {
NSLog(#"Error: %# Cancelling operation.", NSJSONSerializationError);
return nil;
}
NSLog(#"Data: %#",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
return responseJSON;
}
Notice the 4th last line that logs the returned NSData from the NSMutableURLRequest, the output is:
Data: {"error":false "tasks":[]}
The code that calls the above method:
NSString *getAllTasksEndpoint = #"http://developmentVPS.com/TaskList-API/v1/tasks";
NSString *apiKey = #"A Valid API Key";
NSDictionary *headers = [[NSDictionary alloc] initWithObjectsAndKeys:apiKey, #"Authorization", nil];
NSDictionary *responseJSON = [self apiRequestWithEndpoint:getAllTasksEndpoint
withParams:nil
withHTTPHeaders:headers
withHTTPMethod:#"GET"];
It is my understanding that the entire data returned from the request should be logged in that NSLog call, but "tasks" is empty. I am new to iOS development, so I may be missing something simple. Does anybody see anything I am missing here?

JSON response and NSDictionary

I am new in the iOS development and i am calling the web service that returns me data like
[
{
"ID": "3416a75f4cea9109507cacd8e2f2aefc3416a75f4cea9109507cacd8e2f2aefc",
"Name": "2M Enerji"
},
{
"ID": "072b030ba126b2f4b2374f342be9ed44072b030ba126b2f4b2374f342be9ed44",
"Name": "Çedaş"
},
{
"ID": "093f65e080a295f8076b1c5722a46aa2093f65e080a295f8076b1c5722a46aa2",
"Name": "Çelikler"
},
{
"ID": "7cbbc409ec990f19c78c75bd1e06f2157cbbc409ec990f19c78c75bd1e06f215",
"Name": "Çoruh EDAŞ"
},
{
"ID": "70efdf2ec9b086079795c442636b55fb70efdf2ec9b086079795c442636b55fb",
"Name": "İçdaş"
}
]
Now i am trying to get it in the array , the array will be seperate for the name and id , i am done till taking in NSDICT following is my code
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"finish loading");
NSString *loginStatus = [[NSString alloc] initWithBytes:[webData mutableBytes]
length:[webData length]
encoding:NSUTF8StringEncoding];
NSString *responsewith = [[NSString alloc] initWithData:webData
encoding:NSUTF8StringEncoding];
//providerData = [NSKeyedUnarchiver unarchiveObjectWithData:webData];
providerDropData = [NSString stringWithFormat:responsewith];
NSLog(#"drop %#",providerDropData);
NSArray *providerData = [providerDropData valueForKey:#"ID"];
NSLog(#"jey %#",responsewith);
NSLog(#"resonser %#",responsewith);
NSLog(#"laoding data %#",loginStatus);
//greeting.text = loginStatus;
[loginStatus release];
[connection release];
[webData release];
}
When i tried saving the NSDictionary to the NSArray for #"ID" the application get crashed.
Please help
You simply want to use NSJSONSerialization
NSError *error = nil;
NSArray *results = [NSJSONSerialization JSONObjectWithData:webData options:0 error:&error];
if (!results)
NSLog(#"%s: JSONObjectWithData error: %#", __FUNCTION__, error);
// get the first provider id
NSString *providerData = results[0][#"ID"];
You can fetch data from JSON like below way as well,
id jsonObjectData = [NSJSONSerialization JSONObjectWithData:webData error:&error];
if(jsonObjectData){
NSMutableArray *idArray = [jsonObjectData mutableArrayValueForKeyPath:#"ID"];
NSMutableArray *nameArray = [jsonObjectData mutableArrayValueForKeyPath:#"Name"];
}
Convert the data to NSDictionary by parsing, then you can extract using KVP.
NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:response options:0 error:&error];
NSDictionary * providerDropData = [NSJSONSerialization JSONObjectWithData:webData error:&error];
NSLog(#"drop %#",providerDropData);
NSMutableArray *providerData = [NSMutableArray new];
NSString *key = #"ID";
for (key in providerDropData){
NSLog(#"Key: %#, Value %#", key, [providerDropData objectForKey: key]);
[providerData addObject:[providerDropData objectForKey:key]];
}
NSLog("ID Array = %#", providerData]);
}

Disqualify lead in Dynamics CRM (iOS)

How can i disqualify lead in Microsoft Dynamics CRM ? Is there any particular API for doing this from iOS platform?
I tried this :
for (id key in [details allKeys]) {
if([key isEqualToString:#"LeadState"])
{
[contactPostDict setObject:#"2" forKey:#"State"];
}
else if([key isEqualToString:#"LeadStatus"])
{
[contactPostDict setObject:#"6" forKey:#"Status"];
}
}
This is the error:
"error": {
"code": "", "message": {
"lang": "en-US", "value": "Error processing request stream. The property name 'Status' specified for type 'Microsoft.Crm.Sdk.Data.Services.Lead' is not valid."
}
}
I have never worked on the iOS platform but from the error that is being thrown, the error seems to be pretty straight forward.
You are looking for the keys "Status" & "State" but they don't exist. Instead you should be looking at their schema names which is as follows
Status = statuscode, State = statecode
Can you try modifying the code to use the above keys and see if you still gets the same error.
(BOOL)setLeadStatus:(NSString *)ID andDetails:(NSMutableDictionary *)details
{
NSString *uri = [MSDYNAMICS_AUTHENTICATION_CALL stringByAppendingPathComponent:[NSString stringWithFormat:#"LeadSet(guid'%#')/",ID]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:uri]];
request.HTTPMethod = #"MERGE";
[request setValue:JSON_CONTENT_TYPE_PARAMETER forHTTPHeaderField:#"Content-Type"];
[request setValue:JSON_CONTENT_TYPE_PARAMETER forHTTPHeaderField:#"Accept"];
NSMutableDictionary *contactPostDict=[[NSMutableDictionary alloc]init];
for (id key in [details allKeys]) {
if([key isEqualToString:#"LeadState"])
{
[contactPostDict setObject:#"2" forKey:#"statecode"];
}
else if([key isEqualToString:#"LeadStatus"])
{
[contactPostDict setObject:#"6" forKey:#"statuscode"];
}
}
NSError *err;
NSData *postData=[NSJSONSerialization dataWithJSONObject:contactPostDict options:NSJSONWritingPrettyPrinted error:&err];
NSString* postString = [[NSString alloc] initWithData:postData encoding:NSUTF8StringEncoding];
//NSString *postString = #"";
[request setValue:JSON_CONTENT_TYPE_PARAMETER forHTTPHeaderField:CONTENT_TYPE_PARAMETER];
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]];
SURLConnection *conn = [[SURLConnection alloc] init];
NSData *responseData = [conn sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *err1 = [[NSString alloc]initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"error: %#",err1);
if(responseData.length==0 && [conn.response statusCode] == 204)
{
[self getLeadDetailsForID:ID];
return YES;
}
else{
NSString *err = [[NSString alloc]initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"error: %#",err);
}
return NO;
}

Resources