2014-01-24 20 views
9

ich ein JSON-Objekt konvertieren:Wie NSDictionary, um benutzerdefinierte Objekt

@interface Order : NSObject 

@property (nonatomic, retain) NSString *OrderId; 
@property (nonatomic, retain) NSString *Title; 
@property (nonatomic, retain) NSString *Weight; 

- (NSMutableDictionary *)toNSDictionary; 
... 

- (NSMutableDictionary *)toNSDictionary 
{ 

    NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; 
    [dictionary setValue:self.OrderId forKey:@"OrderId"]; 
    [dictionary setValue:self.Title forKey:@"Title"]; 
    [dictionary setValue:self.Weight forKey:@"Weight"]; 

    return dictionary; 
} 

In String ist dies:

{ 
    "Title" : "test", 
    "Weight" : "32", 
    "OrderId" : "55" 
} 

I String JSON mit Code erhalten:

NSMutableDictionary* str = [o toNSDictionary]; 

    NSError *writeError = nil; 

    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:str options:NSJSONWritingPrettyPrinted error:&writeError]; 
    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 

Jetzt Ich brauche erstellen und zuordnen Objekt aus JSON-String:

NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; 
    NSError *e; 
    NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:nil error:&e]; 

Dies gibt mir gefüllt NSDictionary. Was soll ich tun, um ein Objekt von diesem Wörterbuch zu bekommen?

Antwort

18

Hinzufügen einer neuen initWithDictionary: Methode Order:

- (instancetype)initWithDictionary:(NSDictionary*)dictionary { 
    if (self = [super init]) { 
     self.OrderId = dictionary[@"OrderId"]; 
     self.Title = dictionary[@"Title"]; 
     self.Weight = dictionary[@"Weight"];  
    } 
    return self;  
} 

Vergessen Sie nicht, initWithDictionary ‚s Signatur Order.h Datei

In dem Verfahren hinzufügen, wo Sie JSON erhalten:

NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; 
NSError *e; 
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:nil error:&e]; 
Order *order = [[Order alloc] initWithDictionary:dict]; 
+1

Wenn Sie viele Objekte haben, können Sie eine initWithDictionay von einem implementieren müssen ... Es gibt einige flexiblere Lösungen zB :: https: //github.com/Infusion-apps/IAModelBase – ingaham

+0

Siehe auch das Problem, https://github.com/oarrabi/IAModelBase/issues, aber wir können es verwalten. Ja, es ist gut. Bei Fragen kontaktieren Sie mich bitte. –

11

Wenn die Eigenschaftsnamen auf Ihrem Objekt mit den Schlüsseln in der JSON-Zeichenfolge übereinstimmen, können Sie Folgendes tun:

Um die JSON-Zeichenfolge Ihrem Objekt zuzuordnen, müssen Sie zuerst die Zeichenfolge in ein NSDictionary konvertieren und dann eine Methode für NSObject verwenden, die die Schlüsselwertcodierung zum Festlegen der einzelnen Eigenschaften verwendet.

NSError *error = nil; 
NSData *jsonData = ...; // e.g. [myJSONString dataUsingEncoding:NSUTF8Encoding]; 
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingOptionsAllowFragments error:&error]; 

MyObject *object = [[MyObject alloc] init]; 
[object setValuesForKeysWithDictionary:jsonDictionary]; 

Wenn die Schlüssel nicht übereinstimmen Sie die Instanzmethode von NSObject -[NSObject valueForUndefinedKey:] in Ihrer Objektklasse außer Kraft setzen können.

Um Ihr Objekt zu JSON zuzuordnen, können Sie die Objective-C-Laufzeit automatisch ausführen. Die folgenden funktioniert mit jedem NSObject Unterklasse:

#import <objc/runtime.h> 

