web-dev-qa-db-fra.com

Sérialiser et désérialiser des objets Objective-C en JSON

J'ai besoin de sérialiser et de désérialiser les objets objective-c en JSON pour les stocker dans CouchDB. Les gens ont-ils un exemple de code pour les meilleures pratiques pour une solution générale? J'ai regardé quelques frameworks JSON et ils sont arrêtés au niveau NSDictionary/NSArray. c'est-à-dire que beaucoup de frameworks sérialiseront et désérialiseront NSDictionary/NSArray en JSON. Mais je dois encore faire le travail pour convertir NSDictionary en objets Objective-C.

Pour rendre les choses plus complexes, mon objet A peut faire référence à un NSArray/NSDictionary of Object Bs.

Ma question est très similaire à cette question avec l'ajout de l'exigence de collecte.

Instanciation d'une classe personnalisée à partir de NSDictionary

32
PokerIncome.com

Il semble que vous recherchiez une bibliothèque de sérialisation qui puisse vous permettre de convertir des objets de vos propres classes personnalisées en JSON, puis de les reconstituer. La sérialisation des types de listes de propriétés (NSArray, NSNumber, etc.) existe déjà dans les bibliothèques tierces et est même intégrée à OS X 10.7 et iOS 5.

Donc, je pense que la réponse est fondamentalement "non". J'ai posé cette question exacte il y a un mois ou deux sur la liste de diffusion de cacao-dev, et le plus proche d'un hit était de Mike Abdullah, pointant vers une bibliothèque expérimentale qu'il avait écrite:

https://github.com/mikeabdullah/KSPropertyListEncoder

Cela archive les objets dans des listes de propriétés en mémoire, mais comme je l'ai dit, il existe déjà des API pour les convertir en JSON.

Il existe également une application commerciale appelée Objectify qui prétend pouvoir faire quelque chose de similaire:

http://tigerbears.com/objectify/

Il est possible que je finisse par implémenter ce que vous demandez dans le cadre de ma bibliothèque CouchCocoa, mais je n'ai pas encore plongé dans cette tâche.

https://github.com/couchbaselabs/CouchCocoa

10
Jens Alfke

Enfin, nous pouvons résoudre ce problème facilement en utilisant JSONModel . C'est la meilleure méthode jusqu'à présent. JSONModel est une bibliothèque qui sérialise/désérialise génériquement votre objet en fonction de Class. Vous pouvez même utiliser un non-nsobject basé sur des propriétés telles que int, short et float. Il peut également prendre en charge le JSON complexe imbriqué.

Considérant cet exemple JSON:

{ "accounting" : [{ "firstName" : "John",  
                    "lastName"  : "Doe",
                    "age"       : 23 },

                  { "firstName" : "Mary",  
                    "lastName"  : "Smith",
                    "age"       : 32 }
                              ],                            
  "sales"      : [{ "firstName" : "Sally", 
                    "lastName"  : "Green",
                    "age"       : 27 },

                  { "firstName" : "Jim",   
                    "lastName"  : "Galley",
                    "age"       : 41 }
                  ]}

1) Exemple de désérialisation . dans le fichier d'en-tête:

#import "JSONModel.h"

@interface Person : JSONModel 
@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;
@property (nonatomic, strong) NSNumber *age;
@end

@protocol Person;

@interface Department : JSONModel
@property (nonatomic, strong) NSMutableArray<Person> *accounting;
@property (nonatomic, strong) NSMutableArray<Person> *sales;
@end

dans le fichier d'implémentation:

#import "JSONModelLib.h"
#import "myJSONClass.h"

NSString *responseJSON = /*from example*/;
Department *department = [[Department alloc] initWithString:responseJSON error:&err];
if (!err)
{
    for (Person *person in department.accounting) {

        NSLog(@"%@", person.firstName);
        NSLog(@"%@", person.lastName);
        NSLog(@"%@", person.age);         
    }

    for (Person *person in department.sales) {

        NSLog(@"%@", person.firstName);
        NSLog(@"%@", person.lastName);
        NSLog(@"%@", person.age);         
    }
}

2) Exemple de sérialisation . Dans le fichier d'implémentation:

#import "JSONModelLib.h"
#import "myJSONClass.h"

Department *department = [[Department alloc] init];

Person *personAcc1 = [[Person alloc] init];
personAcc1.firstName = @"Uee";
personAcc1.lastName = @"Bae";
personAcc1.age = [NSNumber numberWithInt:22];
[department.accounting addOject:personAcc1];

