Advertise here




Advertise here

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with Google Sign In with OpenID
Please do not post the same thing multiple times. The board software automatically flags certain posts as needing moderator attention. This happens the most often for new users. I'm pretty sure this is made clear at the time you attempt to post. Posting the same thing over and over again just makes that many more posts the moderators have to weed through later. This makes us sad. Don't make us sad. If your post/thread doesn't appear, just wait a while. Don't post it again. If it hasn't shown up by the next day, then you can try again. I normally go through posts in the mornings, and try to check a few times throughout the day, but I'm not here 24/7. There will typically be a significant delay before posts are approved. Just be patient.

Add row to dictionary .plist afterwards via code

I've already created a dictionary (.plist) file, and app is running. Now I want to check afterwards if an entry exists, and if not, add it. But I get stuck 'cause it's getting complicated (for me [newbie] :p). (i've simplified/cleaned up the code a bit to explain :)...)

My dictionary file:
<dict>
<key>cars</key>
<array>
<dict>
<key>make</key><string>BMW</string>
<key>model</key><string>328i</string>
<key>fuel</key><string>petrol</string>
</dict>
<dict>
<key>make</key><string>Audi</string>
<key>model</key><string>A4</string>
<key>fuel</key><string>diesel</string>
</dict>
</array>
</dict>


No I'm looking for 'Mercedes' (=array), but if not found, how do I insert it and then as an array?
myCars = [dDatabase objectForKey:@\"cars\"];//NSMuteableArray

if ([myCars indexOfObject:@\"Mercedes\"]) {
NSLog(@\"yeah it is set!\");
//do nothing
} else {
NSLog(@\"not found\");
//how do I insert a Mercedes ?????
}
Post edited by altaphista on

Replies

  • Duncan CDuncan C Posts: 8,015Tutorial Authors, Registered Users
    altaphista;438794 said:
    I've already created a dictionary (.plist) file, and app is running. Now I want to check afterwards if an entry exists, and if not, add it. But I get stuck 'cause it's getting complicated (for me [newbie] :p). (i've simplified/cleaned up the code a bit to explain :)...)

    My dictionary file:
    <dict>
    <key>cars</key>
    <array>
    <dict>
    <key>make</key><string>BMW</string>
    <key>model</key><string>328i</string>
    <key>fuel</key><string>petrol</string>
    </dict>
    <dict>
    <key>make</key><string>Audi</string>
    <key>model</key><string>A4</string>
    <key>fuel</key><string>diesel</string>
    </dict>
    </array>
    </dict>


    No I'm looking for 'Mercedes' (=array), but if not found, how do I insert it and then as an array?
    myCars = [dDatabase objectForKey:@\"cars\"];//NSMuteableArray

    if ([myCars indexOfObject:@\"Mercedes\"]) {
    NSLog(@\"yeah it is set!\");
    //do nothing
    } else {
    NSLog(@\"not found\");
    //how do I insert a Mercedes ?????
    }
    You've got several issues.

    First of all, when you read a data structure from a plist, everything comes back as the immutable form, even if what you wrote contained mutable objects.

    Fixing that can be tricky if you have a complex structure like a dictionary that contains a dictionary that contains an array that contains dictionaries, and some or all of the internal objects need to be mutable.

    Most objects that come in mutable and immutable form implement a method mutableCopy that returns a mutable version.

    You could write a mutableDeepCopy method that takes a container object like an array or dictionary and traverses it to the end, and creates a mutable equivalent of all the array, dictionary, and set objects inside. It would be easier to write a mutableDeepCopy method for your specific structure than a general-purpose one, but a general-purpose method would be more useful.

    Once you solve that problem, you need to figure out how to find an entry in your array that has the "make" value you are looking for.

    You could do that with the NSDictionary method indexOfObjectPassingTest:

    Something like this:

    if ([cars indexOfObjectPassingTest: indexOfObjectPassingTest:
    ^BOOL (NSDictionary* obj, NSUInteger idx, BOOL *stop)
    {
    if [[obj objectForKey: @\"make] isEqualToString: @\"Mercedes\"]
    {
    stop* = YES;
    return YES;
    }
    return NO;
    }] == NSNotFound)

    {
    //Code to add an object to you cars array
    }


    (Disclaimer: I struggle with the syntax for blocks that take parameters. I think I got the syntax above correct, but I did not compile it, much less test it.)

    Assuming it works, the code above uses one of the new block-based array methods, indexOfObjectPassingTest. It takes a block of code that is run on each element in the array. That code looks at each element to see if it matches your search criteria (That it contains a make key, and the value of that key is "Mercedes"). When it finds such an element, the block returns YES, and the indexOfObjectPassingTest returns the index of the object in question.
    Regards,

    Duncan C
    WareTo

    mug

    Animated GIF created with Face Dancer, available for free in the app store.
  • FstuffFstuff Posts: 154Registered Users
    According to your plist, you have a dictionary which contains a single array which contains several dictionaries. Presumably you have successfully pulled the single array out of the parent dictionary. However, arrays are not key-value coded. The reason that your call to 'indexOfObject' is not behaving as expected is because the method tests each object in the array for equality to the argument you supply. So, your code is comparing a string (@"Mercedes") to a dictionary.

    You will need to iterate through the array and test each dictionary object independently. So, iterate through the array, get the value associated with the "make" key for each dictionary, and test for equality to your string. You could also use a predicate but start with this.

    Here's Apple's documentation on using collections such as arrays and dictionaries: https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Collections/Collections.html#//apple_ref/doc/uid/10000034-BBCFIHFH

    Good luck!
  • altaphistaaltaphista Posts: 2New Users
    @duncan, what you explain goes wel above my knowledge, thanks very much for your extended reply, i'll understand one day ;)

    @Fstuff, thanks for your reply, but can you help me with a start of code, i am quite new to obj-c.
Sign In or Register to comment.