JSONModel arrayOfModelsFromDictionaries — error when key is SOMETIMES missing

泪湿孤枕 提交于 2019-12-12 01:06:42

问题


So I'm just getting started with the youtube data API and JSONModel. Using their YouTubeBrowserDemo as my starting point: https://github.com/JSONModel/YouTubeBrowserDemo.

So it's working fine except sometimes the MediaThumnail entry for certain videos doesn't have a time entry. Some returned videos have them, some don't. I'm fine with this and can of course write simple checks when I'm displaying the data, but when arrayOfModelsFromDictionaries is called to convert the returned JSON to my models, I get the following error and none of the JSON is converted if only one (or more) of the time entries are missing:

[JSONModel.m:205] Incoming data was invalid [MediaThumbnail initWithDictionary:]. Keys missing: {(
    time
)}

How do I make this conversion NOT an all-or-nothing conversion? Some kind of conditional check when mapping? Or is there a different JSONModel method that already does this?


Here's the API call and attempt to convert the resulting JSON:

 [JSONHTTPClient getJSONFromURLWithString:searchURL
                                  completion:^(NSDictionary *json, JSONModelError *err) {


                                      //got JSON back
                                      NSLog(@"Got JSON from web: %@", json);

                                      if (err) {

                                          NSLog(@"err = %@",err);



                                          [[[UIAlertView alloc] initWithTitle:@"Error"
                                                                      message:[err localizedDescription]
                                                                     delegate:nil
                                                            cancelButtonTitle:@"Close"
                                                            otherButtonTitles: nil] show];
                                          return;
                                      }




                                      //initialize the models 
                                      // THIS IS WHERE IT SOMETIMES RETURNS OBJECTS INTO SELF.OBJECTS IF ALL THE MEDIATHUMBNAILS AHVE TIME ENTRIES, OR NOTHING IF ONE OR MORE ARE MISSING
                                      self.objects = [VideoModel arrayOfModelsFromDictionaries:
                                                      json[@"feed"][@"entry"]
                                                      ];




                                      if (self.objects) {
                                          NSLog(@"Loaded successfully models");

                                      }

Here's my VideoModel.h is close to theirs - only one added property:

@interface VideoModel : JSONModel

@property (strong, nonatomic) NSString* title;
@property (strong, nonatomic) NSArray<VideoLink>* link;
@property (strong, nonatomic) NSArray<MediaThumbnail>* thumbnail;
@property (strong, nonatomic) NSArray<Author>* author;

@end

VideoModel.m:

@implementation VideoModel

+(JSONKeyMapper*)keyMapper
{
    return [[JSONKeyMapper alloc] initWithDictionary:@{
            @"media$group.media$thumbnail":@"thumbnail",
            @"title.$t": @"title"
            }];
}

@end

And my MediaThumnail.h:

@interface MediaThumbnail : JSONModel

@property (strong, nonatomic) NSURL* url;
@property (assign, nonatomic) int width;
@property (assign, nonatomic) int height;
@property (strong, nonatomic) NSString* time;

@end

MediaThumnail.m:

@implementation MediaThumbnail

@end

回答1:


It's very easy to make some of your model's properties optional with JSONModel - have a look for an example here (more examples about different features on the same page):

https://github.com/icanzilb/JSONModel#optional-properties-ie-can-be-missing-or-null

All in all what you need to do is add the <Optional> protocol to your property, like so:

@property (strong, nonatomic) NSString<Optional>* time;

That's it. Don't forget when using the property to check first if it's nil or has a value.




回答2:


Create an NSNull+JSON category and import that in the JSONModel.m or in the {ProjectName}-Prefix.pch

#import <Foundation/Foundation.h>

@interface NSNull (JSON)

@end

#import "NSNull+JSON.h"

@implementation NSNull (JSON)

- (NSUInteger)length { return 0; }

- (NSInteger)integerValue { return 0; };

- (NSInteger)intValue { return 0; };

- (float)floatValue { return 0; };

- (NSString *)description { return @"0(NSNull)"; }

- (NSArray *)componentsSeparatedByString:(NSString *)separator { return @[]; }

- (id)objectForKey:(id)key { return nil; }

- (BOOL)boolValue { return NO; }

@end

I have been using that in many of my projects. I prefer to use this process so even if my server introduced any new JSON key for the API response, JSON parsing will still work without any crash or issue...



来源:https://stackoverflow.com/questions/21536241/jsonmodel-arrayofmodelsfromdictionaries-error-when-key-is-sometimes-missing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!