Person *personSales1 = [[Person alloc] init];
personSales1.firstName = @"Sara";
personSales1.lastName = @"Jung";
personSales1.age = [NSNumber numberWithInt:20];
[department.sales addOject:personSales1];

NSLog(@"%@", [department toJSONString]);

Et voici le résultat NSLog de l'exemple Serialize:

{ "accounting" : [{ "firstName" : "Uee",  
                    "lastName"  : "Bae",
                    "age"       : 22 }
                 ],                            
  "sales"      : [{ "firstName" : "Sara", 
                    "lastName"  : "Jung",
                    "age"       : 20 }
                  ]}
35
X Sham

Vous pouvez facilement ajouter la capacité JSON à la classe NSObject à l'aide de NSDictionary, NSArray et NSJSONSerialization

Sérialisation:

Il suffit de voir l'exemple, il sera très facile à comprendre.

Ajout de la capacité JSON à la classe NSObject: -

@interface JsonClassEmp : NSObject

@property(strong,nonatomic)NSString *EmpName,*EmpCode;

-(NSDictionary*)GetJsonDict;

@end

@implementation JsonClassEmp

@synthesize EmpName,EmpCode;

//Add all the properties of the class in it.
-(NSDictionary*)GetJsonDict
{
    return [NSDictionary dictionaryWithObjectsAndKeys:EmpName,@"EmpName",EmpCode,@"EmpCode", nil];
}

@end

Générateur de chaînes JSON: -

Dans iOS 5, Apple a introduit NSJSONSerialization, pour analyser les chaînes JSON donc en utilisant cela, nous générerons une chaîne JSON.

-(NSString*)GetJSON:(id)object
{
    NSError *writeError = nil;

    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:object options:NSJSONWritingPrettyPrinted error:&writeError];

    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

    return jsonString;
}

Passer à la mise en œuvre d'Apple est toujours plus sûr à utiliser, car vous avez la garantie qu'elle sera maintenue et mise à jour.

Façon d'utiliser: -

- (void)viewDidLoad
{
    [super viewDidLoad];

    JsonClassEmp *emp1=[[JsonClassEmp alloc]init];

    [emp1 setEmpName:@"Name1"];

    [emp1 setEmpCode:@"1"];

    JsonClassEmp *emp2=[[JsonClassEmp alloc]init];

    [emp2 setEmpName:@"Name2"];

    [emp2 setEmpCode:@"2"];

    //Add the NSDictionaries of the instances in NSArray
    NSArray *arrEmps_Json=@[emp1.GetJsonDict,emp2.GetJsonDict];

    NSLog(@"JSON Output: %@", [self GetJSON:arrEmps_Json]);

}

Référence

Désérialisation:

C'est la manière habituelle d'obtenir les données désérialisées dans NSDictionary ou NSArray, puis de les affecter aux propriétés de classe.

Je suis sûr qu'en utilisant les méthodes et les idées utilisées ci-dessus, vous pouvez sérialiser et désérialiser facilement json complexe.

7
Durai Amuthan.H

Vous voudrez peut-être essayer JTObjectMapping . Leur description:

JTObjectMapping - Inspiré par RestKit. Un cadre objectif-c très simple qui mappe une réponse JSON de NSDictionary ou NSArray aux sous-classes NSObject pour iOS.

Il est très petit (contrairement à RestKit) et fonctionne très bien.

4
zekel

Ceci est possible en utilisant le système de mappage d'objets de la bibliothèque RestKit.

http://restkit.org/

2
Colin Sullivan

J'ai une classe de modèle simple, que je voulais transformer en un objet JSON.

À cet effet, j'ai ajouté une méthode "jsonData" à ma classe de modèle: la méthode transforme les propriétés du modèle en objets de base (les nombres int en objets NSNumber, etc.) Ensuite, un dictionnaire est rempli avec ces objets et les clés correspondantes (également la dernière Clés JSON). Après une vérification de validité (facultatif), l'objet de données JSON est créé avec la méthode NSJSONSerialization classe "dataWithJSONObject" et renvoyé.

- (NSData *)jsonData {

NSDictionary *root = @{@"Sport" : @(_sportID),          // I´m using literals here for brevity’s sake
                       @"Skill" : @(_skillLevel),
                       @"Visibility" : @(_visibility),
                       @"NotificationRange" : @(_notificationRange)};

if ([NSJSONSerialization isValidJSONObject:root]) {
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:root
                                    options:0
                                      error:nil];
    return jsonData;
}
return nil;

}

2
blauzahn
1
Mirko Brunner