2010-12-13 18 views
1

J'essaye d'analyser une chaîne JSON directement dans un objet géré. La chaîne json contient toutes les chaînes, mais mon entité a des objets Date.NSManagedObject - Comment obtenir le type de la propriété

si cela est ma chaîne JSON

{ 
"name":"John", 
"dob": "12/12/2008", 
etc... 
} 

et voici mon entité Personne:

name : NSString 
dob: Date 
etc... 

Je veux analyser que JSON tout droit en faisant une boucle à travers les clés de la dict JSON, et le réglage les valeurs aux clés correspondantes de mon entité:

Person *aPerson = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:managedObjectContext]; 
NSArray *keys = [jsonDict allKeys]; 

for (NSString *key in keys) { 

[aPerson setValue:[jsonDict valueForKey:key] forKey:key]; 

} 

Cela ne fonctionne que si tous mes Les propriétés de l'entité sont NSStrings.

Comment puis-je obtenir le type/classe de la propriété de mon entité pour pouvoir définir les différents types?

par ex. si key = @ "dob" comment puis-je obtenir le type/classe de aPerson.dob?

donc mon code ressemblera à quelque chose comme:

Person *aPerson = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:managedObjectContext]; 
NSArray *keys = [jsonDict allKeys]; 

for (NSString *key in keys) { 
    if([[aPerson objectForKey:key] isKindOfClass:[NSDate class]]) 
    { 
     // Create an NSDate object 
    }else{ 
     [aPerson setValue:[jsonDict valueForKey:key] forKey:key]; 
    } 
} 

grâce

MISE À JOUR:

Ok j'ai essayé d'utiliser la isKindOfClass et voici le résultat a été:

// for key = @"name" 
// aPerson.name is NSString 
[[aPerson valueForKey:key] isKindOfClass:[NSString class]] => TRUE 
[[aPerson valueForKey:key] isKindOfClass:[NSObject class]] => TRUE 

// for key = @"age" 
// aPerson.age is NSNumber 
[[aPerson valueForKey:key] isKindOfClass:[NSNumber class]] => TRUE 
[[aPerson valueForKey:key] isKindOfClass:[NSObject class]] => TRUE 

// for key = @"dob" 
// aPerson.dob is NSDate 
[[aPerson valueForKey:key] isKindOfClass:[NSDate class]] => FALSE 
[[aPerson valueForKey:key] isKindOfClass:[NSObject class]] => FALSE 

comment est-ce? @dynamic dob et NSDate, c'est notOfClass NSDate!

s'il vous plaît dites-moi ce que je manque!

+0

Alternativement à ma réponse ci-dessous, vous pouvez exécuter le code ci-dessus avec un if ([key isEqualToString: "dob"]) {// Créer un objet NSDate ...} – Rog

+0

Merci Rog, mais j'espérais rendre l'analyse plus dynamique , seulement ramasser le type de la propriété de l'entité sans avoir à connaître le nom de la clé à savoir. "dob" – Bach

+0

Yup tous les points justes.Ce n'est pas testé par ce qui concerne l'utilisation de 'if ([[movieForKey: key] isKindOfClass: [NSDate class]])' – Rog

Répondre

0

Merci beaucoup à Rog, pour me envoyer dans la bonne direction, je me suis retrouvé remplaçant mon setter comme ci-dessous:

-(void)setDob:(id)value 
{ 
    [self willAccessValueForKey:@"dob"]; 
    if ([value isKindOfClass:[NSString class]]) { 
     [self setPrimitiveValue:[DateFormatter dateFromString:value] forKey:@"dob"]; 
    }else{ 
     [self setPrimitiveValue:value forKey:@"dob"]; 
    } 
    [self didChangeValueForKey:@"dob"]; 
} 

et tout fonctionne très bien maintenant, au lieu d'un 1000 lignes d'analyse de code, tout est fait en 3! une belle!

+0

Belle solution, propre et bien rangé. Merci de l'avoir posté! – Rog

1

Vous pouvez convertir votre chaîne JSON en NSDate, puis l'affecter à votre NSManagedObject, ou vous pouvez créer un setter personnalisé dans votre classe Person qui prend un NSString et renvoie NSDate. Voici un exemple:

- (NSDate*)convertStringToDate:(NSString*)dateString { 
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
    // this is imporant - we set our input date format to match our input string 
    // if format doesn't match you'll get nil from your string, so be careful 
    [dateFormatter setDateFormat:@"d MMMM yyyy"]; 
    NSDate *dateFromString = [dateFormatter dateFromString:dateString]; 
    [dateFormatter release]; 
    return dateFromString; 
} 
+0

merci Rog, mais j'ai encore besoin de savoir quand je devrais convertir la chaîne à ce jour. J'ai besoin de connaître le type de xx dans person.xx, pour créer leurs objets dynamiquement. par exemple. person.dob, person.loginDate etc ... si je peux dire qu'ils sont tous deux des propriétés NSDate, je peux ensuite créer un NSDate hors de cette chaîne json. – Bach

+0

J'ai également pensé à remplacer le setter pour prendre un NSString pour créer le NSDate, mais je serai toujours obligé d'utiliser des chaînes chaque fois que je veux définir le "dob" dans mon application. – Bach

+1

Pas nécessairement. Vous pouvez passer (id) au lieu d'un NSString et ensuite faire l'évaluation conditionnelle avec 'isKindOfClass' dans votre setter. – Rog

3

Je sais, cela est une réponse tardive, mais comme je l'étais aujourd'hui pour la recherche d'une bonne solution ... Ce est ce que je me sers maintenant:

NSEntityDescription * myEntity = [object entity]; 
NSDictionary * attributes = [myEntity attributesByName]; 
if ([[[attributes objectForKey:key] attributeValueClassName] isEqualToString:@"NSDate"]) { 
    // this type is NSDate 
}       

Hope this helps :)