Whats is the best way to parse this out?
String:
UMversion=2.9&UMstatus=Approved&UMauthCode=152058&UMrefNum=59567592&UMavsResult=Address%3A%20Match%20%26%205%20Digit%20Zip%3A%20Match&UMavsResultCode=YYY&UMcvv2Result=Match&UMcvv2ResultCode=M&UMresult=A&UMvpasResultCode=&UMerror=Approved&UMerrorcode=00000&UMcustnum=&UMbatch=1&UMbatchRefNum=91016&UMisDuplicate=N&UMconvertedAmount=&UMconvertedAmountCurrency=840&UMconversionRate=&UMcustReceiptResult=No%20Receipt%20Sent&UMprocRefNum=&UMcardLevelResult=A&UMauthAmount=10&UMfiller=filled
I get this back from the web service as one big long string. Each of the variables are listed then they have a = sign then what I need to populate the variable with.
I need to get all of this data into variables to check them.
So, how should I go about breaking it down.
Use this kind of code:
NSArray* components = [veryLongString componentsSeparatedByString:#"&"]; // array of strings like "x=y"
NSMutableDictionary* parsedResult = [NSMutableDictionary new];
for (NSString* keyValuePair in components) {
NSArray* keyAndValue = [keyValuePair componentsSeparatedByString:#"="];
NSString* key = keyAndValue[0];
NSString* value = (keyAndValue.count>1) ? keyAndValue[1] : nil;
// remove percent escapes in case we have URL-encoded characters in the value like '%20' and the like
parsedResult[key] = [value stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] ?: [NSNull null];
}
NSLog(#"dictionary of parameters: %#", parsedResult);
You will end up with a dictionary containing the keys and values extracted from your string.
NSString* firstPass = [sourceString stringByReplacingOccurrencesOfString:#"&" withString:#"\",\""];
NSString* secondPass = [firstPass stringByReplacingOccurrencesOfString:#"=" withString:#"\":\""];
NSString* grandFinale = [NSString stringWithFormat:#"{\"%#\"}"];
NSData* jsonSource = [grandFinale dataUsingEncoding:NSUTF8Encoding];
NSError* error = nil;
NSDictionary* theBiggie = [NSJSONSerialization JSONObjectWithData:jsonSource options:0 error:&error];
I think NSJSONSerialization will automagically fix up the percent encoding. If not, run grandFinale through stringByRemovingPercentEncoding.
Related
I am getting String data from server in the format below. I want to get the value for every tag like phonenumber and name etc. I am able to convert it in array by comma separator. how to get individual values?
Company:Affiliated CO,Organization:TECHNICAL EDUCATION
SOCIETY,Organization:SINHGAD,Organization:National Basketball Association,Person:Parikshit N. Mahalle,PhoneNumber:81 98 22 416 316,PhoneNumber:9120-24100154,Position:Professor,SportsEvent:NBA.
Say your original string is stored in rawString.
You need to :
1) split the string by ,
NSArray *pieces = [rawString componentsSeparatedByString:#","];
2) for each item in this array, split it by :, and add it to a dictionary :
NSMutableDictionary *dict = [NSMutableDictionary new];
for (NSString *piece in pieces) {
NSArray *splitPiece = [piece componentsSeparatedByString:#":"];
// key is at splitPiece[0], value is at splitPiece[1]
dict[splitPiece[0]] = splitPiece[1];
}
Then you'll have a dictionary of what you wanted in the first place.
But as suggested in the comments, it would be far better (and more flexible) for you to receive JSON data.
Edit: your original string shows there are multiple fields named Organization. The code I've given is not designed to handle such cases, it's up to you to build upon it.
If this data is not being returned as a JSON object then you'll have to go with #Clyrille answer. But if it is JSON then NSJSONSerialization:JSONObjectWithData:options:error: will be the way to go.
EXAMPLE
NSDictionary *json = [NSJSONSerialization
JSONObjectWithData:/*urlResponse*/ options:0 error:nil];
NSString *company = [json objectForKey:#"Company"];
NSString *Organization = [json objectForKey:#"Organization"];
NSString *Person = [json objectForKey:#"Person"];
NSString *PhoneNumber = [json objectForKey:#"PhoneNumber"];
NSString *Position = [json objectForKey:#"Position"];
NSString *SportsEvent = [json objectForKey:#"SportsEvent"];
I am new to objective-c but I am trying to render out a simple UItableview, filling it with data from my REST service coded in asp.net. The service takes data from SPs run on SQL servicer and using the JSONSerailzer class spits out a JSON string. I have verified it is a valid JSON string by pasting the output to an online JSON viewer.
Example as follows (This is exactly how my service returns it):
{"d":"[{\"callref\":12345,\"user\":\"foo\",\"name\":\"bar\"},{\"callref\":54321,\"user\":\"bar\",\"name\":\"foo\"}]"}
I can get the data in to objective-c fine via:
id result = [NSJSONSerialization JSONObjectWithData:webData options:kNilOptions error:&error];
However when I try to step into this result either by casting as NSDictionary or NSArray but the result always ends up as NSCFString and because of that it crashes my code when I try to enter a for loop.
NSArray *allItems = [result objectForKey:#"d"];
for (int i=0; i<allItems.count; ++i) {
NSDictionary *item = [allItems objectAtIndex:i];
NSString *callref=[item objectForKey:#"callref"];
NSString *user=[item objectForKey:#"user"];
NSString *name=[item objectForKey:#"name"];
}
What am I missing here? Any help greatly appreciated! Thanks in advance.
The JSON being returned from the server is not what you expect it to be, by the look of it.
It's a dictionary (see the outer { and }), however it contains a key of "d" and a string value of "[{\"callref\" ..." (note the first double-quote and the escaped inner double-quotes).
So first job is to fix the server, which is off-topic to your question.
After that, it should be as simple as:
NSDictionary* result = [NSJSONSerialization JSONObjectWithData:webData
options:kNilOptions
error:&error];
NSArray *keys = [result allKeys];
for (NSString *key in keys) {
NSArray *array = result[key];
for (NSDictionary *item in array) {
NSString *callref = item[#"callref"];
NSString *user = item[#"user"];
NSString *name = item[#"name"];
}
}
Say we have the following dictionary:
dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:currentItem], #"item number",
[NSNumber numberWithInt:([[item valueForKey:#"section"] intValue]+1)], #"section number",
currentDate, #"date of item",
[NSNumber numberWithDouble:timeDifference], #"time difference in millis",
nil];
Then I get the following output:
{
"time difference in millis" : 5.220093071460724,
"section number" : 1,
"date of item" : "28/04/2014 15:56:54,234",
"item number" : 3
}
I use the following code to convert the dictionary to JSON:
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonString = [[NSString alloc] initWithBytes:[jsonData bytes] length:[jsonData length] encoding:NSUTF8StringEncoding];
jsonString = [jsonString stringByReplacingOccurrencesOfString:#"\\" withString:#""];
How can I manipulate the order in which the JSON string shows its keys. For example, I would like to have:
{
"item number" : 3,
"section number" : 1,
"date of item" : "28/04/2014 15:56:54,234",
"time difference in millis" : 5.220093071460724
}
or something else. The point is that I want control over this process. How do I get it? My first thought was writing a parser that shows the ordering in the way that I want.
Here are similar questions, but my emphasis is on manipulating the order instead of just recreating the order in which I put it from the dictionary.
JSON format: getting output in the correct order
Need JSON document that is generated to be in same order as objects inserted in NSMutableDictionary in iOS
NSDictionary is not ordered by definition.
Easiest will be to wrap everything into NSArray if you want to have same order.
To restate the question: how to take an inherently unordered input, produce a string who's specification is inherently unordered, but control the ordering of that string.
Reformatting the dictionary as an array would let you control input ordering, but produce a different output format.
The only reason I can imagine wanting to do this is if wish to use the JSON string not as JSON, but just as a string. The question can then be restated as just lexically reformatting the string.
How general purpose must it be? Can we assume that the JSON has simple, scalar values? Then...
- (NSString *)reorderJSON:(NSString *)json keys:(NSArray *)orderedKeys {
NSArray *splitJson = [json componentsSeparatedByString:#","];
NSMutableArray *splitResult = [NSMutableArray array];
for (NSString *key in orderedKeys) {
for (NSString *splitPair in splitJson) {
if ([self jsonPair:splitPair hasKey:key]) {
NSString *trimmedSplitPair = [splitPair stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"{}"]];
[splitResult addObject:trimmedSplitPair];
}
}
}
NSString *joinedResult = [splitResult componentsJoinedByString:#","];
return [NSString stringWithFormat:#"{%#\n}", joinedResult];
}
- (BOOL)jsonPair:(NSString *)pair hasKey:(NSString *)key {
// pair should begin with double quote delimited key
NSString *trimmedPair = [pair stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSArray *splitPair = [trimmedPair componentsSeparatedByString:#"\""];
return [splitPair[1] isEqualToString:key];
}
Call it like this:
- (void)testJson {
NSDictionary *d = #{ #"time difference in millis": #5.220093071460724,
#"section number": #1,
#"date of item" : #"28/04/2014 15:56:54,234",
#"item number": #3};
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:d options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonString = [[NSString alloc] initWithBytes:[jsonData bytes] length:[jsonData length] encoding:NSUTF8StringEncoding];
NSArray *orderedKeys = #[ #"item number", #"section number", #"date of item", #"time difference in millis"];
NSString *result = [self reorderJSON:jsonString keys:orderedKeys];
NSLog(#"%#", result);
}
You shouldn't want that. Dictionaries have no order and writing some code that uses the order will just lead to problems in the future.
That said, if you want to, you can write your own code to generate the JSON string from your (ordered) array of keys and dictionary of values.
This question already has answers here:
Remove characters from NSString?
(6 answers)
Closed 8 years ago.
I am getting string from json dictionory but result string is in brackets, i have to get string without backets
code is
jsonDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&error];
NSDictionary *dictResult = [jsonDictionary objectForKey:#"result"];
NSDictionary *dictPronunciations = [dictResult valueForKey:#"pronunciations"];
NSDictionary *dictAudio = [dictPronunciations valueForKey:#"audio"];
NSString *strMp3Path = [dictAudio valueForKey:#"url"];
NSLog(#"str mp3 path %#",strMp3Path);
and result is
(
(
"/v2/dictionaries/assets/ldoce/gb_pron/abate0205.mp3"
)
)
I want to get /v2/dictionaries/assets/ldoce/gb_pron/abate0205.mp3 as a string without brackets. Please help...
The object you are logging is not a NSString instance. it is a string inside an array in an array.
try:
NSLog(#"str mp3 path %#",strMp3Path[0][0]);
if this prints as desired, the object dictAudio holds with the key url is an array, with an array. you should fix that where ever you stick it into the dictionary.
Try with following code:
NSMutableArray *myArray = [dictAudio valueForKey:#"url"];
NSString *myStr = [[myArray objectAtIndex:0] objectAtIndex:0];
NSLog(#"%#", myStr);
Use this code. If your values are multiple from json then the value can be added one by one without braces :
NSMutableArray *dictPronunciations = [dictResult valueForKey:#"pronunciations"];
NSMutableArray *arrayPronunciations = [[NSMutableArray alloc] init];
for (int i = 0; i< [dictPronunciations count]; i++)
{
NSString *string = [dictPronunciations objectAtIndex:i];
NSLog(#"String = %#",string);
[arrayPronunciations addObject:string];
}
NSLog(#"Array Pronounciations = %#",arrayPronunciations);
I am trying to parse some json data with SBJson to show the current temperature. The example code from this tutorial works perfect: Tutorial: Fetch and parse JSON
When I change the code to my json feed i get a null. I am kind of new to JSON but followed every tutorial and documentation I found. The json source i used: JSON Source
My code with sbjson:
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
self.responseData = nil;
NSArray* currentw = [(NSDictionary*)[responseString JSONValue] objectForKey:#"current_weather"];
//choose a random loan
NSDictionary* weathernow = [currentw objectAtIndex:0];
//fetch the data
NSNumber* tempc = [weathernow objectForKey:#"temp_C"];
NSNumber* weatherCode = [weathernow objectForKey:#"weatherCode"];
NSLog(#"%# %#", tempc, weatherCode);
and of course I have already implemented the other sbjson code.
There is no current_weather key in the JSON data you posted. The structure is:
{ "data": { "current_condition": [ { ..., "temp_C": "7", ... } ], ... } }
Here's a visual representation:
Therefore, to get to temp_C, you'd need to first obtain the top-level data property:
NSDictionary* json = (NSDictionary*)[responseString JSONValue];
NSDictionary* data = [json objectForKey:#"data"];
then, from that, obtain the current_location property:
NSArray* current_condition = [data objectForKey:#"current_condition"];
and finally, from the current_location array, get the element you're interested in:
NSDictionary* weathernow = [current_condition objectAtIndex:0];
Also note that temp_C and weatherCode are strings, not numbers. To transform them to numbers, instead of:
NSNumber* tempc = [weathernow objectForKey:#"temp_C"];
NSNumber* weatherCode = [weathernow objectForKey:#"weatherCode"];
you could use something like:
int tempc = [[weathernow objectForKey:#"temp_C"] intValue];
int weatherCode = [[weathernow objectForKey:#"weatherCode"] intValue];
(or floatValue / doubleValue if the value is not supposed to be an int, but rather a float or a double)
You would then use %d (or %f for float / double) as a format string:
NSLog(#"%d %d", tempc, weatherCode);
Provided link returns json without current_weather parameter. There is only current_condition parameter, please review this.
Use NSJSONSerialization instead of JSONValue.
NSData* data = [responseString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary* jsonDict = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:&error];
NSLog(#"jsonDict:%#",jsonDict);
In your link, there is no current_weather key.
NSString* tempc = [[[[jsonDict objectForKey:#"data"] objectForKey:#"current_condition"] objectAtIndex:0] objectForKey:#"temp_C"];