I have an NSDictionary, named "thisList", and I need to get the value of its key "list_collection".
Xcode indicates that the value is a "NSSingleEntryDictionary".
The value itself contains an array with yet another dictionary.
Please take a look at the screenshot:
Now, no matter what I try (objectforKey/valueforKey) or whatever type of object I initialize (NSArray/NsMutableArray/NSDictionary/NSMutableDictionary) I end up with a nil value.
Apparently, I miss some essential knowledge on how to handle this.
My question: how should I initialize an object with the value of the key "list_collection".
Here is a (partial) dump of the json:
Printing description of thisList:
{
archived = 0;
"chapter_part" = "";
"chapter_title" = "";
comment = "";
"cover_id" = "<null>";
"created_at" = "2017-01-06T12:59:04.000+01:00";
"date_created" = "06 January 2017";
deleted = 0;
id = 141384502;
isMyList = 1;
keywords = (
);
"list_collection" = {
lists = (
{
"speech_locale" = EN;
subject = engels;
words = (
{
word = attitude;
},
The to me most logical approach would be:
NSDictionary * myDic = [thisList objectForKey:#"list_collection"];
Note: I didn't explicitly initialize 'myDic' here.
To put things in context, here is my code:
NSString * hlists = [json objectForKey:#"lists"];
NSData* data = [hlists dataUsingEncoding:NSUTF8StringEncoding];
NSArray *wrtsLists = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonParsingError];
Lists = [[NSMutableArray alloc]init];
for (NSDictionary *thisList in wrtsLists){
WordList* theList = [[WordList alloc]init];
theList.title = [thisList valueForKey:#"title"];
[Lists addObject:theList];
NSDictionary *myDic = thisList[#"list_collection"];
>>>>this is where I put a breakpoint. myDic is nil here
}
Thanks for your insights.
You can simply get "list_collection" array from "thisList" using by this code
NSDictionary *myDic = thisList[#"list_collection"];
In the end, I figured out, that it was an Xcode problem.
The Debug area just didn't correctly display the values of my objects.
I restarted Xcode, and things started to work as expected.
I lost several hours of my life on this. But I learned a lot, thanks to your good advises.
Try this hope it helps You
NSDictionary *myDic = [thelist valueForKey:"list_collection"];
I'm using the Edmunds API to return a JSON string of vehicle makes for a certain year.
The resulting NSDictionary looks like this:
makes = (
{
id = 200002038;
models = (
{ // not relevant
}
);
name = Acura;
niceName = acura;
},
{
id = 200001769;
models = (
{ // not relevant
}
);
name = "Aston Martin";
niceName = "aston-martin";
},
There are a lot more values in this dictionary...how can I loop through through the dictionary to retrieve each of the 'name' values?
I like valueForKeyPath because you can do so much with it and it's a one line solution. Tested this and it works in my dev setup. If you know your data is in a predictable format, then you can do amazing things with valueForKeyPath.
NSArray *makeNames = [makes valueForKeyPath:#"name"];
Great info on valueForKeyPath http://nshipster.com/kvc-collection-operators/
NSMutableArray *makeNames = [NSMutableArray new];
for (NSDictionary *make in makes) {
NSLog(#"Make name: %#", make[#"name"]);
[makeNames addObject:make];
}
NSLog(#"Makes array: %#", makeNames);
I am using the following type of object reference copy functionality throughout my iOS application.
e.g. objectA = objectB;
When you perform operation/changes on objectA it would automatically get reflected in objectB. You do not need to copy objectA to objectB again to reflect the changes in objectB, as they are pointing/referring to same location(address).
The problem is it was working fine till the iOS 8.2 however it seems to not work in iOS 8.3 at all.
Following is one of the code snippet which is not working correctly.
NSMutableDictionary *fieldObj = self.theData[indexPath.section ][indexPath.row];
// Adding text to data array
[fieldObj setObject:textField.text.stringByStrippingHTML forKey:#"value"];
NSLog(#"Line 1 \n%#",fieldObj);
NSLog(#"Line 2 \n%#",self.theData[indexPath.section][indexPath.row]);
From Above code Line 1 and Line 2 are giving same output upto iOS 8.2.
Line 1
{
name = Name;
required = NO;
type = 4;
value = asdfasdfasdfasdfsad;
}
Line 2
{
name = Name;
required = NO;
type = 4;
value = asdfasdfasdfasdfsad;
}
however in iOS 8.3 they are giving the different outputs.
Line 1
{
name = Name;
required = NO;
type = 4;
value = asdfasdfasdfasdfsad;
}
Line 2
{
name = Name;
required = NO;
type = 4;
value = "";
}
Am I doing anything wrong here?
If not does anyone know about the issue and how to solve it?
EDIT:
Sorry for the above misleading question, the reason behind above problem I found is that the indexPathForItemAtPoint:(CGPoint) is returning wrong indexPath in iOS 8.3 only.
The code I have used is as follow:
// retrieve indexpath from uitextfield
CGPoint pos = [textField convertPoint:CGPointZero toView:self.collectionView];
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:pos];
The above code is working fine upto iOS versions 8.2.
I made and easy snippet that I think it will reflect you actual situation: an immutable container with mutable container inside.
int main(int argc, const char * argv[]) {
#autoreleasepool {
// insert code here...
NSLog(#"Hello, World!");
NSArray * array = #[#{#"KEY" : #"OLD" }.mutableCopy];
NSMutableDictionary * dict = array.firstObject;
[dict setObject:#"NEW" forKey:#"KEY"];
NSLog(#"Mutated dict %#",dict);
NSLog(#"From original source %#",array.firstObject);
}
return 0;
}
Everything seems to work as expected, are you sure that you are doing something somewhere else?
2015-04-15 08:37:09.740 prova[912:117578] Mutated dict {
KEY = NEW; } 2015-04-15 08:37:09.741 prova[912:117578] From original source {
KEY = NEW; }
Also the both object have the same address as expected:
(lldb) expression dict (__NSDictionaryM *) $2 = 0x00000001003004a0 1
key/value pair (lldb) expression array.firstObject (__NSDictionaryM *)
$3 = 0x00000001003004a0 1 key/value pair
Try to set it as below.
NSMutableDictionary *fieldObj =
[
self.theData[indexPath.section ][indexPath.row]
mutableCopy
];
& check. I believe it will work.
I have a NSArray containing multiple NSDictionary object and this NSDictionary again has one array of some NSStrings/NSNumbers...
This NSArray looks like below...
(
{
"bins_arr" = (
531662,
549177,
540165,
546616,
549777,
549778,
549779,
532663,
549852,
529495,
532662,
529117,
533890,
544170,
554619,
542418,
540175,
552137,
542531,
542556,
552093,
540531,
552790,
541497,
554637,
526421,
431921,
412800,
431922,
464558,
508159,
456822,
450900,
508126,
508125,
517700,
430463,
414746,
461797,
438628,
461796,
510460,
520386,
421175,
455038,
524133,
518936,
455390,
405450,
456407,
438587,
405451,
493714,
549149
);
"issuing_School" = ABCDEF;
status = 0;
title = ABCDEF;
},
{
"bins_arr" = (
429393,
416644,
416645,
416643,
416646,
436390,
436389,
436388,
470613,
524253,
428306,
489604,
478893,
414767,
428348,
469645,
421493,
470614,
543705
);
"issuing_School" = PQRS;
status = 0;
title = "PQRS";
},
{
"bins_arr" = (
422316,
421560,
483541
);
"issuing_School" = TCSB;
status = 0;
title = "TCSB";
}
)
Now I need to find out a given NString/NSNumber inside the NSArray, if it gets found I need to fine corresponding issuing_School value as well, for example If I find 461797 so it should search it and find that issuing_School of this is PQRS.
One way of doing it is to get the each NSArray inside NSArray-->NSDictionary and loop through the whole NSArray and match the given number with the number present and in the NSArray, but I don't want this search since this NSArray have so may object of NSDictionary and all NSDictionary object again have big NSArray.
Can Any one suggest me some awesome view to achieve this.
Thanks in Advance.
Turn your arrays into sets.
NSArray* array = ...;
NSSet* set = [[NSSet alloc] initWithArray:array];
if ([set containsObject:aNumber]) ...
No loop involved. Constant time no matter how many elements in the set.
Array object at index 0---:
<Merchandise:AW9JgReRyQ:(null)>
{
ACL = "<PFACL: 0x201b2590>\";
CoverPhotos = "<ItemPhotos:L5ln3ZN5rm>\";
item = ugh;
listingprice = 356;
originalprice = "25)";
user = "<PFUser:KdRfesAJA3>";
},
I have implemented my iOS app using Parse.com
In that I have an array of objects (Array of dictionaries)
in those I have print the 1st object of that array..
I have some pre text Merchandise:AW9JgReRyQ:(null before every object / dictionary which is related to object id
i want to get the preText " Merchandise:AW9JgReRyQ:(null) " or atleast "AW9JgReRyQ"
How to do ..>?
Total entire array of all objects is
array-------
(
"<Merchandise:AW9JgReRyQ:(null)>
{\n ACL = \"<PFACL: 0x201b2590>\";\n CoverPhotos = \"<ItemPhotos:L5ln3ZN5rm>\";\n Photos = \"<PFRelation: 0x201bff80>(<00000000>.(null) -> ItemPhotos)\";\n brand = \"Baby Gap\";\n description = \"\\nFight\";\n item = ugh;\n listingprice = 356;\n originalprice = \"25)\";\n user = \"<PFUser:KdRfesAJA3>\";\n}",
"<Merchandise:bMPFijErWI:(null)>
{\n ACL = \"<PFACL: 0x201a2300>\";\n CoverPhotos = \"<ItemPhotos:4pm7vX7q26>\";\n Photos = \"<PFRelation: 0x2019a490>(<00000000>.(null) -> ItemPhotos)\";\n brand = \"3 Pommes\";\n description = Sett;\n item = udder;\n listingprice = 245;\n originalprice = 245;\n user = \"<PFUser:KdRfesAJA3>\";\n}"
)
It seems like you have two options for this. Either parse each one out into a string (definitely the less elegant/way uglier way). Or also it looks more likely that it could be an array of arrays that contain a string and dictionary.
If it ends up being the second option, you could easily just grab the object at index 0 twice to get the preText your looking for. However, if thats no avail..then you can just go for it like so:
//Convert your object into an NSString
NSString *converted = (NSString*)[yourArray objectAtIndex:i];
//Or..your may need to do NSString *converted = [NSString stringWithFormat:#"%#",[yourArray objectAtIndex:0]];
NSArray *firstSplitterArray = [converted componentsSeparatedByString:#"<"];//split by <
NSString *partialSplit = [splitterArray objectAtIndex:0];
NSArray *secondSplitterArray = [partialSplit componentsSeparatedByString:#">"];//split by >
NSString *yourPreText = [secondSplitterArray objectAtIndex:0];//final step
//now yourPreText should equal Merchandise:AW9JgReRyQ:(null)
I wrote this according to your first code snippet. If there is actually a leading quotation mark or something, you'll need to change your indexes. But this gives you the idea. Just do some print statements to verify your arrays at each step and you will be good to go. Not the cleanest, but if your in a pinch this could work.