it-swarm.com.ru

Как прочитать структуру данных из файла .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];

Тем не менее, я подумал, что было бы лучше, если бы он был прочитан из файла. Поэтому я создал файл league.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);

Это, наконец, сводит меня с ума. Помогите, пожалуйста!

Спасибо

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

Этот ответ правильный - вы уверены, что ваш файл находится в приложении? Вы добавили его в свой проект и проверили, копируется ли он в ваш пакет приложений? Если нет, то, возможно, файл не был добавлен к цели, которую вы строите, что легко сделать, особенно если у вас несколько целей.

121
Kendall Helmstetter Gelner

Используйте этот код, если 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];
4
Narayanan

У меня была эта проблема, но она не работала, потому что я помещал результаты из списка pList в массив, где это должен был быть словарь, т.е.

NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"VehicleDetailItems" ofType:@"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
4
noRema

Для полноты картины Кендалл и Бентфорд совершенно правы. Однако в моем примере contentArray был свойством, и к концу метода он выходил из области видимости, потому что arrayWithContentsOfFile создает автоматически освобожденный объект.

Чтобы сделать эту работу правильно, мне нужно было сделать 3 вещи:

  1. поместите файл в папку ресурсов

  2. назовите файл правильно (был league.plist вместо league.plist)

  3. читать файл, используя [[NSArray alloc] initWithContentsOfFile: plistPath)];

третья часть создает выделенный NSArray, который не освобождается при выходе из области действия этой функции ... конечно, это необходимо было освободить в функции dealloc.

2
Xetius

Кендалл прав. 

По моему опыту, вам нужно добавить свой файл в папку «Ресурсы» в xcode.

2
bentford

Просто чтобы добавить. У меня была та же самая проблема, и предложенное решение помогло мне решить проблему, однако я не уверен, действительно ли я использовал точное решение. В моем случае проблема заключалась в том, что файл .plist был добавлен к другой цели (добавила новую цель за мгновение до этого). Поэтому решение было .plist> Get Info> Targets, и убедитесь, что оно добавлено к правильной цели, чтобы оно было скопировано на устройство при установке. Черт, если бы я понял это достаточно скоро, я бы сэкономил много времени. Надеюсь, это тоже полезно. С уважением!

0
Bob B.

Этот код работает 

NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"plist-name" ofType:@"plist"];
NSDictionary *Dictionary= [[NSDictionary alloc]initWithContentsOfFile:plistPath];
NSLog(@" current version CFBundleVersion = %@",[Dictionary valueForKey:@"CFBundleVersion"]);
0
Mohit Gaur

Если файл не добавлен в папку ресурсов и помещен только в папку с документами . Вы можете сделать это 

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"file.plist"];
NSMutableArray *arrContentsplist = [[NSMutableArray alloc] initWithContentsOfFile:path];
0
Taimur Ajmal