2009-07-02 5 views
26

Donc, j'ai une chaîne structurée plist, qui obtient dynamiquement (pas à partir du système de fichiers). Comment je convertirais cette chaîne en NSDictionary. J'ai essayé de convertir NSData puis NSDictionary avec NSPropertyListSerialization, mais il renvoie "[NSCFString objectAtIndex:]: sélecteur non reconnu envoyé à l'instance 0x100539f40" lorsque j'essaie d'accéder au NSDictionary, montrant que mon dictionnaire n'était pas créé avec succès.Parse Plist (NSString) dans NSDictionary

Exemple de NSString (ce sont les données 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"> 
<dict> 
<key>Key1</key> 
<dict> 
    <key>Test1</key> 
    <false/> 
    <key>Key2</key> 
    <string>Value2</string> 
    <key>Key3</key> 
    <string>value3</string> 
</dict> 
</dict> 
</plist> 

Merci!

Répondre

72

Voir Serializing a Property List

NSData* plistData = [source dataUsingEncoding:NSUTF8StringEncoding]; 
NSString *error; 
NSPropertyListFormat format; 
NSDictionary* plist = [NSPropertyListSerialization propertyListWithData:plistData mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error]; 
NSLog(@"plist is %@", plist); 
if(!plist){ 
    NSLog(@"Error: %@",error); 
    [error release]; 
} 
+4

+1 Votre solution semble bien polie - en utilisant immutable pour créer un NSDictionary et en se souvenant de libérer l'erreur s'il y en a un valent des points bonus. :-) –

+0

J'ai presque appelé cela une sur-version. Um, wow. Cette API enfreint totalement les règles de gestion de la mémoire en demandant à l'appelant de libérer cette chaîne d'erreur. –

+0

Selon les notes de publication, il a été modifié pour ne pas avoir cette violation dans Leopard. Ça vaut le coup de chercher. Il y a un rapport de bug à ce sujet: http://openradar.appspot.com/5563963 –

12

Essayez ceci:

NSData * data = [yourString dataUsingEncoding:NSUTF8StringEncoding]; 

NSString *errorDesc = nil; 
NSPropertyListFormat format; 
NSDictionary * dict = (NSDictionary*)[NSPropertyListSerialization 
             propertyListFromData:data 
             mutabilityOption:NSPropertyListMutableContainersAndLeaves 
             format:&format 
             errorDescription:&errorDesc]; 
+0

Parfait! Merci! – christo16

+0

À l'exception de la fuite de mémoire, mais diable il arrive (: – Jacob

+0

NSDictionary * dict = (NSDictionary *) [NSPropertyListSerialization ...... Vous devez vérifier le fichier que vous essayez de lire que vous pouvez retourner un NSArray au lieu de NSDictionary – Komposr

1

I've tried converting it NSData and then to a NSDictionary with NSPropertyListSerialization, but it returns "[NSCFString objectAtIndex:]: unrecognized selector sent to instance 0x100539f40" when I attempt to access the NSDictionary, showing that my Dictionary was not successfully created.

Non, il ne montre pas une telle chose. Ce que cela montre, c'est que vous avez essayé de traiter une chaîne comme un tableau. Vous auriez besoin de déterminer où dans le plist vous essayiez d'obtenir un tableau et pourquoi il y avait une chaîne où vous attendiez un tableau-c.-à-d. Si vous avez créé le plist incorrectement (mettez une chaîne là où vous vouliez mettre un tableau) ou l'examine incorrectement (la présence d'une chaîne est correcte, votre attente ultérieure d'un tableau est fausse).