2

私は次のコードを持っています:

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

オブジェクトが'sの場合は通過しますがNSString、customObjectをディクショナリに追加すると、無効になります。どうすれば修正できますか?どんな助けでも大歓迎です。前もって感謝します!

4

6 に答える 6

4

単純な真実は次のとおりです。できません。NSCodingがリストされていないNSJSONSerializationのドキュメントを読んでください。:(

于 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:カスタムオブジェクトクラスに、JSONに追加する属性を保持するサンプルディクショナリによって呼び出されるNSDictonary型の別の属性を追加します。

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年代からそれを引きずってくれることを望みます。

カスタムオブジェクトをシリアル化する方法の例を見てみましょう。

次のような.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;
}

これを実行すると、オブジェクトのバージョンをシリアル化できるようになります。NSJSONSerializationNSDictionary

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プロトコルを使用する必要があります。

NSCodingプロトコルを.hファイルに実装し、カスタムクラスの.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 に答える