Objective-c NSMutableDictionary set with an array keep empty - ios

I'm new here, but I use to read this site when I need something, but today, I can't find an answer to my question.
I'll try to explain my problem with enough details.
I need to add an array into a NSMutableDictionary at a specific key. The key added into it is correctly up, but my dictionary value keep empty. Here is my code :
dictionarySection = [[NSMutableDictionary alloc] initWithObjects:arraySectionValues forKeys:arraySectionKeys];
dictionaryClip = [[NSMutableDictionary alloc] initWithCapacity:[arraySectionKeys count]];
NSArray *tabSection = [dictionarySection allKeys];
id key,value;
for (int j=0; j<tabSection.count; j++)
{
array = [NSMutableArray array];
key = [tabSection objectAtIndex: j];
value = [dictionarySection objectForKey: key];
//NSLog (#"Key: %# for value: %#", key, value);
for (SMXMLElement *clip in [books childrenNamed:#"clip"]) {
if([[clip valueWithPath:#"categorie"] isEqualToString:value]){
[array addObject:[clip valueWithPath:#"titre"]];
}
}
NSLog(#"Test array %#",array);
[dictionaryClip setObject:array forKey:key];
[array removeAllObjects];
NSLog(#"Test dictionary %#",dictionaryClip);
}
Here the NSLog result :
2015-07-15 14:34:48.272 test[15533:390301] Test array (
"CDS : ITV Philippe Dunoyer",
"FLASH INFO NCI : crise des banques",
"Les Roussettes sont-elles dangereuses ?",
"Flash infos banques gr\U00e8ve",
"CDS : ITV Paul Langevin",
"CDS : ITV Valls",
"CDS : ITV Victor Tutugoro",
"CDS : ITV Roch Wamytan",
"NCGLAN 20",
"Flash Info : dispositif anti-d\U00e9linquance"
)
2015-07-15 14:34:48.273 test[15533:390301] key : 0
2015-07-15 14:34:48.273 test[15533:390301] Test dictionary {
0 = (
);
}
As we can see, the array is filled, the dictionary's key is correct, but the array isn't into my dictionary.
How may I suppose to fill my dictionary with this array?
Thanks a lot guy(s) for answer(s) :)
Ps : excuse my english :(

You are calling removeAllObjects: method for same instance of array which you are passing in dictionary so it objects are being removed in stored array. Try to pass that array's copy or a new instance of array with same objects.
Example:
[dictionaryClip setObject:[array copy] forKey:key];

In Objective-C arrays are reference types.
The method setObject:forKey: puts a pointer to the array into the dictionary, the array is not copied.
If you remove all objects from the array, they also disappear in the dictionary

Related

Enumerating all the Keys and Values

From API, I am able to get below format.
{
"status": true,
"data": {
"29": "Hardik sheth",
"30": "Kavit Gosvami"
}
}
In that, I want to fetch Key and value both.
How can i do this using NSDictionary?
Sometime, you need to iterate over all the key/value pairs in a dictionary. To do this, you use the method -allKeys to retrieve an array of all the keys in the dictionary; this array contains all the keys, in no particular (ie random) order. You can then cycle over this array, and for each key retrieve its value. The following example prints out all the key-values in a dictionary:
void
describeDictionary (NSDictionary *dict)
{
NSArray *keys;
int i, count;
id key, value;
keys = [dict allKeys];
count = [keys count];
for (i = 0; i < count; i++)
{
key = [keys objectAtIndex: i];
value = [dict objectForKey: key];
NSLog (#"Key: %# for value: %#", key, value);
}
}
As usual, this code is just an example of how to enumerate all the entries in a dictionary; in real life, to get a description of a NSDictionary, you just do NSLog (#"%#", myDictionary);.
Are you using Swift or Objective-C?
In Objective-C you'd use allKeys to get the list of keys, as outlined by #BhavinSolanki in his answer.
In Swift you could do that as well (using the Swift Dictionary keys property, myDictinoary.keys)
Alternately you could use tuples to loop through the keys and values:
for (key, value) in dictionary {
NSLog (#"Key: %# for value: %#", key, value);
}

NSArray objects addresses

So unlike C where an array = &array = &array[0], was trying to have a quick look at the structure of a NSArray and how its objects were stored and have a question with the below code.
NSString *str1 = [NSString stringWithFormat:#"abc"];
NSString *str2 = [NSString stringWithFormat:#"xyz"];
NSString *str3 = [NSString stringWithFormat:#"123"];
NSMutableArray *someArray = (NSMutableArray*)#[#"1",#"2",#"3"];
NSMutableArray *original = (NSMutableArray*)#[str1, str2, [someArray mutableCopy]];
NSMutableArray *deep = [original mutableCopy];
[[original objectAtIndex:2] addObject:str3];
for (id obj in original) {
NSLog(#"\nIn Original:: \nvalue is:%#, at :%p; Address of object: %p\n",obj, obj, &obj);
}
for (id obj in deep) {
NSLog(#"\nIn Deep:: \nvalue is:%#, at :%p; Address of object: %p\n",obj, obj, &obj);
}
NSLog(#"\n Address of Original : %p \n", &original);
NSLog(#"\n Address IN Original : %p \n", original);
NSLog(#"\n Address in first object of original : %p \n", [original objectAtIndex:0]);
Sample o/p.
In Original::
object is:abc, at :0x7f8a5a58e750; Address of object pointer is : 0x7fff50cdd750
object is:xyz, at :0x7f8a5a58ff70; Address of object pointer is : 0x7fff50cdd750
object is:(
1,
2,
3,
123
), at :0x7f8a5a591200; Address of object: 0x7fff50cdd750
In Deep::
object is:abc, at :0x7f8a5a58e750; Address of object pointer is : 0x7fff50cdd708
object is:xyz, at :0x7f8a5a58ff70; Address of object pointer is : 0x7fff50cdd708
object is:(
1,
2,
3,
123
), at :0x7f8a5a591200; Address of object pointer: 0x7fff50cdd708
Address of Original : 0x7fff50cdd760
Address IN Original : 0x7f8a5a591230
Address in first object of original : 0x7f8a5a58e750
Im getting the same address for &obj for all the elements in the arrays above. Anything Im missing here? Thanks for your help.
The obj is a pointer which holds the address of another variable. If you change the value of that pointer it won't change it's address. In details,
id obj = original[0];
If you use
NSLog(#"%p",obj);
It'll print the address of the object contained in original[0]. And if you use
NSLog(#"%p",&obj);
It'll print the address of obj.
So even if you change the value like:
obj = original[1];
NSLog(#"%p",&obj);
Will give you same pointer address (Address of obj is not changing only the value of obj is changing)
-[NSArray mutableCopy] doesn't do a deep copy. Even if it did, those are constant strings you're trying to copy. NSString is immutable, so actually making a copy would be a waste of time and memory.
If you want to do a deep copy on an array, you need to do something like this:
NSMutableArray *copiedArray = [NSMutableArray new];
for (id obj in originalArray) {
[copiedArray addObject:[obj copy]];
}
Of course, this only works if all of the objects in your array support NSCopying.
You could get clever and make a category on NSArray that does something similar. You should check, though, that all of your objects conform to NSCopying.

iOS sort one array based on order of strings in another array

This is another very specific problem I am trying to solve.
I am pulling a list a twitter user accounts logged into the users settings application. This returns an array with the usernames in the correct order.
I then pass this array to this twitter API:
https://api.twitter.com/1.1/users/lookup.json
The returned array contain all the additional data I need for each user account logged in. The first array contains NSStrings (usernames), the returned array has been parsed to contain dictionaries that have a key and value for the username, name, and profile pic.
Problem now is that the order is completely different than the first array I passed.. This is expected behavior from Twitter, but it needs to be in the exact same order (I will be referencing the original index of the AccountStore which will match the first array, but not the new array of dictionaries).
How can I tell the new array to match the contained dictionaries to be the same order as the first array based on the username key?
I know this sounds confusing, so let me at least post the data to help.
Here is the first array output:
(
kbegeman,
indeedyes,
soiownabusiness,
iphonedev4me
)
Here is what the second array outputs:
(
{
image = "https://si0.twimg.com/profile_images/3518542448/3d2862eee546894a6b0600713a8de862_normal.jpeg";
name = "Kyle Begeman";
"screen_name" = kbegeman;
},
{
image = "https://si0.twimg.com/profile_images/481537542/image_normal.jpg";
name = "Jane Doe";
"screen_name" = iPhoneDev4Me;
},
{
image = "https://twimg0-a.akamaihd.net/profile_images/378800000139973355/787498ff5a80a5f45e234b79005f56b5_normal.jpeg";
name = "John Doe";
"screen_name" = indeedyes;
},
{
image = "https://si0.twimg.com/sticky/default_profile_images/default_profile_5_normal.png";
name = "Brad Pitt";
"screen_name" = soiownabusiness;
}
)
Due to the way Twitter returns the data, it is never the EXACT same order, so I have to check this every time I call these methods.
Any help would be great, would save my night. Thanks in advance!
You want the array of dictionaries be sorted by comparing screen_name value with your first array. Right? Also, the screen name may have different case than your username. Right?
I would use mapping dictionary:
Create dictionary from screen name to user dictionary:
NSArray *screenNames = [arrayOfUserDicts valueForKeyPath:#"screen_name.lowercaseString"];
NSDictionary *userDictsByScreenName = [NSDictionary dictionaryWithObjects:arrayOfUserDicts forKeys:screenNames];
Build final array by finding user dictionary for usernames in your array:
NSMutableArray *sortedUserDicts = [NSMutableArray arrayWithCapacity:arrayOfUsernames.count];
for (NSString *username in arrayOfUsernames) {
NSDictionary *userDict = [userDictsByScreenName objectForKey:username.lowercaseString];
[sortedUserDicts addObject:userDict];
}
First generate a mapping that maps the "screen_name" to the corresponding dictionary
in the second array:
NSDictionary *map = [NSDictionary dictionaryWithObjects:secondArray
forKeys:[secondArray valueForKey:#"screen_name"]];
Then you can create the sorted array with a single loop:
NSMutableArray *sorted = [NSMutableArray array];
for (NSString *name in firstArray) {
[sorted addObject:map[name]];
}
That sort order isn't something that could be easily replicated (i.e. it's not alpha, etc). Instead, you should just use that original NSArray as a guide to match data from the NSDictionary from Twitter. For example:
[twitterDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSInteger index = [yourLocalArray indexOfObject:obj];
if (index != NSNotFound) {
// You have a match, do something.
}
}];
lets name your arrays as firstArray and secondArray.
NSArray *sortedArray = [secondArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [#([firstArray indexOfObject:[obj1 objectForKey:#"name"]]) compare:#([firstArray indexOfObject:[obj2 objectForKey:#"name"]])];
}];

Add data from an array using its value for key to another Array

Hi i have two Arrays one being Parsed Data that has multiple entries at each cell (FolderName & ID) i want this data to be saved into another array like it is stored in the first array
FilteredData = [[NSMutableArray alloc]initWithArray:[ParsedData ValueForKey:#"FolderName"]];
SearchData = [[NSMutableArray alloc]initWithArray:FilteredData];
This is what i have been trying, The data Containing a dictionary at each entry is ParsedData, And the Array in which i have to copy these items is SearchData.
The Array (Parsed Data) Containing the dictionary looks like this
PARSED DATA (
{
CreatedBy = 1;
FolderName = Posteingang;
ID = 13000;
ParentID = 0;
},
{
CreatedBy = 1;
FolderName = Freigaben;
ID = 13001;
ParentID = 0;
},
From this Array I need to Get the FolderName And the ID and get them in the SearchData Array
SearchData (
Posteingang;
13000;
Freigaben;
13001;
)
I hope the question is clear now
check this one,
NSMutableArray *searchData = [NSMutableArray new];
for(NSDictionary *dict in ParsedDataArray){//here ParsedDataArray means PARSED DATA array name
NSDictionary *tempDict=[[NSDictionary alloc]initWithObjectsAndKeys:[dict ValueForKey:#"FolderName"],#"FolderName",[dict ValueForKey:#"ID"],#"ID" nil],
[searchData addObject:dict];
}
It seems like you misspelled the method name, it should be:
dictionaryWithObjectsAndKeys:
Notice the "s" after Object.
I want a dictionary inside an array which contains foldername and id
So you can get it using this:
NSMutableArray *searchData = [NSMutableArray new];
for(NSDictionary *dict in parsedDataArray){
NSDictionary *tempDict=#{#"FolderName":dict[#"FolderName"],
#"ID":dict[#"ID"]};
[searchData addObject:tempDict];
}
EDIT:
#[#"key:#"object"] is the new dictionary literal.
If you are using Xcode 4.3 or older need to do as:
NSDictionary *tempDict=#{#"FolderName":dict[#"FolderName"],
#"ID":dict[#"ID"]};
means,
NSDictionary *tempDict=[NSDictionary dictionaryWithObjectsAndKeys:[dict objectForKey:#"FolderName"], #"FolderName",[dict objectForKey:#"ID"],#"ID", nil];

ios-save nsdictionary in nsuserdefault

i want to save a nsdictionary have value null in nsuserdefault and don't need replace and delete value null
How?
My code -> impossible save in nsuserdefault
NSMutableArray * _itemsNames;
NSString * itemsFilename;
- (void) responseArray:(NSMutableArray *)array {
[_itemsNames setArray:array];
[spinner stopAnimating];
[_itemsNames writeToFile:itemsFilename atomically:YES];
NSMutableSet *filepathsSet = [[NSUserDefaults standardUserDefaults] objectForKey:#"test"];
[filepathsSet setByAddingObject:itemsFilename];
[[NSUserDefaults standardUserDefaults] setObject:filepathsSet forKey:#"test"];
}
The json is:(have value null)
({
ID:11,
name:21-12-2012,
des:"<null>",
url:
[
{
ID:1,
name: "<null>"
},
{
ID:2,
name:"<null>"
}
]
},
{
ID:12,
name:if i die young,
des:"<null>",
url:
[
{
ID:3,
name: "<null>"
},
{
ID:21,
name:"<null>"
}
]
})
If you have dictionary myDict
Then
[[NSUserDefaults standardUserDefaults] setObject:myDict forKey:#"MyDictionary"];
myDict will be saved only if it contains all objects that implements NSCoding
Regarding your null concept.
There is no need to save nil values in dictionary for a key.
If you try to get an object for a key and in dictionary there isn't any object related to that key then it will return nil. So no need to save null values
If you really need to store null values in NSDictionary use NSNull. Anyway you can just not store key with null value and then for [mydict objectForKey:#"keyWithNullValue"] you'll get nil.
But as I said if you really really want to store null use something like that:
NSSet *mySet = [NSSet setWithObjects:#{
#"ID":#(11),
#"name":#"21-12-2012",
#"des":[NSNull null],
#"url": #[#{
#"ID":#(1),
#"name": [NSNull null]
}, #{
#"ID":#(2),
#"name":[NSNull null]
}]
},#{
#"ID":#(12),
#"name":#"if i die young",
#"des":[NSNull null],
#"url": #[#{
#"ID":#(3),
#"name": [NSNull null]
}, #{
#"ID":#(21),
#"name":[NSNull null]
}]}, nil];
You mention saving dictionaries, but all you are showing is the JSON representation of an array of dictionaries.
You don't need to do anything strange, take the returned JSON data and turn it into an array and write the array to a plist. Turning it into a string and then trying to make a collection out of it is probably causing you the problems.

Resources