it-swarm.com.de

iOS JSON-Serialisierung für NSObject-basierte Klassen

Ich möchte meine eigenen benutzerdefinierten Klassen mit JSON-serialisieren. Ich arbeite in Objective-C/iOS5. Ich möchte Folgendes tun:

Person* person = [self getPerson ]; // Any custom object, NOT based on NSDictionary
NSString* jsonRepresentation = [JsonWriter stringWithObject:person ];
Person* clone = [JsonReader objectFromJson: jsonRepresentation withClass:[Person Class]];

Es scheint, dass NSJSONSerialization (und einige andere Bibliotheken) erfordern, dass die Klasse "person" auf NSDictionary usw. basiert. Ich möchte etwas, das jedes benutzerdefinierte Objekt serialisiert, das ich definieren möchte (innerhalb des Grundes).

Stellen wir uns vor, dass Person.h so aussieht:

#import <Foundation/Foundation.h>
@interface Person : NSObject 
@property NSString* firstname;
@property NSString* surname;
@end

Ich möchte, dass die generierte JSON für eine Instanz wie folgt aussieht:

{"firstname":"Jenson","surname":"Button"}

Meine App verwendet ARC. Ich brauche etwas, das mit Objekten sowohl serialisiert als auch deserialisiert wird.

Danke vielmals.

18
Journeyman

Dies ist eine schwierige Sache, da die einzigen Daten, die Sie in JSON eingeben können, einfache Objekte sind (NSString, NSArray, NSNumber usw.), aber keine benutzerdefinierten Klassen oder Skalar-Typen. Warum? Ohne alle Arten von bedingten Anweisungen zu erstellen, um alle diese Datentypen in diese Objekttypen einzubinden, wäre eine Lösung etwa so:

//at the top…
#import <objC/runtime.h>

    NSMutableDictionary *muteDictionary = [NSMutableDictionary dictionary];

    id YourClass = objc_getClass("YOURCLASSNAME");
    unsigned int outCount, i;
    objc_property_t *properties = class_copyPropertyList(YourClass, &outCount);
    for (i = 0; i < outCount; i++) {
        objc_property_t property = properties[i];
        NSString *propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
        SEL propertySelector = NSSelectorFromString(propertyName);
        if ([classInstance respondsToSelector:propertySelector]) {
            [muteDictionary setValue:[classInstance performSelector:propertySelector] forKey:propertyName];
        }
    }
    NSError *jsonError = nil;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:muteDictionary options:0 error:&jsonError];

Dies ist jedoch wegen des oben Gesagten schwierig. Wenn Sie Skalartypen oder benutzerdefinierte Objekte haben, stürzt das Ganze ab. Wenn es wirklich wichtig ist, etwas wie dieses in Gang zu bringen, würde ich vorschlagen, die Zeit zu investieren und die Links von Ricard zu betrachten, die es Ihnen ermöglichen, Eigenschaftstypen zu sehen, die bei den bedingten Anweisungen hilfreich sind, die zum Einschließen der Werte in NSDictionary-sichere Objekte erforderlich sind. 

23

Jetzt können Sie dieses Problem einfach mit JSONModel lösen. JSONModel ist eine Bibliothek, die Ihr Objekt basierend auf Class generisch serialisiert/deserialisiert. Sie können auch Nicht-nsobject-basierte Eigenschaften für Eigenschaften wie int, short und float verwenden. Es kann auch verschachtelte komplexe JSONs unterstützen.

Deserialize Beispiel . Unter Bezugnahme auf Ihr Beispiel in der Header-Datei:

#import "JSONModel.h"

@interface Person : JSONModel 
@property (nonatomic, strong) NSString* firstname;
@property (nonatomic, strong) NSString* surname;
@end

in der Implementierungsdatei:

#import "JSONModelLib.h"
#import "yourPersonClass.h"

NSString *responseJSON = /*from somewhere*/;
Person *person = [[Person alloc] initWithString:responseJSON error:&err];
if (!err)
{
   NSLog(@"%@  %@", person.firstname, person.surname):
}

Serialize Beispiel . In der Implementierungsdatei:

#import "JSONModelLib.h"
#import "yourPersonClass.h"

Person *person = [[Person alloc] init];
person.firstname = @"Jenson";
person.surname = @"Uee";

NSLog(@"%@", [person toJSONString]);
16
X Sham

vielleicht kann dies helfen JLObjectStrip

es ist das gleiche wie das, was jacob gesagt hat, aber es wiederholt sich sogar bis zum Eigentum der Klasse. Sie erhalten dann Wörterbuch/Array und verwenden dann einfach Sbjson/Jsonkit oder was auch immer Sie bevorzugen, um Ihren Json-String zu konstruieren.

1
Joshua

Was ich für meine Objekte mache, ist, dass ich eine Methode namens "toDict" habe, die ein nsdictionary zurückgibt. In dieser Methode setze ich zum Beispiel alle Attribute, die ich brauche/will, in das Wörterbuch

[user setObject:self.first_name forKey:@"first_name"];
[user setObject:self.last_name forKey:@"last_name"];
[user setObject:self.email forKey:@"email"];
0
Travis Delly

Versuchen Sie es mit diesem BWJSONMatcher

Es ist sehr einfach und bequem.

...
NSString *jsonString = @"{your-json-string}";
YourValueObject *dataModel = [YourValueObject fromJSONString:jsonString];

NSDictionary *jsonObject = @{your-json-object};
YourValueObject *dataModel = [YourValueObject fromJSONObject:jsonObject];
...
YourValueObject *dataModel = instance-of-your-value-object;
NSString *jsonString = [dataModel toJSONString];
NSDictionary *jsonObject = [dataModel toJSONObject];
...
0
Burrows Wang