超シンプルなiOS JSONマッパー

少なくとも一度iOSのクライアントサーバーアプリケーションを作成した人は、何らかの形でjson / xml / otherをオブジェクトにマッピングすることに直面していました。 難しい場合もあれば、辞書だけで作業したい場合もありますが、RestKitのような既製のソリューションはすでに多くあります。これは、一般的にあらゆる場面で普遍的な組み合わせです。



多くの理由があるかもしれませんが、私が自分のミニマッパーを書くようになった理由のいくつかは次のとおりです。







まず、 GitHubへリンク 。ここには、将来のモデルの基本クラスのソースコードと、マッパーを使用したサンプルプロジェクトがあります。



賞賛または他の何かの前に、私は短所を説明します:





プラスの-使いやすく、サイズが小さく、クラスの数が少なく、その場合、あなたはそれを理解する必要があり、その仕事をします。



彼と仕事をする方法は? マッパーは1つのクラスで構成されます-TinyMappingModel。これは、モデルのすべての後続クラスの基本クラスです。 各jsonオブジェクトに対して、TinyMappingModelの子孫が作成されます。これには、必要なデータを保存するためのプロパティが含まれている必要があります。 理想的なケースでは、jsonの対応するフィールドが呼び出されるのと同じ方法でそれらを呼び出す必要があります-マッピングは、マジック(KVC)のように、これが不可能な場合について(たとえば、名前がim:name、id、1workのフィールドについて) )、以下に書きます。



TinyMappingModelには4つのメソッドが含まれています。



//public + (instancetype)mapObjectFromDictionary:(NSDictionary *)data; + (NSArray *)mapArrayOfObjects:(NSArray *)data; //protected methods - (NSDictionary *)keyToClassMappingRules; - (NSDictionary *)keyToPropertyNameReplacementRules;
      
      





相続人は、必要に応じて、最後の2つを再定義する必要があります。



-(NSDictionary *)keyToClassMappingRules; -jsonオブジェクトをカスタムクラス(TinyMappingModelの子孫)または配列にマッピングする必要がある場合に再定義されました。 メソッドは、キーフィールド名のペアをjsonに持つディクショナリを返す必要があります。値は、オブジェクトがマッピングされるクラス、またはコレクションの場合は、コレクションを構成するオブジェクトです。 例:



 - (NSDictionary *)keyToClassMappingRules { return @{@"im:name":[TitleModel class], @"im:image":[ImageModel class]}; }
      
      





-(NSDictionary *)keyToPropertyNameReplacementRules; -何らかの理由でjsonで呼び出されるのと同じ方法でクラスのプロパティに名前を付けることができない/したい場合は再定義します。 キーはjsonのフィールドの名前で、値はクラスのプロパティの名前です。次に例を示します。



 - (NSDictionary *)keyToPropertyNameReplacementRules { return @{@"im:name":@"name",@"im:image":@"images"}; }
      
      





例から与えられた2つのメソッドは、実装で実装するために最低限必要な唯一のメソッドです。 クラスのヘッダー(EntryModelなど)は次のようになります。



 @class TitleModel; @interface EntryModel : TinyMappingModel @property (nonatomic, strong) TitleModel *name; @property (nonatomic, strong) NSArray *images; @end
      
      





名前を指定すると、すべてが明確になり、ImageModelタイプのオブジェクトが画像配列に格納されます。もちろん、実装に必要なクラス(この場合はImageModelとTitleModel)をインポートする必要があります。もちろん、行で実行してからNSClassFromStringを実行できますが、 。



次に、どのように働きますか? ネットワークからデータを取得し、何らかの方法でjsonに変換した場合(たとえば、小規模なプロジェクトでAFNetworkingをよく使用します)、次のようになります。



 //data - NSDictionary c json EntryModel *model= [EntryModel mapObjectFromDictionary:data]; // data - NSArray EntryModel *modelArray= [EntryModel mapArrayOfObjects:data];
      
      





バリエーションが可能です。 主なことは、正しいオブジェクトを正しいメソッドに渡すことです。複雑なことは何もありません。



簡単に言えば、マッパーの仕組みを説明します。

最も重要なメソッド+(instancetype)mapObjectFromDictionary:(NSDictionary *)データ、本質的にすべての作業を行います-将来のモデルを作成し、jsonキーを反復処理し、マップするものを決定します(クラス-keyToClassMappingRulesにあるものに応じて)そして、どの名前プロパティで-keyToPropertyNameReplacementRulesに応じて)。 さらに、現在のキーのデータが何であり、何をマップするかに応じて、イベントの開発には3つの方法があります。





それは基本的にそれです。 要約すると、3つの「エンティティ」があります。マッピングするもの、マッピングするクラス、または「プリミティブ」、マッピングするプロパティ(または、指定しない場合はjsonキー名を持つプロパティ)、および配列mapまたはnotの値は、それぞれmapObjectFromDictionaryまたはmapArrayOfObjectsによって呼び出されます。 mapArrayOfObjectsは基本的には何もしません。配列を作成し、[self mapArrayOfObjects:value]または[mappedArray addObject:[self mapObjectFromDictionary:value]を入れます。valueは入力配列の反復中に取得した値です。 以上です。



ご清聴ありがとうございました。ユーザビリティについてのご意見は興味深いものです。ソースをご覧になった場合は、マッパーについてもお聞かせください。



All Articles