CouchDBに保存するには、objective-cオブジェクトをJSONにシリアライズおよびデシリアライズする必要があります。一般的なソリューションのベストプラクティスのサンプルコードはありますか?いくつかのJSONフレームワークを見て、それらはNSDictionary/NSArrayレベルで停止しています。つまり、多くのフレームワークが、NSDictionary/NSArrayをJSONにシリアライズおよびデシリアライズします。ただし、NSDictionaryをObjective-Cオブジェクトに変換する作業はまだ必要です。
物事をより複雑にするために、私のオブジェクトAはオブジェクトBのNSArray/NSDictionaryへの参照を持つことができます。
私の質問は、収集の要件が追加されたこの質問に非常に似ています。
独自のカスタムクラスのオブジェクトをJSONに変換してから再構成できるシリアル化ライブラリを探しているようです。プロパティリストタイプ(NSArray、NSNumberなど)のシリアル化は、サードパーティライブラリに既に存在し、OS X 10.7およびiOS 5に組み込まれています。
ですから、答えは基本的に「いいえ」だと思います。 1〜2か月前にcocoa-devメーリングリストでこの正確な質問をしましたが、ヒットに最も近かったのはMike Abdullahで、彼が書いた実験ライブラリを指しています。
https://github.com/mikeabdullah/KSPropertyListEncoder
これにより、オブジェクトがメモリ内のプロパティリストにアーカイブされますが、前述したように、それらをJSONに変換するためのAPIが既にあります。
同様のことができると主張するObjectifyという商用アプリもあります。
http://tigerbears.com/objectify/
CouchCocoaライブラリの一部として、あなたが求めているものを実装することになる可能性はありますが、私はまだそのタスクに飛び込みませんでした。
最後に、 JSONModel を使用してこの問題を簡単に解決できます。これはこれまでのところ最良の方法です。 JSONModelは、クラスに基づいてオブジェクトを一般的にシリアライズ/デシリアライズするライブラリです。 int
、short
、およびfloat
などのプロパティに対して非nsobjectベースを使用することもできます。また、ネストされた複雑なJSONにも対応できます。
この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)例の逆シリアル化。ヘッダーファイル内:
#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
実装ファイル内:
#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)シリアル化の例。実装ファイル内:
#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]);
そして、これはSerializeの例からのNSLogの結果です:
{ "accounting" : [{ "firstName" : "Uee",
"lastName" : "Bae",
"age" : 22 }
],
"sales" : [{ "firstName" : "Sara",
"lastName" : "Jung",
"age" : 20 }
]}
NSDictionary、NSArrayおよびNSJSONSerializationを使用して、JSON機能をNSObjectクラスに簡単に追加できます。
例を見るだけで理解しやすくなります。
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:-
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;
}
Appleの実装に向けて移行することは、それが維持され、最新の状態に保たれるという保証があるため、常に安全に使用できます。
使用方法:-
- (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]);
}
デシリアライズされたデータをNSDictionaryまたはNSArrayに取得し、それをクラスプロパティに割り当てる通常の方法です。
上記で使用した方法とアイデアを使用すると、複雑なJSONを簡単にシリアライズおよびデシリアライズできます。
JTObjectMapping を試してみてください。彼らの説明:
JTObjectMapping-RestKitに触発されました。 NSDictionaryまたはNSArrayからのJSONレスポンスをiOSのNSObjectサブクラスにマッピングする非常にシンプルなObjective-Cフレームワーク。
それは非常に小さく(RestKitとは異なり)動作します。
これは、RestKitライブラリのオブジェクトマッピングシステムを使用して可能です。
シンプルなモデルクラスがあり、それをJSONオブジェクトに変換したいと考えました。
この目的のために、モデルクラスに「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;
}