Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read data structure from .plist file into NSArray

I was creating a data structure manually using the following:

NSDictionary* league1 = [[NSDictionary alloc] initWithObjectsAndKeys: @"Barclays Premier League", @"name",
                 @"Premier League", @"shortname",
                 @"101", @"id", nil];
NSDictionary* league2 = [[NSDictionary alloc] initWithObjectsAndKeys: @"Coca-Cola Championship", @"name",
                 @"Championship", @"shortname",
                 @"102", @"id", nil];
NSDictionary* league3 = [[NSDictionary alloc] initWithObjectsAndKeys: @"Scottish Premier League", @"name",
                 @"SPL", @"shortname",
                 @"201", @"id", nil];
NSDictionary* league4 = [[NSDictionary alloc] initWithObjectsAndKeys: @"Champions League", @"name",
                 @"UCL", @"shortname",
                 @"501", @"id", nil];

contentArray = [[NSArray alloc] initWithObjects:

                [[NSDictionary alloc] initWithObjectsAndKeys: @"English", @"category", [[NSArray alloc] initWithObjects: league1, league2, nil], @"leagues", nil],
                [[NSDictionary alloc] initWithObjectsAndKeys: @"Scottish", @"category", [[NSArray alloc] initWithObjects: league3, nil], @"leagues", nil],
                [[NSDictionary alloc] initWithObjectsAndKeys: @"Tournaments", @"category", [[NSArray alloc] initWithObjects: league4, nil], @"leagues", nil],
                nil];

[league1 release];
[league2 release];
[league3 release];
[league4 release];

However, I thought this would be better if it was read from a file. So I created the file leagues.plist which has the following structure:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <array>
        <dict>
            <key>category</key>
            <string>English</string>
            <key>leagues</key>
            <array>
                <dict>
                    <key>name</key>
                    <string>Barclays Premier League</string>
                    <key>shortname</key>
                    <string>Premier League</string>
                    <key>id</key>
                    <string>101</string>
                </dict>
                <dict>
                    <key>name</key>
                    <string>Coca-Cola Championship</string>
                    <key>shortname</key>
                    <string>Championship</string>
                    <key>id</key>
                    <string>102</string>
                </dict>
            </array>
        </dict>
        <dict>
            <key>category</key>
            <string>Scottish</string>
            <key>leagues</key>
            <array>
                <dict>
                    <key>name</key>
                    <string>Scottish Premier League</string>
                    <key>shortname</key>
                    <string>SPL</string>
                    <key>id</key>
                    <string>201</string>
                </dict>
            </array>
        </dict>
        <dict>
            <key>category</key>
            <string>Tournaments</string>
            <key>leagues</key>
            <array>
                <dict>
                    <key>name</key>
                    <string>Champions League</string>
                    <key>shortname</key>
                    <string>UCL</string>
                    <key>id</key>
                    <string>501</string>
                </dict>
            </array>
        </dict>
    </array>
</plist>

How do I read this file in. I have tried various methods but nothing has worked. I don't even know if I am looking in the right place for the file. For reference I am trying the following methods:

NSString* errorDesc = nil;
NSPropertyListFormat format;
NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"league" ofType:@"plist"];
NSData* plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];
contentArray = (NSArray*)[NSPropertyListSerialization
                                     propertyListFromData:plistXML
                                     mutabilityOption:NSPropertyListMutableContainersAndLeaves
                                     format:&format
                                     errorDescription:&errorDesc];

if (!contentArray) {
    NSLog(errorDesc);
    [errorDesc release];
}

or

NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"league" ofType:@"plist"];
contentArray = [NSArray arrayWithContentsOfFile:plistPath];

or

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];

NSString *fooPath = [documentsPath stringByAppendingPathComponent:@"leagues.plist"];
NSLog(fooPath);
contentArray = [NSArray arrayWithContentsOfFile:fooPath];
NSLog(@"%@",contentArray);

This is finally driving me completely insane. Help please!

Thank you kindly

like image 671
Xetius Avatar asked Apr 14 '09 21:04

Xetius


4 Answers

NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"league" ofType:@"plist"];
contentDict = [NSDictionary dictionaryWithContentsOfFile:plistPath];

That answer is correct - are you sure that your file is in the app? Did you add it to your project, and check to see if it gets copied into your app bundle? If not, it might be the file was not added to the target you are building, an easy mistake to make especially if you have multiple targets.

like image 127
Kendall Helmstetter Gelner Avatar answered Nov 11 '22 04:11

Kendall Helmstetter Gelner


Use this code if the plist is in the resources folder of the project.

  NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"league"    ofType:@"plist"];
 contentArray = [NSArray arrayWithContentsOfFile:sourcePath];

If the plist is inside the document directory of the app use this:

    NSArray *paths = 
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;

NSString *plistName = @"league";
NSString *finalPath = [basePath stringByAppendingPathComponent: 
                       [NSString stringWithFormat: @"%@.plist", plistName]];



contentArray = [NSArray arrayWithContentsOfFile:finalPath];
like image 35
Narayanan Avatar answered Nov 11 '22 04:11

Narayanan


I had this issue but it wasn't working because I was putting the results from the pList into an array where it should have been a dictionary, i.e

NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"VehicleDetailItems" ofType:@"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
like image 4
noRema Avatar answered Nov 11 '22 04:11

noRema


Kendall is correct.

In my experience, you need to add your file to the "Resources" folder in xcode.

like image 2
bentford Avatar answered Nov 11 '22 03:11

bentford