18

自分のカスタムクラスをJSONシリアル化したいと思います。私はObjective-C/iOS5で働いています。次のことをしたいのですが。

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

NSJSONSerialization(および他のいくつかのライブラリ)では、「person」クラスがNSDictionaryなどに基づいている必要があるようです。定義したいカスタムオブジェクトを(理由の範囲内で)シリアル化するものが必要です。

Person.hが次のようになっていると想像してみましょう。

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

インスタンス用に生成されたJSONを次のようにしたいと思います。

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

私のアプリはARCを使用しています。オブジェクトを使用してシリアル化と逆シリアル化の両方を行うものが必要です。

どうもありがとう。

4

5 に答える 5

23

JSONに入力できるデータは単純なオブジェクト(NSString、NSArray、NSNumberなど)だけであり、カスタムクラスやスカラー型ではないため、これは注意が必要です。なんで?これらのすべてのデータ型をこれらのタイプのオブジェクトにラップするためのあらゆる種類の条件ステートメントを作成しない場合、解決策は次のようになります。

//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];

私が前に述べたことのために、これはトリッキーです。スカラー型またはカスタムオブジェクトがある場合は、すべてが失敗します。このようなことを実現することが非常に重要な場合は、時間をかけて、値をNSDictionaryセーフオブジェクトにラップするために必要な条件ステートメントを支援するプロパティタイプを確認できるRicardのリンクを確認することをお勧めします。

于 2012-05-09T14:17:26.583 に答える
16

これで、 JSONModelを使用してこの問題を簡単に解決できます。JSONModelは、クラスに基づいてオブジェクトを一般的にシリアル化/逆シリアル化するライブラリです。、、などintのプロパティに基づいた非nsobjectを使用することもできます。ネストされた複雑なJSONにも対応できます。shortfloat

を逆シリアル化します。あなたの例を参照すると、ヘッダーファイルで:

#import "JSONModel.h"

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

実装ファイル内:

#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):
}

シリアル化の例。実装ファイル:

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

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

NSLog(@"%@", [person toJSONString]);
于 2013-05-27T09:37:14.817 に答える
1

多分これはJLObjectStripを助けることができます。

jacobが言ったことと同じですが、クラスのプロパティに対しても反復します。これにより、辞書/配列が得られ、sbjson/jsonkitまたはjson文字列の作成に使用したいものを使用できます。

于 2013-04-29T09:49:21.767 に答える
0

これを試してみてくださいBWJSONMatcher

とてもシンプルで便利です。

...
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];
...
于 2015-10-29T03:44:15.313 に答える
0

私が自分のオブジェクトに対して行うことは、nsdictionaryを返す「toDict」と呼ばれるメソッドを持っていることです。この方法では、必要な/欲しいすべての属性を辞書に設定します。

[user setObject:self.first_name forKey:@"first_name"];
[user setObject:self.last_name forKey:@"last_name"];
[user setObject:self.email forKey:@"email"];
于 2016-11-25T04:28:37.143 に答える