将 Objective-C 对象序列化和反序列化为 JSON

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7172001/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:57:50  来源:igfitidea点击:

Serialize and Deserialize Objective-C objects into JSON

objective-cjsoncouchdbnsarraynsdictionary

提问by PokerIncome.com

I need to serialize and deserialize objective-c objects into JSON to store in CouchDB. Do people have any example code for best practice for a general solution? I looked at a few JSON framework and they are stopped at the NSDictionary/NSArray level. i.e. A lot of framework will serialize and deserialize NSDictionary/NSArray into JSON. But I still have to do the work to convert NSDictionary into Objective-C objects.

我需要将objective-c 对象序列化和反序列化为JSON 以存储在CouchDB 中。人们是否有通用解决方案的最佳实践示例代码?我查看了一些 JSON 框架,它们都停留在 NSDictionary/NSArray 级别。即很多框架会将 NSDictionary/NSArray 序列化和反序列化为 JSON。但是我仍然需要完成将 NSDictionary 转换为 Objective-C 对象的工作。

To make things more complex, my Object A can have reference to an NSArray/NSDictionary of Object Bs.

为了使事情更复杂,我的对象 A 可以引用对象 B 的 NSArray/NSDictionary。

My question is very similar to this question with addition of the collection requirement.

我的问题与这个问题非常相似,但增加了收集要求。

Instantiating Custom Class from NSDictionary

从 NSDictionary 实例化自定义类

采纳答案by Jens Alfke

It sounds like you're looking for a serialization library that can let you convert objects of your own custom classes into JSON, and then reconstitute them back. Serialization of property-list types (NSArray, NSNumber, etc.) already exists in 3rd party libraries, and is even built into OS X 10.7 and iOS 5.

听起来您正在寻找一个序列化库,它可以让您将自己的自定义类的对象转换为 JSON,然后重新构建它们。属性列表类型(NSArray、NSNumber 等)的序列化已经存在于 3rd 方库中,甚至内置到 OS X 10.7 和 iOS 5 中。

So, I think the answer is basically "no". I asked this exact question a month or two ago on the cocoa-dev mailing list, and the closest I got to a hit was from Mike Abdullah, pointing to an experimental library he'd written:

所以,我认为答案基本上是“不”。一两个月前,我在 cocoa-dev 邮件列表上问了这个确切的问题,我最接近成功的是 Mike Abdullah,他指着一个他写的实验库:

https://github.com/mikeabdullah/KSPropertyListEncoder

https://github.com/mikeabdullah/KSPropertyListEncoder

This archives objects to in-memory property lists, but as I said there are already APIs for converting those into JSON.

这会将对象归档到内存中的属性列表,但正如我所说,已经有 API 可以将这些对象转换为 JSON。

There's also a commercial app called Objectify that claims to be able to do something similar:

还有一个名为 Objectify 的商业应用程序声称能够做类似的事情:

http://tigerbears.com/objectify/

http://tigerbears.com/objectify/

It's possible I'll end up implementing what you're asking for as part of my CouchCocoa library, but I haven't dived into that task yet.

我可能最终会在我的 CouchCocoa 库中实现您所要求的内容,但我还没有深入研究该任务。

https://github.com/couchbaselabs/CouchCocoa

https://github.com/couchbaselabs/CouchCocoa

回答by X Sham

Finally we can solve this problem easily using JSONModel. This is the best method so far. JSONModel is a library that generically serialize/deserialize your object based on Class. You can even use non-nsobject based for property like int, shortand float. It can also cater nested-complex JSON.

最后我们可以使用JSONModel轻松解决这个问题。这是目前最好的方法。JSONModel 是一个基于 Class 对您的对象进行一般序列化/反序列化的库。您甚至可以将基于非 nsobject 的属性用于int,shortfloat。它还可以满足嵌套复杂的 JSON。

Considering this JSON example:

考虑这个 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) Deserialize example. in header file:

1)反序列化示例。在头文件中:

#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

in implementation file:

在实现文件中:

#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) Serialize Example. In implementation file:

2)序列化示例。在实现文件中:

#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]);

And this is NSLog result from Serialize example:

这是来自 Serialize 示例的 NSLog 结果:

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

回答by Durai Amuthan.H

You can easily add JSON capability to NSObject class with the help of NSDictionary,NSArray and NSJSONSerialization

借助NSDictionary、NSArray 和 NSJSONSerialization,您可以轻松地向 NSObject 类添加 JSON 功能

Serialization:

序列化:

Just see the example it will be very easy to understand.

看例子就很容易理解了。

Adding JSON Capability to NSObject Class:-

向 NSObject 类添加 JSON 功能:-

@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

JSON String Generator:-

JSON 字符串生成器:-

In iOS 5, Apple introduced NSJSONSerialization, for parsing JSON strings so by using that we will generate JSON string.

在 iOS 5 中,Apple 引入了 NSJSONSerialization,用于解析 JSON 字符串,因此通过使用我们将生成 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;
}

Moving towards Apple's implementation is always safer to use since you have the guarantee that it will be maintained and kept up to date.

转向 Apple 的实施始终使用起来更安全,因为您可以保证它会得到维护并保持最新状态。

Way to use:-

使用方法:-

- (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]);

}

Reference

参考

Deserialization:

反序列化:

It's usual way of getting the deserialized data into NSDictionary or NSArray then assign it to class properties.

这是将反序列化数据放入 NSDictionary 或 NSArray 然后将其分配给类属性的常用方法。

I am sure using the methods and ideas used above you can serialize & deserialize complex json easily.

我相信使用上面使用的方法和想法,您可以轻松地序列化和反序列化复杂的 json。

回答by zekel

You may want to try JTObjectMapping. Their description:

您可能想尝试JTObjectMapping。他们的描述:

JTObjectMapping- Inspired by RestKit. A very simple objective-c framework that maps a JSON response from NSDictionary or NSArray to NSObject subclasses for iOS.

JTObjectMapping- 受 RestKit 启发。一个非常简单的objective-c 框架,它将JSON 响应从NSDictionary 或NSArray 映射到iOS 的NSObject 子类。

It's very small (unlike RestKit) and works great.

它非常小(与 RestKit 不同)并且效果很好。

回答by Colin Sullivan

This is possible using the RestKit library's object mapping system.

这可以使用 RestKit 库的对象映射系统来实现。

http://restkit.org/

http://restkit.org/

回答by blauzahn

I have a simple model class, which I wanted to turn into a JSON-Object.

我有一个简单的模型类,我想把它变成一个 JSON 对象。

For this purpose I added a ?jsonData“-method to my model class: The method turns the model properties into foundation objects (int numbers into NSNumber objects etc.) Then a dictionary is populated with these objects and the corresponding keys (also the later JSON keys). After an (optional) check for validity, the JSON data object ist created with the NSJSONSerialization class ?dataWithJSONObject“ method and returned.

为此,我在我的模型类中添加了一个“jsonData”方法:该方法将模型属性转换为基础对象(int 数字转换为 NSNumber 对象等)然后用这些对象和相应的键填充字典(也是后者JSON 键)。在(可选)检查有效性后,使用 NSJSONSerialization 类“dataWithJSONObject”方法创建 JSON 数据对象并返回。

- (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;

}

}