「XCodeでJSONを使用してNSDictionaryでカスタムオブジェクトをシリアル化するにはどうすればよいですか?」
私がXCodeを嫌うもう一つの理由を考えて、誰かが1990年代からそれを引きずってくれることを望みます。
カスタムオブジェクトをシリアル化する方法の例を見てみましょう。
次のような.hファイルを持つ非常に単純なUserRecordクラスがあるとします。
@interface UserRecord : NSObject
@property(nonatomic) int UserID;
@property(nonatomic, strong) NSString* FirstName;
@property(nonatomic, strong) NSString* LastName;
@property(nonatomic) int Age;
@end
そして、このような.m:
@implementation UserRecord
@synthesize UserID;
@synthesize FirstName;
@synthesize LastName;
@synthesize Age;
@end
UserRecordオブジェクトを作成し、NSJSONSerializationクラスを使用してシリアル化しようとした場合。
UserRecord* sampleRecord = [[UserRecord alloc] init];
sampleRecord.UserID = 13;
sampleRecord.FirstName = @"Mike";
sampleRecord.LastName = @"Gledhill";
sampleRecord.Age = 82;
NSError* error = nil;
NSData* jsonData2 = [NSJSONSerialization dataWithJSONObject:sampleRecord options:NSJSONWritingPrettyPrinted error:&error];
..それはあなたを笑い、例外をスローし、アプリケーションをクラッシュさせます:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[NSJSONSerialization dataWithJSONObject:options:error:]: Invalid top-level type in JSON write'
この茶番を回避する1つの方法はNSObject
、データをに変換する関数をに追加しNSDictionary
、それをシリアル化することです。
これが私のクラスの新しい.mファイルです。
@implementation UserRecord
@synthesize UserID;
@synthesize FirstName;
@synthesize LastName;
@synthesize Age;
-(NSDictionary*)fetchInDictionaryForm
{
NSMutableDictionary* dict = [[NSMutableDictionary alloc] init];
[dict setObject:[NSNumber numberWithInt:UserID] forKey:@"UserID"];
[dict setObject:FirstName forKey:@"FirstName"];
[dict setObject:LastName forKey:@"LastName"];
[dict setObject:[NSNumber numberWithInt:Age] forKey:@"Age"];
return dict;
}
@end
実際、次のことを行うNSDictionary
場合は、一度にその値を作成できます。
-(NSDictionary*)fetchInDictionaryForm
{
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:UserID], @"UserID",
FirstName, @"FirstName",
LastName,@"LastName",
[NSNumber numberWithInt:Age], @"Age",
nil];
return dict;
}
これを実行すると、オブジェクトのバージョンをシリアル化できるようになります。NSJSONSerialization
NSDictionary
UserRecord* sampleRecord = [[UserRecord alloc] init];
sampleRecord.UserID = 13;
sampleRecord.FirstName = @"Mike";
sampleRecord.LastName = @"Gledhill";
sampleRecord.Age = 82;
NSDictionary* dictionary = [sampleRecord fetchInDictionaryForm];
if ([NSJSONSerialization isValidJSONObject:dictionary])
{
NSError* error = nil;
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:&error];
NSString* jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(@"%@", jsonString);
}
そして、これにより、必要なJSON出力が生成されます。
{
"UserID" : 13,
"FirstName" : "Mike",
"LastName" : "Gledhill",
"Age" : 82
}
衝撃的です。2015年でも、AppleのSDKは単純なint
sとNSString
sのセットをJSONにシリアル化することはできません。
これが他のXCodeの犠牲者に役立つことを願っています。