I am receiving comma separated string as below which is to be converted to array of dictionaries.I tried using [myString componentsSeparatedByString:#","]; which however gives a totally different output.What is the correct way of converting it?
NSString *cancellationStr ==> [{"cutoffTime":"0-2","refundInPercentage":"0"},{"cutoffTime":"2-3","refundInPercentage":"50"},{"cutoffTime":"3-24","refundInPercentage":"90"}]
NSArray *array = [cancellationStr componentsSeparatedByString:#","];
//Gives response like below
(
"[{\"cutoffTime\":\"0-2\"",
"\"refundInPercentage\":\"0\"}",
"{\"cutoffTime\":\"2-3\"",
"\"refundInPercentage\":\"50\"}",
"{\"cutoffTime\":\"3-24\"",
"\"refundInPercentage\":\"90\"}]"
)
The code to fetch and parse using a singleton HTTP class
NSString *urlString=[NSString stringWithFormat:#"%#%#sourceCity=%#&destinationCity=%#&doj=%#",BASE_URL,AVAILABLE_BUSES,source,destination,dateStr];
urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url= [NSURL URLWithString:urlString];
SuccessBlock successBlock = ^(NSData *responseData){
NSError *error;
jsonDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];
bArray = [jsonDictionary objectForKey:#"apiAvailableBuses"];
};
FailureBlock failureBlock = ^(NSError *error){
NSLog(#"%#",error);
};
HTTPRequest *request = [[HTTPRequest alloc]initWithURL:url successBlock:successBlock failureBlock:failureBlock];
[request startRequest];
The above success block receives the string which then I am looking to convert.
NSString *cancellationStr = [[bArray objectAtIndex:rowIndex]valueForKey:#"cancellationPolicy"];
bObject.cancellationPolicy = [cancellationStr componentsSeparatedByString:#","];
NSLog(#"Cancellation Array : %#",bObject.cancellationPolicy);
So, "apiAvailableBusses" is an array of elements like this one:
{
"operatorId":196,
"operatorName":"Sahara Bus",
"departureTime":"6:45 PM",
"mTicketAllowed":false,
"idProofRequired":false,
"serviceId":"1602",
"fare":"450",
"busType":"Sahara Hitech Non A/c",
"routeScheduleId":"1602",
"availableSeats":29,
"partialCancellationAllowed":false,
"arrivalTime":"07:30 AM",
"cancellationPolicy":"[{\"cutoffTime\":\"12\",\"refundInPercentage\":\"0\"},{\"cutoffTime\":\"24\",\"refundInPercentage\":\"50\"}]",
"commPCT":0.0,
"boardingPoints":[
{
"time":"09:05PM",
"location":"Ameerpet,Kaveri Kmakshi Travels,Beside RKS Mall,Ameerpet, Mr.Aman-9391830030.",
"id":"6"
},
{
"time":"09:15PM",
"location":"Punjagutta,Sai Ganesh Travels, Punjagutta, Mr.Aman-9391830030.",
"id":"2241"
},
{
"time":"09:30PM",
"location":"Lakdi-ka-pool,Sahara Travels,Hotel Sri Krishna Complex,Mr.Aman-9391830030.",
"id":"2242"
},
{
"time":"08:45PM",
"location":"ESI,Behind Bajaj Show Room, Near Nani Travels. Mr.Aman-9391830030.",
"id":"2287"
},
{
"time":"09:45PM",
"location":"Nampally,Near Khaja Travels, Nampally,Mr.Aman-9391830030.",
"id":"2321"
},
{
"time":"09:16PM",
"location":"Paradise,Near SVR Travels, Paradise,Mr.Aman-9391830030.",
"id":"2322"
},
{
"time":"10:00PM",
"location":"Afzalgunj,Sahar Travels,Mr.Aman-9391830030.",
"id":"2323"
},
{
"time":"09:00PM",
"location":"Secunderbad Station,Near Asian Travels.Mr.Aman-9391830030.",
"id":"2336"
}
],
"droppingPoints":null,
"inventoryType":0
}
The "cancellationPolicy" element is a string which is what is called "embedded JSON". (Why they did that in this case I haven't a clue.) This means that the string must be fed through NSJSONSerialization again. And to convert the NSString to NSData (to feed through NSJSONSerialization again) you need to first use dataWithEncoding:NSUTF8StringEncoding.
Related
When i send API i'm getting JSON response like this.
{"ABC":[{"ID1":"response","ID2":"response","ID3":"response","ID4":"response","ID5":"response"},{"ID1":"response","ID2":"response","ID3":"response","ID4":"response","ID5":"response"},{"ID1":"response","ID2":"response","ID3":"response","ID4":"response","ID5":"response"}],"status":"OK","count":3}
{"XYZ":[{"id1":"response"},{"id1":"response"},{"id1":"response"}],"status":"OK","count":3}
Here i'm getting two JSON objects in the response. How to store this data in MutableArrays.
My code is...
//Getting data from server through JSON approach ...
self.urlSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
self.urlReq= [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[[NSString alloc] initWithFormat:#"http://MyApiName"]]];
self.dataTask = [self.urlSession dataTaskWithRequest:self.urlReq completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (!(data == nil)) {
self.loginDic = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(#"data : %#", data);
NSLog(#"Login Dic : %#", [self.loginDic objectForKey:#"ABC"]);
if (!(self.loginDic == nil)) {
self.integer = [[self.loginDic objectForKey:#"ABC"] count];
if ([[self.loginDic objectForKey:#"status"] isEqualToString:#"OK"] && (!(self.integer == 0))) {
self.ID1 = [[NSMutableArray alloc]init];
self.ID2 = [[NSMutableArray alloc]init];
self.ID3 = [[NSMutableArray alloc]init];
self.ID4 = [[NSMutableArray alloc]init];
self.ID5 = [[NSMutableArray alloc]init];
for (int i=0; i<self.integer; i++) {
[self.ID1 addObject:[[[self.loginDic objectForKey:#"ABC"] objectAtIndex:i] objectForKey:#"ID1"]];
[self.ID2 addObject:[[[self.loginDic objectForKey:#"ABC"] objectAtIndex:i] objectForKey:#"ID2"]];
[self.ID3 addObject:[[[self.loginDic objectForKey:#"ABC"] objectAtIndex:i] objectForKey:#"ID3"]];
[self.ID4 addObject:[[[self.loginDic objectForKey:#"ABC"] objectAtIndex:i] objectForKey:#"ID4"]];
[self.ID5 addObject:[[[self.loginDic objectForKey:#"ABC"] objectAtIndex:i] objectForKey:#"ID5"]];
}
NSLog(#"%#", self.ID1);
NSLog(#"%#", self.ID2);
} else {
}
} else {
}
} else {
}
}];
[self.dataTask resume];
}
I'm getting data, but I'm getting loginDic = null.
after you get AB , its array of Dictionary
you can easily use this valueForKeyPath like:
NSArray * AB = #[#{
#"ID1":#"response",
#"ID2":#"response",
#"ID3":#"response",
#"ID4":#"response",
#"ID5":#"response",
},#{
#"ID1":#"response",
#"ID2":#"response",
#"ID3":#"response",
#"ID4":#"response",
#"ID5":#"response"
}];
NSArray * ID1 = [AB valueForKeyPath:#"ID1"];
NSArray * ID2 = [AB valueForKeyPath:#"ID2"];
How to receive two JSON objects at a time?
The JSON you show is indeed two valid JSON encodings concatenated. If your server is doing this and there is nothing you can do to fix that then you can try to fix it yourself:
Any occurrence of ][, }{, ]{ or }[ with any amount of white space between the two characters is the end of one JSON encoding and the start of the next. Construct an NSRegularExpression to find these sequences and replace them with the same close/open bracket/brace combination but with a comma (,) in between them.
Add a single [ at the start and a single ] at the end.
These two steps will converted your concatenated JSON encodings into a JSON array of the individual encodings. Now parse and process as usual remembering you first need to index into the outermost array to access the particular JSON response before your index into the response to access the elements you need.
HTH
I'm using NSJSONSerialization to parse Google suggestions.
The query "f" returns these suggestions:
["f",["facebook","flipkart","fox news","forever 21","friv","fandango","fedex","fitbit","food near me","flights"]]
The parser works fine but when there are special characters like "ñ" for the query "fac":
["fac",["facebook","facebook search","fac","facebook app","facebook lite","facebook login","facebook logo","facebook messenger","facetime","facebook en español"]]
It throws an exception:
Error Domain=NSCocoaErrorDomain Code=3840 "Unable to convert data to string around character 139." UserInfo={NSDebugDescription=Unable to convert data to string around character 139.}
Any ideas? I tried all different reading options but none of them works.
#pragma mark -
- (void)request:(NSString *)text
{
NSMutableArray *items = [[NSMutableArray alloc] init];
NSString *query = [text stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSString *languageCode = [[NSLocale preferredLanguages] firstObject];
if (!languageCode) {
languageCode = #"en";
}
NSString *URLString = [NSString stringWithFormat:#"http://suggestqueries.google.com/complete/search?q=%#&client=firefox&hl=%#", query, languageCode];
NSError *downloadError = nil;
NSData *JSONData = [NSData dataWithContentsOfURL:[NSURL URLWithString:URLString] options:0 error:&downloadError];
if (!downloadError && JSONData) {
NSError *parseError = nil;
id object = [NSJSONSerialization JSONObjectWithData:JSONData options:NSJSONReadingMutableContainers error:&parseError];
if (!parseError && object) {
if ([object isKindOfClass:[NSArray class]]) {
NSArray *objects = (NSArray *)object;
NSArray *texts = [objects objectAtIndex:1];
for (NSString *text in texts) {
SNGoogleItem *item = [[SNGoogleItem alloc] initWithText:text];
[items addObject:item];
}
[_delegate google:self didRespondWithItems:items];
}
else {
[_delegate google:self didRespondWithItems:items];
}
}
else {
[_delegate google:self didRespondWithItems:items];
}
}
else {
[_delegate google:self didRespondWithItems:items];
}
}
JSONSerialization supports all the encodings in JSON spec, says Apple documentation.
You didn't provide much info about the encoding scheme of your data but I guess you use nonLossyASCII or something like that, which is not supported by JSONSerialization.
Here is how I convert data to/from JSON:
let rawString = "[[\"facebook en español\"]]"
// if I use String.Encoding.nonLossyASCII below, I get the error you are getting
let data = rawString.data(using: String.Encoding.utf8)
let dict = try! JSONSerialization.jsonObject(with: data!)
let convertedData = try! JSONSerialization.data(withJSONObject: dict)
let convertedString = String(data: convertedData, encoding: String.Encoding.utf8)!
// now convertedString contains "ñ" character
This will convert whatever encoding used to UTF8:
NSData *JSONData = [NSData dataWithContentsOfURL:[NSURL URLWithString:URLString] options:0 error:&downloadError];
NSString *convertedJSONString; BOOL usedLossyConversion;
[NSString stringEncodingForData:JSONData encodingOptions:0 convertedString:&convertedJSONString usedLossyConversion:&usedLossyConversion];
NSData *convertedJSONData = [convertedJSONString dataUsingEncoding:NSUTF8StringEncoding];
Now, it works!
I am converting JSON data in to NSString using below code:
NSString *json_string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Data AS STRING %#", json_string);
it returns NSString in this format:
Data AS STRING
{
"success": true,
"terms": "https://currencylayer.com/terms",
"privacy": "https://currencylayer.com/privacy",
"timestamp": 1446673809,
"source": "USD",
"quotes": {
"USDAED": 3.672993,
"USDAFN": 64.980003,
"USDALL": 127.164497,
"USDAMD": 474.480011,
"USDANG": 1.790326,
"USDAOA": 135.225006,
"USDARS": 9.536025,
"USDAUD": 1.398308,
"USDAWG": 1.79,
"USDAZN": 1.04625,
"USDBAM": 1.800851,
"USDBBD": 2,
"USDBDT": 78.666946,
"USDBGN": 1.80115,
"USDBHD": 0.37727,
"USDBIF": 1562.5,
"USDBMD": 1.00005,
"USDBND": 1.403198,
"USDBOB": 6.899293,
"USDBRL": 3.80025,
"USDBSD": 0.999335,
"USDBTC": 0.002372,
"USDBTN": 65.495003,
"USDBWP": 10.55195,
"USDBYR": 17415,
"USDBZD": 1.994983,
"USDCAD": 1.315225,
"USDCDF": 929.999946,
"USDCHF": 0.99331,
"USDCLF": 0.024598,
"USDCLP": 692.094971,
"USDCNY": 6.33525,
"USDCOP": 2837.080078,
"USDCRC": 534.015015,
"USDCUC": 0.99991,
"USDCUP": 0.99978,
"USDCVE": 101.349503,
"USDCZK": 24.907012,
"USDDJF": 177.595001,
"USDDKK": 6.8657,
"USDDOP": 45.400002,
"USDDZD": 107.014999,
"USDEEK": 14.325002,
"USDEGP": 8.029699,
"USDERN": 15.279969,
"USDETB": 21.022499,
"USDEUR": 0.920471,
"USDFJD": 2.157498,
"USDFKP": 0.648499,
"USDGBP": 0.650132,
"USDGEL": 2.395014,
"USDZWL": 322.355011
}
}
I need to get value of "USDGBP" from that string. How can I do that? Preferably stored as double.
Rather than converting it into NSString try converting it in NSDictionary using
NSError *error;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
then you can retrieve value of USDGBP like
double usdgbp = [jsonDict[#"quotes"][#"USDGBP"] doubleValue];
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
double usdgbpValue = [jsonDict[#"quotes"][#"USDGBP"] doubleValue];
you can find the value in the string simply extracting a string between 2 string.
NSString *jsonStr = #"long json string";
NSRange str1 = [jsonStr rangeOfString:#"\"USDGBP\":"];
NSRange str2 = [jsonStr rangeOfString:#","];
NSRange strSub = NSMakeRange(str1.location + str1.length, str2.location - str1.location - str1.length);
NSString *valueForUSDGBP = [jsonStr substringWithRange:strSub];
You should use NSJSONSerialization
NSData *jsonData = your data ... ;
NSError *theError = nil;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&theError];
if (theError) {
NSLog(#"%#", theError);
}
else {
double theValue = [jsonDict[#"quotes"][#"USDGBP"] doubleValue];
}
If you'd like to have much fun, use NSScanner to parse the string ;)
I have a NSArray which is based on JSON format. I requested it from the web and saved it in the array. I am trying to use a dictionary to get the values of "categoryname" and "subscore" and store them in new arrays, but they remain empty. Do I have to convert the array back to NSData using JSON serialisation or is there a more direct way to achieve this?
NSArray detailedscore:
{
"articles": [
{
"abstract": "text",
"title": "title"
}
],
"subscore": 3,
"categoryname": "Reporting"
},
{
"articles": [
{
"abstract": "text2",
"title": "title"
}
],
"subscore": 1,
"categoryname": "Power"
}]
}
Code:
for(int i = 0; i < [self.detailedscore count]; i++)
{
NSMutableDictionary * dc = [self.detailedscore objectAtIndex:i];
NSString * score = [dc objectForKey:#"subscore"];
NSString * categoryname = [dc objectForKey:#"categoryname"];
[self.allscores addObject:subscore];
[self.allcategories addObject:categoryname];
for (NSString *yourVar in allcategories) {
NSLog (#"Your Array elements are = %#", yourVar);
}
{} ----> means dictionary, []---> array..... this is a rule I follow while assinging the return value from webservices as NSArray or NSDictionary....
Depending on your current JSON format, perhaps this might give you an idea
NSMutableArray *categoryArray = [NSMutableArray new];
for (NSDictionary *childDict in self.detailedscore)
{
[categoryArray addObject:[childDict objectForkey:#"categoryname"]];
}
If you have the array use below code
for(int i = 0; i < [self.detailedscore count]; i++)
{
NSMutableDictionary * dc = [self.detailedscore objectAtIndex:i];
NSString * score = [dc objectForKey:#"subscore"];
NSString * categoryname = [dc objectForKey:#"categoryname"];
[self.allscores score];
[self.allcategories addObject:categoryname];
for (NSString *yourVar in allcategories) {
NSLog (#"Your Array elements are = %#", yourVar);
}
The problem wasn't in the array or dictionary or the web request. I didn't allocated the NSMutableArrays so they were empty all the time. The code works fine for extracting values from the array in case anyone wants to use it.
Hope this helps.
[NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (!connectionError) {
NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&connectionError];
NSLog(#"Dict %#",dict);
BOOL isValid = [NSJSONSerialization isValidJSONObject:dict];
if (isValid) {
[target getJSONFromresponseDictionary:dict forConnection:strTag error:connectionError];
}
else{
NSString *strResponse = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[target getStringFromresponseDictionary:strResponse forConnection:strTag error:error];
}
I have retrive following response form Server in JSON format which I have sucessfully store in NSDictionary.
{
"#companyName" = "MobileAPPSDeveloper";
"#generatedDate" = "8/6/13 2:41 AM";
"#version" = "1.0";
application = (
{
"#apiKey" = 234FXPQB36GHFF2334H;
"#createdDate" = "2013-03-01";
"#name" = FirstApp;
"#platform" = iPhone;
},
{
"#apiKey" = 3PF9WDY234546234M3Z;
"#createdDate" = "2013-02-01";
"#name" = SecondAPP;
"#platform" = iPhone;
},
{
"#apiKey" = NXGQXM2347Y23234Q4;
"#createdDate" = "2013-05-22";
"#name" = ThirdApp;
"#platform" = Android;
}
);
}
This is method I have used.
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
[self convertDataIntoDictionary:responseData];
}
-(void)convertDataIntoDictionary:(NSData*)data{
NSDictionary *dictionary;
if (data.length>0) {
NSError *parsingDataError;
dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parsingDataError];
if (parsingDataError) {
// [ErrorAlert showError:parsingDataError];
NSString *recievedString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Data Conversion Error When Parsing: %#", recievedString);
}
}
NSLog(#"Data back from server\n %#",dictionary);
NSArray *applicationDetails = dictionary[#"application"];
}
I can not go further then this?
I would like to get All NAME of APPS in Array.
Any help would be appreciate.
The basics of parsing JSON is:
{ }- dis represents dictionary
( )- dis represents array
So in your JSON, there is a dictionary at the root and inside it has a key application which cbntains an Array.
NSArray *applicationArray = [dictionary objectForKey:#"application"];
NSMutableArray *mutableAppNamesArray = [[NSMutableArray alloc]init];
Inside this array there are three NSDictionary at every index:
for(NSDictionary *dict in applicationArray){
NSString *appName = [dict objectForKey:#"#name"];
NSLog(#"app name : %#", appName);
[mutableAppNamesArray addObject:appName];
}
NSArray * appNamesArray = [NSArray arrayWithArray:mutableAppNamesArray];
I think this is not a proper format for JSON. JSON objects usually contain ':' instead of '='
Example :-
{
products_id: "476",
products_model: "XOLO Play",
products_price: "15499.0000",
products_image: "xolo-play-play-t1000-.jpg",
products_date_available: null,
products_last_modified: "2013-08-04 06:04:11",
products_date_added: "2013-08-04 06:03:10",
manufacturers_id: "17",
products_status: "1",
products_rating: null,
category_id: "11"
},
{
products_id: "18",
products_model: "Nokia Lumia 820",
products_price: "8990.0000",
products_image: "samsung-galaxy-ace-duos-gsm-mobile-phone-large-1.jpg",
products_date_available: null,
products_last_modified: "2013-07-30 03:45:28",
products_date_added: "2013-01-23 00:52:00",
manufacturers_id: "2",
products_status: "1",
products_rating: "3",
category_id: "11"
},
But if you still need to parse it then you might try as below:
First get into the array
by NSDictionary *array = [allValues objectForKey:#"application"]; then each index to NSDictionary and then object for key. If its your server response than try to make it in the proper JSON format.