I would like to get the value of NO (from the plist under) into a NSString i got. But I'm stuck.
I used the following code:
//Load Dictionary with wood name cross refference values for image name
NSString *plistCatPath = [[NSBundle mainBundle] pathForResource:#"Numbers" ofType:#"plist"];
NSDictionary *numberDictionary = [[NSDictionary alloc] initWithContentsOfFile:plistCatPath];
self.numberArray = numberDictionary[#"Two"];
// ,[codeForCountryDictionary objectForKey:selectedCountryPicker]
number = [self.policeArray valueForKey:#"NO"];
NSLog(#"Numero: %#", number);
But then I got:
(
012
)
and I only want 012, not with the parentheses.
My Plist:
the "NO" is a NSString key in the "Two" NSDictionary and NSString "012" is the value, for the key "NO"
NSDictionary * dict = numberDictionary[#"Two"];
for (NSString * key in dict) {
NSLog(#"%# %#", key, dict[key]);
}
If you want to get the key for a value from NSDictionary, use
NSDictionary * dict = numberDictionary[#"Two"];
NSArray *temp = [dict allKeysForObject:#"012"];
NSString *key = [temp lastObject];
Note: allKeysForObject returns an NSArray, as more keys, may have the same value assigned
Related
In my application I need to build an url like :
https://www.thefootballapi/football/league1/player/stats
In order to be able to build the url, I need to access the objects in an NSDictionary, since NSDictionary is an unordered data set, I need to sort the objects alphabetically in order to build the correct url:
NSDictionary
{
category = "football";
league = " League1 " ;
section = player;
"sub_category" = "stats";
}
I have tried doing this by writing this block of code:
Accessing the objects:
NSArray *keyyy0= [self.redirect allKeys];
id aaKey0 = [keyyy0 objectAtIndex:0];
id aanObject0 = [self.redirect objectForKey:aaKey0];
NSArray *keys = [self.redirect allKeys];
id aKey = [keys objectAtIndex:1];
id anObject = [self.redirect objectForKey:aKey];
NSArray *keyyy = [self.redirect allKeys];
id aaKey = [keyyy objectAtIndex:2];
id aanObject = [self.redirect objectForKey:aaKey];
and building the full url like this :
NSString *fullurl = [NSString stringWithFormat:#"%#%#%#%#", newurl,anObject,aanObject,aanObject3 ];
This method works fine for now, however I was wondering if this is the correct way of doing this ? is there a better way of implementing this ?
For example as it's mentioned here : Joe's answer ,NSURLQueryItem is used to access objects from dictionaries and build queries from it, however when I used NSURLQueryItem the full url was built with ? and = signs.
Are there any other methods that can be used to just get all of the objects in an NSDictionary ?
When accessing values from an NSDictionary there's no guarantee what type it will be. With full type-checking, a safer and more readable way of creating your URL might be something like:
NSDictionary *redirect = #{#"category" : #"football",
#"league" : #" League1 ",
#"section" : #"player",
#"sub_category" : #"stats"};
id category = redirect[#"category"];
id league = redirect[#"league"];
id section = redirect[#"section"];
id subCategory = redirect[#"sub_category"];
if ([category isKindOfClass:[NSString class]] &&
[league isKindOfClass:[NSString class]] &&
[section isKindOfClass:[NSString class]] &&
[subCategory isKindOfClass:[NSString class]])
{
NSString *urlString = [NSString stringWithFormat:#"https://www.thefootballapi/%#/%#/%#/%#",
[((NSString*)category).lowercaseString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]],
[((NSString*)league).lowercaseString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]],
[((NSString*)section).lowercaseString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]],
[((NSString*)subCategory).lowercaseString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
NSLog(#"%#", urlString); // https://www.thefootballapi/football/league1/player/stats
}
This also ensures the URL is generated as you wanted (lowercase "league1" without leading/trailing whitespace) given your input JSON.
Try this code.
//Your Dictionary
NSMutableDictionary *dict = [NSMutableDictionary new];
[dict setValue:#"football" forKey:#"category"];
[dict setValue:#"League1" forKey:#"league"];
[dict setValue:#"player" forKey:#"section"];
[dict setValue:#"stats" forKey:#"sub_category"];
// Get desired URL like this
NSArray *arr = [[dict allValues] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSString *strURL = [NSString stringWithFormat:#"https://www.thefootballapi/%#/%#/%#/%#", [arr objectAtIndex:0], [arr objectAtIndex:1], [arr objectAtIndex:2], [arr objectAtIndex:3]];
NSLog(#"%#", strURL);
It will return ULR same as you want : https://www.thefootballapi/football/League1/player/stats
NSDictionary *myDict = #{#"one":#"1",#"two":#"2"};
for (NSDictionary* tmp in myDict) {
NSLog(#"%#",tmp);
}
resut:
my tmpis NSString
I want to get a dictionary with key= one , value = 1
for in for NSDictionary will iterate the keys.
for (NSString * key in myDict) {
NSLog(#"%#",key);
NSString * value = [myDict objectForKey:key];
}
If you want to get a dictionary. You have to create a dictionary from these values
for (NSString * key in myDict) {
NSLog(#"%#",key);
NSString * value = [myDict objectForKey:key];
NSDictionary * dict = #{key:value};
}
Or you should init like this:
NSArray *arrDict = #[{#{"one":#"1"},#{#"two":#"2"}];
for (NSDictionary* tmp in arrDict) {
NSLog(#"%#",tmp);
}
You can get all keys from your dic then add the key and value to your new dic like this:
NSDictionary *myDict = #{#"one":#"1",#"two":#"2"};
NSArray *keys = [myDict allKeys];
for (NSString *key in keys) {
NSDictionary *yourDic = #{key: [myDict valueForKey:key]};
NSLog(#"%#", yourDic);
}
You didn't create it that way. If you wanted to have a NSDictionary inside another NSDictionary you should write something like this :
NSDictionary *myDict = #{
#"firstDict" : #{
#"one":#"1"
},
#"secondDict": #{
#"two":#"2"
}
};
Above code will create a NSDictionary with two dictionaries at keys #firstDict and #secondDict.
Also, bear in mind, that because dictionaries are key-value pairs, using a for-in loop, actually loops through the keys in that dictionary. So your code is equivalent to:
for(NSString *key in dict.allKeys) { ... }
I got the solution
NSDictionary *myDict = #{#"one":#"1",#"two":#"2"};
NSMutableArray *arrayObject = [[NSMutableArray alloc]init];
NSMutableArray *arrayKey = [[NSMutableArray alloc]init];
NSMutableArray *arrayObjectKey = [[NSMutableArray alloc]init];
NSMutableDictionary *dict = [[NSMutableDictionary alloc]init];
for (NSString *stringValue in myDict.allValues)
{
[arrayObject addObject:stringValue];
}
for (NSString *stringKey in myDict.allKeys)
{
[arrayKey addObject:stringKey];
}
for(int i = 0;i<[arrayKey count];i++)
{
dict = [[NSMutableDictionary alloc]initWithObjectsAndKeys:[NSString stringWithFormat:#"%#",[arrayKey objectAtIndex:i]],#"key",nil];
[dict setObject:[NSString stringWithFormat:#"%#",[arrayObject objectAtIndex:i]] forKey:#"value"];
[arrayObjectKey addObject:dict];
}
NSLog(#"The arrayObjectKey is - %#",arrayObjectKey);
The Output is
The arrayObjectKey is -
(
{
key = one;
value = 1;
},
{
key = two;
value = 2;
}
)
Create the dictionary:
NSDictionary *myDict = [NSDictionary dictionaryWithObjectsAndKeys:#"1",#"One",#"2","Two",nil];
Get a value out using:(this example tmp will be 1)
NSString *tmp = [myDict objectForKey:#"One"];
Display the output in console:
NSLog(#"%#",tmp);
To display the whole NSDictionary
NSLog (#"contents of myDict: %#",myDict);
What you are doing is creating a dictionary with key-value pairs. I think what you want to do is have an array with dictionaries.
NSArray *myArray = #[#{#"one":#"1"}, #{#"two":#"2"}];
for (NSDictionary* tmp in myArray) {
NSLog(#"%#",tmp);
}
However I don't see a point in doing this. What you could do is:
NSDictionary *myDict = #{#"one":#"1",#"two":#"2"};
for (NSString* key in [myDict allKeys]) {
NSLog(#"%# = %#", key, myDict[key]);
}
I've already looked at Parse Plist (NSString) into NSDictionary and deemed it to be not a duplicate, as that question and its answer do not address my concerns.
I have a .plist file in the file system structured like this:
The source code of this .plist file looks like this:
{
"My App" = {
"Side Panel" = {
Items = {
Price = "#123ABC";
};
};
};
}
I know how to get an item in the Root like this:
[[NSBundle mainBundle] pathForResource:#"filename" ofType:#"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSString value = [dict objectForKey:#"key"]);
But what if the structure is like mine, with tiered dictionaries? How do I get the value of Price?
I would like to do this all in one method, ideally like this:
Calling
NSString *hexString = [self getColorForKey:#"My App.Side Panel.Items.Price"];
Definition
- (NSString *) getColorForKey: (NSString *)key
{
NSArray *path = [key componentsSeparatedByString:#"."];
NSDictionary *colors = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Colors" ofType:#"plist"]];
NSString *color = #"#FFFFFF"; // white is our backup
// What do I put here to get the color?
return color;
}
Here's the solution that worked for me:
+ (NSString*) getHexColorForKey:(NSString*)key
{
NSArray *path = [key componentsSeparatedByString:#"."];
NSDictionary *colors = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Colors" ofType:#"plist"]];
NSString *color = #"#FFFFFF";
for (NSString *location in path) {
NSObject *subdict = colors[location];
if ([subdict isKindOfClass:[NSString class]])
{
color = (NSString*)subdict;
break;
}
else if ([subdict isKindOfClass:[NSDictionary class]])
{
colors = (NSDictionary*)subdict; // if it's a dictinoary, our color may be inside it
}
else
{
[SilverLog level:SilverLogLevelError message:#"Unexpected type of dictinoary entry: %#", [subdict class]];
return color;
}
}
return color;
}
where key is an NSString that matches /^[^.]+(\.[^.]+)*$/, meaning it looks like my targeted #"My App.Side Panel.Items.Price".
Yes I understand what you're looking to accomplish; thank you for the clarification. I will however add that the resources and advice I have written do provide the necessary information resolve your problem.
That said, the following gets your dictionary:
NSURL *plistURL = [[NSBundle mainBundle] URLForResource:#"Info" withExtension:#"plist"];
NSData *plistData = [NSData dataWithContentsOfURL:plistURL];
NSDictionary *tieredPlistData = [NSPropertyListSerialization propertyListWithData:plistData
options:kCFPropertyListImmutable
format:NULL
error:nil];
Then, if we're interested in the information contained in Items
NSDictionary *allItemsDictionary = tieredPlistData[#"My App"][#"Side Panel"][#"Items"];
Assuming that Items will contain a number of objects, you could use
NSArray *keys = [allItems allKeys];
for(NSString *key in keys){
NSString *colorValue = allItemsDictionary[key];
// do something with said color value and key
}
Or, if there is a single value you need, then just reference that key
NSString *colorForPriceText = allItemsDictionary[#"Price"];
But a few tips:
It's generally considered a better idea to keep frequently accessed values in code instead of a plist/file that is loaded at runtime.
That said, you wouldn't put your call to load from NSBundle in the same method you would use to query a specific value. In your example, every time you need a color, you end up re-accessing NSBundle and pile on unneeded memory allocations. One method would load the plist into an iVar NSDictionary and then that NSDictionary would be used separately by another method.
I have a NSDictionary and make a copy of NSDictionary:
NSDictionary *immutableDict = (NSDictionary *)json;
NSMutableDictionary *mutableDict = [immutableDict mutableCopy];
I want to convert this into a NSString selection category for then edit contain.
NSString * name = [mutableDict objectForKey:#"category"];
name = [name stringByAppendingString:[NSString stringWithFormat:#"mytexttoadd"]];
But when I want to change this NSString my app crash because the NSString is a NSCFArray ..
How can make this a NSString so I can edit it?
How do i retrieve the value for key in a NSDictionary is the value already has quotes arround it
Code:
for(NSDictionary *dict in jsonData)
{
NSString *firstName = [dict valueForKey:#"name_forenames"];
NSString *lastName = [dict valueForKey:#"name_surnames"];
NSLog (#"%# %#", firstName, lastName);
}
in my dictionary which is :
(
{
"name_forenames" = Jordan;
"name_surnames" = Newton;
}, {
"name_forenames" = Jordan;
"name_surnames" = Newton;
}
)
because it just returns null in my NSLog
The dictionary keys do not really contain quotation marks, that's only how the
description method of a dictionary shows strings that contain special characters.
So
NSString *firstName = [dict objectForKey:#"name_forenames"];
or the new syntax
NSString *firstName = dict[#"name_forenames"];
should just work.
Note that objectForKey: is the dedicated method to retrieve dictionary values.
valueForKey: is for Key-Value Coding trickery.
You insert backslash in front of the quotation mark \".
NSString *firstName = [dict valueForKey:#"\"name_forenames\""];