How to read data structure from .plist file in NSArray

I created the 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 it would be better if it were read from a file. Therefore, I created the leagues.plist file, 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. I tried various methods but nothing worked. I don’t even know if I look in the right place for the file. For reference, I am trying to use 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); 

It totally drives me crazy. Help me please!

Thank you

+49
ios objective-c iphone cocoa-touch plist
Apr 14 '09 at 21:52
source share
8 answers
 NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"league" ofType:@"plist"]; contentDict = [NSDictionary dictionaryWithContentsOfFile:plistPath]; 

The answer is correct: are you sure that your file is in the application? Have you added it to your project and check if it is copied to the application suite? If not, the file may not have been added to the goal you are building, which is easy to do, especially if you have several goals.

+121
Apr 15 '09 at 5:56
source share

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

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

If plist is inside the application document directory, 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]; 
+4
Jun 07 '11 at 12:45
source share

I had this problem, but it did not work, because I put the results from pList in the array where the dictionary was supposed to be, i.e.

 NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"VehicleDetailItems" ofType:@"plist"]; NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:plistPath]; 
+4
May 17 '12 at 13:56
source share

Kendall is right.

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

+2
Apr 15 '09 at 8:16
source share

For completeness, Kendall and Bentford are completely true. However, in my example, contentArray was a property and by the end of the method it went out of scope because arrayWithContentsOfFile creates an automatically issued object.

To make this work correctly, I needed to do 3 things:

  • put the file in the resource folder

  • specify the file correctly (was leagues.plist instead of league.plist)

  • read the file using [[NSArray alloc] initWithContentsOfFile: plistPath)];

the third part creates a dedicated NSArray, which is not freed when it leaves the scope of this function ... of course, this should have been released in the dealloc function.

+2
Apr 17 '09 at 8:50
source share

Just add. I had the same problem and the proposed solution helped me solve the problem, however, I am not sure if I really used the exact solution. In my case, the problem was that the .plist file was added to another target (previously added a new target). Therefore, the solution was .plist> Get Info> Targets, and make sure that it was added to the correct target, so it is copied to the device during installation. Darn, I realized that I would soon save a lot of time. Hope this is helpful too. Hello!

0
Aug 28 '09 at 6:08
source share

If the file is not added to the resource folder and placed only in the document directory. You can do it

 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *path = [documentsDirectory stringByAppendingPathComponent:@"file.plist"]; NSMutableArray *arrContentsplist = [[NSMutableArray alloc] initWithContentsOfFile:path]; 
0
Jan 10 '13 at
source share

This code works

 NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"plist-name" ofType:@"plist"]; NSDictionary *Dictionary= [[NSDictionary alloc]initWithContentsOfFile:plistPath]; NSLog(@" current version CFBundleVersion = %@",[Dictionary valueForKey:@"CFBundleVersion"]); 
0
Feb 14 '13 at 10:16
source share



All Articles