3

JSON ディクショナリまたは配列を取得して、JSON タグと同じ名前のプロパティを持つカスタム オブジェクトに直接マップできるかどうかを検索してきましたが、それに関する情報は見つかりませんでした。

次のように、JSON 辞書を手動で解析してきました。

id deserializedObj = nil;
id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData
                                                options:NSJSONReadingAllowFragments
                                                  error:&error];
if ([jsonObject isKindOfClass:[NSDictionary class]]) {
        NSDictionary *jsonDictionary = (NSDictionary *)jsonObject;

  if ([jsonDictionary objectForKey:idTag] != [NSNull null])
     [myObject setID:[[jsonDictionary objectForKey:@"id"] integerValue]];

  // Rest of properties
}

しかし、各ディクショナリ エントリを手動で解析する必要があり、それをカスタム オブジェクトに直接シリアル化する方法がないのは奇妙だと思います。他に高速な方法はありませんか?

注: iOS 5 以降と互換性のあるアプリが必要です

前もって感謝します

4

3 に答える 3

8

Motisというライブラリを提案します。これは、KeyValueCoding を介してオブジェクト マッピングを行う NSObject のカテゴリです。このカテゴリの優れた点は、非常に軽量で、(イントロスペクションを介して) プロパティのクラス タイプに適合するように自動的に値の検証を実行することです。

最も重要なことは、「JSONKey」と「PropertyName」のペアを使用して、NSObject サブクラスでマッピング (辞書) を定義することです。

また、配列がある場合は、配列名からそのコンテンツのクラス型へのマッピングを定義して、配列コンテンツの自動オブジェクト マッピングを有効にすることができます。

たとえば、次の JSON をカスタム オブジェクトにマップしようとすると、次のようになります。

{"video_id": 23,
 "video_title": "My holidays in Paris",
 "video_uploader":{"user_id":55,
                   "user_username": "johndoe"
                  },
 "video_people":[{"user_id":55,
                   "user_username": "johndoe"
                 },
                 {"user_id":45,
                   "user_username": "jimmy"
                 },
                 {"user_id":55,
                   "user_username": "martha"
                 }
                ]
 }

NSObject サブクラスで実装します。

// --- Video Object --- //
@interface Video : NSObject
@property (nonatomic, assing) NSInteger videoId; 
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) User *uploader;
@property (nonatomic, strong) NSArray *peopleInVideo; // <-- Array of users
@end

@implementation Video
+ (NSDictionary*)mts_mapping
{
    return @{@"video_id" : mts_key(videoId),
             @"video_title" : mts_key(title),
             @"video_uploader" : mtsk_key(uploader),
             @"video_people": mts_key(peopleInVideo),
            };
}

+ (NSDictionary*)mts_arrayClassMapping
{
    return @{mts_key(peopleInVideo): User.class};
}

@end

// --- User Object --- //
@interface User : NSObject
@property (nonatomic, assing) NSInteger userId; 
@property (nonatomic, strong) NSString *username;
@end

@implementation User
+ (NSDictionary*)mts_mapping
{
    return @{@"user_id" : mts_key(userId),
             @"user_username" : mts_key(username),
            };
}

@end

解析とオブジェクト マッピングを実行するには、次のようにします。

NSData *data = ... // <-- The JSON data
NSError *error = nil;
NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];

if (error)
    return; // if error, abort.

Video *video = [[Video alloc] init];
[video mts_setValuesForKeysInDictionary:jsonObject]; // <-- Motis Object Mapping 

NSLog(@"Video: %@", video.description);

それは簡単です。ここで詳細を読むことができます: http://github.com/mobilejazz/Motis

詳細については、 MobileJazz ブログに書いた KeyValueCoding と分散オブジェクト マッピングを使用する利点に関するブログ投稿を確認してください。

役立つことを願っています。

于 2014-03-18T09:28:10.373 に答える
4

プロパティを使用して独自の NSObject サブクラスを作成し、JSON デシリアライゼーションから返されたすべての NSDictionary キーを探索するループで Key-Value Coding を使用してそれらを設定できます。もちろん、各ディクショナリ キーはオブジェクト プロパティと一致する必要があります。 キー値コーディング

于 2013-07-29T17:00:16.923 に答える