- (NSDictionary *)dictionaryValue 
{ 
    NSMutableArray *propertyKeys = [NSMutableArray array]; 
    Class currentClass = self.class; 

    while ([currentClass superclass]) { // avoid printing NSObject's attributes 
     unsigned int outCount, i; 
     objc_property_t *properties = class_copyPropertyList(currentClass, &outCount); 
     for (i = 0; i < outCount; i++) { 
      objc_property_t property = properties[i]; 
      const char *propName = property_getName(property); 
      if (propName) { 
       NSString *propertyName = [NSString stringWithUTF8String:propName]; 
       [propertyKeys addObject:propertyName]; 
      } 
     } 
     free(properties); 
     currentClass = [currentClass superclass]; 
    } 

    return [self dictionaryWithValuesForKeys:propertyKeys]; 
} 
0

Der perfekte Weg, dies zu tun ist durch eine Bibliothek für die Serialisierung mit/Deserialisierung viele Bibliotheken sind verfügbar, aber ein i mag JagPropertyConverter https://github.com/jagill/JAGPropertyConverter

es kann Konvertieren Sie Ihr benutzerdefiniertes Objekt in NSDictionary und umgekehrt
sogar unterstützt es Wörterbuch oder Array oder ein beliebiges benutzerdefiniertes Objekt in Ihrem Objekt zu konvertieren (dh Zusammensetzung)

JAGPropertyConverter *converter = [[JAGPropertyConverter alloc]init]; 
converter.classesToConvert = [NSSet setWithObjects:[Order class], nil]; 

@interface Order : NSObject 

@property (nonatomic, retain) NSString *OrderId; 
@property (nonatomic, retain) NSString *Title; 
@property (nonatomic, retain) NSString *Weight; 
@end 



//For Dictionary to Object (AS IN YOUR CASE) 

NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; 
[dictionary setValue:self.OrderId forKey:@"OrderId"]; 
[dictionary setValue:self.Title forKey:@"Title"]; 
[dictionary setValue:self.Weight forKey:@"Weight"]; 

Order *order = [[Order alloc]init]; 
[converter setPropertiesOf:order fromDictionary:dictionary]; 


//For Object to Dictionary 

Order *order = [[Order alloc]init]; 
order.OrderId = @"10"; 
order.Title = @"Title; 
order.Weight = @"Weight"; 

NSDictionary *dictPerson = [converter convertToDictionary:person]; 
4

Unter der Annahme, dass Ihre Eigenschaften Namen und die Dictionary-Schlüssel gleich sind, können Sie diese Funktion verwenden, jedes Objekt zu konvertieren

- (void) setObject:(id) object ValuesFromDictionary:(NSDictionary *) dictionary 
{ 
    for (NSString *fieldName in dictionary) { 
     [object setValue:[dictionary objectForKey:fieldName] forKey:fieldName]; 
    } 
} 
+1

Dies stürzt ab, wenn ein Feld fehlt –

+0

Dies sollte helfen. Überprüfen Sie das Objekt auf den Feldnamen, bevor Sie den Wert festlegen. if ([Objekt antwortetToSelector: NSSelectorFromString (Feldname)]) { [Objekt SetValue: [Dictionary ObjektForKey: FeldName] forKey: FeldName]; } } } –

+0

Es funktioniert gut für mich. Vielen Dank! –

3

dies bequemer für Sie sein:

- (instancetype)initWithDictionary:(NSDictionary*)dictionary { 
     if (self = [super init]) { 
      [self setValuesForKeysWithDictionary:dictionary];} 
     return self; 
    } 
0

Definieren Sie Ihre Die benutzerdefinierte Klasse erbt von "AutoBindObject". Deklarieren Sie Eigenschaften, die denselben Namen mit Schlüsseln in NSDictionary haben.Rufen Sie dann Methode:

Eigentlich können wir Klasse anpassen, um verschiedene Eigenschaftennamen Schlüssel im Wörterbuch zuordnen. Daneben können wir geschachtelte Objekte binden.
Bitte werfen Sie einen Blick auf diese Demo. Die Verwendung ist einfach:
https://github.com/caohuuloc/AutoBindObject

Verwandte Themen