web-dev-qa-db-fra.com

Comment lire la structure de données d'un fichier .plist dans NSArray

Je créais manuellement une structure de données à l'aide des éléments suivants:

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];

Cependant, je pensais que ce serait mieux si c'était lu à partir d'un fichier. J'ai donc créé le fichier leagues.plist qui a la structure suivante:

<?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>

Comment lire ce fichier? J'ai essayé diverses méthodes, mais rien n'a fonctionné. Je ne sais même pas si je cherche le dossier au bon endroit. Pour référence, j'essaie les méthodes suivantes:

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];
}

ou

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

ou

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);

Cela me rend finalement complètement fou. Aidez-moi, s'il vous plaît!

Merci de bien vouloir

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

Cette réponse est correcte - êtes-vous sûr que votre fichier est dans l'application? L'avez-vous ajouté à votre projet et vérifiez-vous s'il est copié dans votre bundle d'applications? Sinon, le fichier n'a peut-être pas été ajouté à la cible que vous construisez, une erreur facile à commettre, surtout si vous avez plusieurs cibles.

Utilisez ce code si la variable plist se trouve dans le dossier des ressources du projet.

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

Si la plist se trouve dans le répertoire de documents de l'application, utilisez ceci:

    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

J'avais ce problème mais cela ne fonctionnait pas car je mettais les résultats de la pList dans un tableau où il aurait dû s'agir d'un dictionnaire, c'est-à-dire

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

Pour être complet, Kendall et Bentford sont tout à fait corrects. Cependant, dans mon exemple, contentArray était une propriété et, à la fin de la méthode, il était hors de portée car arrayWithContentsOfFile crée un objet libéré automatiquement.

Pour que cela fonctionne correctement, je devais faire 3 choses:

  1. mettre le fichier dans le dossier des ressources

  2. nommer le fichier correctement (était leagues.plist au lieu de league.plist)

  3. lire le fichier en utilisant [[NSArray alloc]] initWithContentsOfFile: plistPath)];

la troisième partie crée un NSArray alloué qui ne se libère pas lorsque vous quittez la portée de cette fonction ... bien sûr, il devait être libéré dans la fonction dealloc.

2
Xetius

Kendall est correct. 

D'après mon expérience, vous devez ajouter votre fichier au dossier "Ressources" de xcode.

2
bentford

Juste pour ajouter. J'avais le même problème et la solution suggérée m'a aidé à résoudre le problème, mais je ne suis pas sûr d'avoir réellement utilisé la solution exacte. Dans mon cas, le problème était que le fichier .plist avait été ajouté à une cible différente (avait ajouté une nouvelle cible un moment auparavant). Par conséquent, la solution était .plist> Obtenir des informations> Cibles et assurez-vous qu’elle est ajoutée à la cible correcte afin qu’elle soit copiée sur le périphérique lors de l’installation. Darn si j'avais compris cela assez tôt, j'aurais économisé beaucoup de temps. J'espère que c'est utile aussi. Cordialement!

0
Bob B.

Ce code fonctionne 

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

Si le fichier n'est pas ajouté dans le dossier des ressources et placé uniquement dans votre répertoire de documents, vous pouvez le faire. 

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