Как читать структуру данных из файла .plist в NSArray
Я создавал структуру данных вручную, используя следующее:
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];
Однако я подумал, что было бы лучше, если бы оно было прочитано из файла. Поэтому я создал файл leagues.plist, который имеет следующую структуру:
<?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>
Как мне прочитать этот файл. Я пробовал различные методы, но ничего не сработало. Я даже не знаю, смотрю ли я в нужном месте для файла. Для справки я пытаюсь использовать следующие методы:
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];
}
или
NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"league" ofType:@"plist"];
contentArray = [NSArray arrayWithContentsOfFile:plistPath];
или
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);
Это окончательно сводит меня с ума. Помогите пожалуйста!
Благодарим вас
Ответы
Ответ 1
NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"league" ofType:@"plist"];
contentDict = [NSDictionary dictionaryWithContentsOfFile:plistPath];
Ответ правильный: уверены ли вы, что ваш файл находится в приложении? Вы добавили его в свой проект и проверьте, не скопированы ли его в комплект приложений? Если нет, возможно, файл не был добавлен к цели, которую вы строите, что легко сделать, особенно если у вас несколько целей.
Ответ 2
Используйте этот код, если plist
находится в папке ресурсов проекта.
NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"league" ofType:@"plist"];
contentArray = [NSArray arrayWithContentsOfFile:sourcePath];
Если plist
находится внутри каталога документа приложения, используйте это:
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];
Ответ 3
У меня была эта проблема, но она не работала, потому что я помещал результаты из pList в массив, где должен был быть словарь, т.е.
NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"VehicleDetailItems" ofType:@"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
Ответ 4
Кендалл прав.
По моему опыту, вы должны добавить свой файл в папку "Ресурсы" в xcode.
Ответ 5
Для полноты, Кендалл и Бентфорд полностью верны. Однако в моем примере contentArray был свойством и к концу метода он вышел из области видимости, потому что arrayWithContentsOfFile создает автоматически выпущенный объект.
Чтобы сделать эту работу правильно, мне нужно было сделать 3 вещи:
-
поместите файл в папку ресурсов
-
правильно укажите файл (был leagues.plist вместо league.plist)
-
прочитайте файл, используя [[NSArray alloc] initWithContentsOfFile: plistPath)];
третья часть создает выделенный NSArray, который не освобождается при выходе из области действия этой функции... конечно, это должно было быть выпущено в функции dealloc.
Ответ 6
Просто добавьте. У меня была та же проблема, и предлагаемое решение помогло мне решить проблему, однако я не уверен, действительно ли я использовал точное решение. В моем случае проблема заключалась в том, что файл .plist был добавлен в другую цель (ранее добавила новую цель). Поэтому решение было .plist > Get Info > Targets, и убедитесь, что оно добавлено к правильной цели, поэтому оно копируется на устройство при установке. Дарн, я понял, что скоро я бы сэкономил много времени. Надеюсь, это тоже полезно. Привет!
Ответ 7
Если файл не добавлен в папку ресурсов и помещен только в каталог документов.
Вы можете сделать это
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"file.plist"];
NSMutableArray *arrContentsplist = [[NSMutableArray alloc] initWithContentsOfFile:path];
Ответ 8
Этот код работает
NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"plist-name" ofType:@"plist"];
NSDictionary *Dictionary= [[NSDictionary alloc]initWithContentsOfFile:plistPath];
NSLog(@" current version CFBundleVersion = %@",[Dictionary valueForKey:@"CFBundleVersion"]);