How to search in a plist to retrieve a value for a

2020-06-29 08:12发布

问题:

I am using a plist to store the country data for my app's users. So I have this <dict> list that holds several countries. For each country there are several provinces. For each region there are regions. And each region holds many cities.

So my list looks like the following:

<dict>
    <key>Country</key>
    <array>
        <dict>
            <key>ISO</key>
            <string>ES</string>
            <key>Value</key>
            <string>Spain</string>
            <key>Children</key>
            <array>
                <dict>
                    <key>ISO</key>
                    <string>AL</string>
                    <key>Value</key>
                    <string>Andalucia</string>
                    <key>Children</key>
                    <array>
                        ...
                    </array>
                </dict>
            </array>
        </dict>
    </array>
</dict>

The most detailed node is the city which holds information as:

<dict>
    <key>ISO</key>
    <string>03002</string>
    <key>Value</key>
    <string>ALICANTE</string>
</dict>

In the database I then store 03002 which is the unique key for Alicante in this case. But in my GUI I obviously want to display Alicante and not the numeric representation.

So is there an easy way to search this plist file to find the matching Value for this ISO ?

Thanks!

EDIT

At the moment I created this method. It does the trick, but I cannot really call it efficient coding. So please advise...

- (NSString *)getCityNameForKey: (NSString *)ISO {
    NSString *cityName = @"";
    NSArray *citySource = [[Locations getInstance] toDataSource];

    for (int i = 0; i < [citySource count]; i++) {
        //Country
        NSDictionary *p_dictionary = [citySource objectAtIndex:i];
        NSArray *provinces = [p_dictionary objectForKey:@"Children"];
        if ([provinces count] > 0) {
            //Province
            for (int j = 0; j < [provinces count]; j++) {
                NSDictionary *r_dictionary = [provinces objectAtIndex:j];
                NSArray *regions = [r_dictionary objectForKey:@"Children"];
                if ([regions count] > 0) {
                    //City
                    for (int k = 0; k < [regions count]; k++) {
                        NSDictionary *c_dictionary = [regions objectAtIndex:k];
                        NSArray *cities = [c_dictionary objectForKey:@"Children"];
                        if ([cities count] > 0) {
                            for (int l = 0; l < [cities count]; l++) {
                                NSDictionary *result_dict = [cities objectAtIndex:l];
                                if ([[result_dict objectForKey:@"ISO"] isEqualToString:ISO]) {

                                    index_country = i;
                                    index_province = j;
                                    index_region = k;
                                    index_city = l;                                    

                                    cityName = [result_dict objectForKey:@"Value"];
                                    return cityName;
                                    break;
                                }
                            }
                        }

                    }
                }
            }
        }
    }
    return cityName;
}

回答1:

You can load a plist into an NSDictionary with the method:

NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];

Then simply access the values as you would for any dictionary:

NSDictionary *region = [dict valueForKey:@"City"];
NSString *name = [region objectForKey:@"Value"];


回答2:

There's not enough data for me to really picture it exactly, but you could use a keyPath to get an array of all Cities and then use a predicate on this array

Something like this would be a start for how you start to get all the data into one array

NSArray *cities = [countries valueForKeyPath:@"Children.Children"];

Then to search you could do something like

__block NSString *name = nil;

[cities enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    if ([[obj valueForKey:@"ISO"] isEqualToString:ISOValue]) {
        name = [obj valueForKey:@"Value"];
        *stop = YES:
    }
}];