2009-04-14 24 views
49

stavo creando una struttura di dati manualmente utilizzando il seguente:Come leggere struttura di dati da file .plist in 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]; 

Tuttavia, ho pensato che questo sarebbe stato meglio se fosse stato letto da un file. Così ho creato il file di leagues.plist che ha la seguente struttura:

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

Come faccio a leggere questo file nella ho provato vari metodi, ma niente ha funzionato.. Non so nemmeno se sto cercando nel posto giusto per il file. Per avere un riferimento Sto cercando i seguenti metodi:

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

o

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

o

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

Questa è finalmente mi guida completamente folle. Aiuto per favore!

Grazie gentilmente

risposta

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

La risposta è corretta - sei sicuro che il file è in app? L'hai aggiunto al tuo progetto e controlla se viene copiato nel pacchetto della tua app? In caso contrario, potrebbe essere il file non è stato aggiunto al target che si sta creando, un errore facile da fare soprattutto se si dispone di più obiettivi.

+0

Basta imparare qui :). Non so se è nel pacchetto principale. Grazie controllerò quello dopo. – Xetius

+1

È: '[dizionario NSDictionaryWithContentsOfFile: plistPath];' – shebelaw

+0

Grazie a @shebelaw, ho modificato il codice. Ho pensato che fosse un array ... –

2

Kendall è corretto.

Nella mia esperienza, è necessario aggiungere il file alla cartella "Risorse" in xcode.

+0

Che dire di una cartella all'interno della cartella Risorse? Può anche essere aggiunto lì? – Patricia

+0

@Patricia va bene, basta assicurarsi che sia relativo al gruppo. – Kjuly

2

Per completezza, Kendall e Bentford sono completamente corretti. Tuttavia, nel mio esempio, contentArray era una proprietà e alla fine del metodo stava andando fuori campo perché arrayWithContentsOfFile crea un oggetto rilasciato automaticamente.

Per fare questo lavoro in modo corretto quello che dovevo fare 3 cose:

  1. mettere il file nella cartella risorse

  2. nome del file in modo corretto (era leagues.plist invece di league.plist)

  3. leggere il file utilizzando [[NSArray alloc] initWithContentsOfFile: plistPath)];

la terza parte crea un NSArray allocata che non rilascia quando si esce dal campo di applicazione di questa funzione ... Naturalmente, questo doveva essere rilasciato nella funzione dealloc.

+0

per la cosa autorelease .. puoi semplicemente "mantenere" dove appropriato. – dwery

0

Solo per aggiungere. Ho avuto lo stesso problema e la soluzione suggerita mi ha aiutato a risolvere il problema, tuttavia non sono sicuro di aver effettivamente utilizzato la soluzione esatta. Nel mio caso il problema era che il file .plist è stato aggiunto a un target diverso (aveva aggiunto un nuovo target un momento prima). Quindi la soluzione era .plist> Ottieni informazioni> Obiettivi e assicurati che venga aggiunto alla destinazione corretta in modo che venga copiata sul dispositivo durante l'installazione. Maledizione, se l'avessi scoperto abbastanza presto avrei risparmiato un sacco di tempo.Spero che anche questo sia utile. Saluti!

4

Utilizzare questo codice se plist si trova nella cartella delle risorse del progetto.

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

Se il plist è dentro la directory del documento del app utilizzare questo:

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

ho avuto questo problema, ma non funzionava perché stavo mettendo i risultati dalla plist in un array dove avrebbe dovuto essere un dizionario, ovvero

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

Se il file non viene aggiunto nella cartella delle risorse e inserito solo nella directory dei documenti. È possibile farlo

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

Questo codice funziona

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