2

我有以下代码:

NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:@"one", @"oneKey", 
@"two", @"twoKey", customObject, @"customObjectKey", nil];
if([NSJSONSerialization isValidJSONObject:dict])
{
    NSLog(@"Went through.");
}

如果对象是NSString's,它将通过,但是一旦我将 customObject 添加到字典中,它就不再有效。我该如何解决?任何帮助深表感谢。提前致谢!

4

6 回答 6

4

简单的事实是:你不能。阅读 NSJSONSerialization 的文档,其中没有列出 NSCoding。:(

于 2012-10-11T19:29:22.040 回答
1

您不能将自定义对象设置为 Dictionary 的键。确定,你的键是什么 NSStrings

来自 func +(BOOL) isValidJSONObject:(id)obj 的 Foundatoin.framework 的文本;

- All dictionary keys are NSStrings
于 2012-06-04T06:20:26.967 回答
1

原因:这是因为“customObject”不是:NSArray、NSDictionary 或 NSString。很可能是用户定义的类,这是 isValidJSONOperation 的约定:

/* 如果给定对象可以转换为 JSON 数据,则返回 YES,否则返回 NO。该对象必须具有以下属性:
    - 顶级对象是 NSArray 或 NSDictionary
    - 所有对象都是 NSString、NSNumber、NSArray、NSDictionary 或 NSNull
    - 所有字典键都是 NSStrings
    - NSNumbers 不是 NaN 或无穷大
 其他规则可能适用。调用此方法或尝试转换是判断给定对象是否可以转换为 JSON 数据的确定方法。
 */
+ (BOOL)isValidJSONObject:(id)obj;

可能的解决方案 1:将另一个类型为 NSDictonary 的属性添加到您的 customObject 类中,该属性由示例字典调用,该字典包含要添加到 JSON 中的属性。

NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:@"one", @"oneKey",
@"two", @"twoKey", customObject.dictionary, @"customObjectKey", nil];

可能的解决方案 2:使用要从 customObject 的 JSON 添加的属性(和值)创建一个新字典。

于 2015-01-08T09:26:10.793 回答
0

键是字符串,但值可以是任何对象,包括 NSNull。

于 2012-10-07T19:20:56.610 回答
-1

“如何在 XCode 中使用 JSON 序列化 NSDictionary 中的自定义对象?”

找出我讨厌 XCode 的另一个原因,并希望有人能把它从 1990 年代拖出来。

让我们通过一个示例来说明我们期望如何序列化自定义对象。

假设您有一个非常简单的 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 也无法将一组简单的ints 和NSStrings 序列化为 JSON。

希望这可以帮助其他 XCode 受害者。

于 2015-01-16T15:22:54.677 回答
-7

您需要使用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"];
}
于 2012-06-04T06:19:04.890 回答