iOS 5 および OSX 10.7 以降では、JSON を解析するときにor (指定されている場合は変更可能なバリアント)NSJSONSerialization
を返す を使用してJSON を解析するのは非常に簡単です。値はandなどの一般的な Cocoa 型として解析されますが、 orからデータを取得し、それをアプリのデータ オブジェクトに解析する際にどの程度注意する必要があるか知りたいと思います。私の主な懸念は、キーの値 a) が nil ではなく、b) が予期しない型ではないかどうかです。NSDictionary
NSArray
NSString
NSNumber
NSDictionary
NSArray
たとえば、次の JSON オブジェクトがあるとします。
{
"version":1,
"title":"Some interesting title",
"info":"Some detail here"
}
現在、これは NSDictionary として解析されます。
@{
@"version": @1,
@"title":@"Some interesting title",
@"info": @"Some detail here"
}
私の問題は、返されたもののデータ型をチェックするときに注意する必要があることです。理論的には、適切な API を使用している場合は常にバージョン キーの数値を取得する必要がありますが、何らかの理由でサーバー側で次のように変更された場合はどうなるでしょうか。
{ "version:"1", ... }
さらに悪いことに:
{ "version:"one", ... }
次のコードを実行しようとすると、例外が発生し、アプリがクラッシュします。
NSNumber * myNumber = dictionary[@"version"];
if ([myNumber isEqualToNumber:@1])
{
...
}
dictionary[@"version"]
a) は NSString であり、b) isEqualToNumber: は NSNumber でのみ使用できるため、コードは実行されません(認識されないセレクター例外、アプリがクラッシュします)。
同様に、"info" の JSON が次のように変更された場合、問題が発生する可能性があります。
{
"info":{
"code":200,
"message":"Some detail here"
}
}
私のアプリNSString
がキーの を期待している場合、info
代わりに NSDictionary が見つかるため、再びクラッシュします。
ほとんどの場合、API またはファイルからのほとんどの JSON は適切であり、現在のバージョンのアプリでサポートされている必要があります。すべての JSON がバージョン管理され、サーバー側で正しくエンコードされていることが望まれます。場合によっては、JSON が破損または変更されていると、アプリがクラッシュする可能性がありますが、これは回避したいと考えています。
考えられる解決策:
- すべての単一のキーと値のペアをチェックして、
isKindOfClass:
またはrespondsToSelector:
true の場合にのみ続行します - キーが存在することを確認し、nil の場合はエラーを生成します
- すべてを try/catch ブロックにまとめますが、使用できるものを使用し、データに問題がある場合はエラーが発生するようにしたいと考えています。これにより、多くの @try/@catch ステートメントが互いに含まれる可能性があります
これらのソリューションはそれぞれかなりかさばり、可能であれば避けたいコードに多くを追加します(「良い」JSONを使用する場合は完全に可能です)。JSON を解析するプロセスを処理し、カスタム オブジェクトに入れる前にキーの型と値をチェックする代替ソリューションがある場合は、ぜひ知りたいです。