我有以下代码:
NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:@"one", @"oneKey",
@"two", @"twoKey", customObject, @"customObjectKey", nil];
if([NSJSONSerialization isValidJSONObject:dict])
{
NSLog(@"Went through.");
}
如果对象是NSString
,它将会通过,但是一旦我将customObject添加到字典中,它就不再有效了。我该如何解决这个问题?任何帮助深表感谢。提前谢谢!
答案 0 :(得分:4)
简单的事实是:你做不到。阅读NSJSONSerialization的文档,该文档未列出NSCoding。 :(
答案 1 :(得分:1)
您无法将自定义对象设置为Dictionary的键。确保你的密钥是NSStrings
来自func +(BOOL)的Foundatoin.framework的文本isValidJSONObject:(id)obj;
- All dictionary keys are NSStrings
答案 2 :(得分:1)
原因:这是因为" customObject"不是:NSArray,NSDictionary和NSString。最有可能是用户定义的类,这是isValidJSONOperation的合同:
/* Returns YES if the given object can be converted to JSON data, NO otherwise. The object must have the following properties: - Top level object is an NSArray or NSDictionary - All objects are NSString, NSNumber, NSArray, NSDictionary, or NSNull - All dictionary keys are NSStrings - NSNumbers are not NaN or infinity Other rules may apply. Calling this method or attempting a conversion are the definitive ways to tell if a given object can be converted to JSON data. */ + (BOOL)isValidJSONObject:(id)obj;
可能的解决方案1:在您的customObject类中添加另一个NSDictonary类型的属性,该属性由示例字典调用,该属性包含要在JSON中添加的属性。
NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:@"one", @"oneKey", @"two", @"twoKey", customObject.dictionary, @"customObjectKey", nil];
可能的解决方案2:使用要从customObject添加到JSON中的属性(和值)创建一个新字典。
答案 3 :(得分:0)
键是字符串,但值可以是任何对象,包括NSNull。
答案 4 :(得分:-1)
“如何在XCode中使用JSON在NSDictionary中序列化自定义对象?”
说明我厌恶XCode的另一个原因,并希望有人会在20世纪90年代拖延它。
让我们来看看我们如何序列化自定义对象。
假设您有一个非常简单的UserRecord类,其中包含.h文件:
@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'
解决这个闹剧的一种方法是向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
和NSString
序列化为JSON。
希望这有助于其他XCode受害者。
答案 5 :(得分:-6)
您需要使用NSCoding协议来序列化自定义对象。
在.h文件中实现NSCoding
协议,并在自定义类的.m文件中实现以下方法。
- (id)initWithCoder:(NSCoder *)aDecoder
{
if(self = [super init]) // this needs to be [super initWithCoder:aDecoder] if the superclass implements NSCoding
{
aString = [[aDecoder decodeObjectForKey:@"aStringkey"] retain];
anotherString = [[aDecoder decodeObjectForKey:@"anotherStringkey"] retain];
}
return self;
}
和
- (void)encodeWithCoder:(NSCoder *)encoder
{
// add [super encodeWithCoder:encoder] if the superclass implements NSCoding
[encoder encodeObject:aString forKey:@"aStringkey"];
[encoder encodeObject:anotherString forKey:@"anotherStringkey"];
}