2

iOS 5 および OSX 10.7 以降では、JSON を解析するときにor (指定されている場合は変更可能なバリアント)NSJSONSerializationを返す を使用してJSON を解析するのは非常に簡単です。値はandなどの一般的な Cocoa 型として解析されますが、 orからデータを取得し、それをアプリのデータ オブジェクトに解析する際にどの程度注意する必要があるか知りたいと思います。私の主な懸念は、キーの値 a) が nil ではなく、b) が予期しない型ではないかどうかです。NSDictionaryNSArrayNSStringNSNumberNSDictionaryNSArray

たとえば、次の 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 を解析するプロセスを処理し、カスタム オブジェクトに入れる前にキーの型と値をチェックする代替ソリューションがある場合は、ぜひ知りたいです。

4

2 に答える 2

2

通常、安定した API に対して実行する必要があります。あなたが心配している種類の変更には、適切なアップグレード時までアプリを変更から隔離する合理的なシステムでバージョン番号の変更を伴う必要があります。そのため、一般的に期待されるデータ型を知っておく必要があります。

場合によっては、API は、多重度に応じて辞書または配列を受け取るように指定します。この場合、クラスを確認し、それに応じて対処する必要があります。

それらを確実にチェックしnilNSNull適切に処理する必要があります。

破損した JSON はパーサーによって処理され、適切なエラーが返されます。

また、RestKit のようなフレームワークを使用して、カスタム オブジェクトへのマッピングを行うこともできます。標準として多くのデータ型チェックを行い、基本的にすべてのマッピング コードを単純な構成に削除します。また、すべてのネットワーク通信 (AFNetworking 経由) も処理します。

于 2013-09-22T18:08:30.387 に答える