1

Specific situation detail:

In my current photo app, There are such situation : allow user experience first without log in, but no have some field(e.g:voted,purchased ,etc) in the JSON responded from backend. If user logged in, the field is added in JSON .

I'll show off my implement details as following:

PhotoListResponseModel (directly inherit MTLModel)

@interface PhotoListResponseModel : MTLModel <MTLJSONSerializing>
...
@property (nonatomic, copy, readonly) NSNumber *foo;
@property (nonatomic, copy, readonly) NSArray<PhotoModel *> *subPhotos;

@end

@interface PhotoModel : MTLModel <MTLJSONSerializing>

@property (nonatomic, copy, readonly) NSNumber *photoID;
@property (nonatomic, copy, readonly) NSURL *imageUrl;
...
@end


@implementation PhotoListResponseModel
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
   return @{@"foo": @"foo"
            @"subPhotos": @"photos"
            };
}

+ (NSValueTransformer *)subPhotosJSONTransformer {
    return [MTLJSONAdapter arrayTransformerWithModelClass:PhotoModel.class];
}

@end

@implementation PhotoModel
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
    return @{
             @"photoID": @"id",
             @"userID": @"user_id",
             };
}

@end

Correspondly, the JSON example as following:

noAuthPhoto.json

{
        "foo": 1,
        "photos": [
                   {
                   "id": 204748881,
                   "image_url": "https://foo1/bar1",
                   },
                   {
                   "id": 204996257,
                   "image_url": "https://foo2/bar2"
                   }
                   ],
                   …
                   …
    }

AuthedPhoto.json

{
        "foo": 1,
        "photos": [
                   {
                   "id": 204748881,
                   "image_url": "https://foo1/bar2”,
                   "voted": false,
                   "purchased": false
                   },
                   {
                   "id": 204996257,
                   "image_url": "https://foo2/bar2”,
                   "voted": false,
                   "purchased": false
                   }
                 ],
                 ...
                 ...
    }

So, how let new field can compatible my already existing code?

Optional Property? (I not know how to do this.)

Or add a subclass of inherit from PhotoListResponseModel & PhotoModel?

Or any good idea : )


Update: I noticed this information,but still don't know how to do it.

0xxxD
  • 181
  • 10

1 Answers1

0

Optional properties are only available in Swift, but similar idea for the Obj-C — objects with possible nil value — should work well. You can add the following NSNumber properties to your PhotoModel:

@property (nonatomic, strong) NSNumber *voted;
@property (nonatomic, strong) NSNumber *purchased;

And assign your BOOL values from parsed JSON during PhotoModel object creation like this:

photoModelObject.voted = [NSNumber numberWithBool:[parsedJson valueForKey:@"voted"]];
photoModelObject.purchased = [NSNumber numberWithBool:[parsedJson valueForKey:@"purchased"]];

Next, when you reference your photo object, just check if these properties have nil value. If they are — your user is not logged in and you don't need to show them. Otherwise, extract BOOL value from them like this:

if (photoModelObject.voted && photoMobelObject.purchased) {
    BOOL isVoted = [photoModelObject.voted boolValue];
    BOOL isPurchased = [photoModelObject.purchased boolValue];

    // Use booleans to present info for registered users
} else {
    // There is no info about votes and purchasing provided for the current user
}
0xNSHuman
  • 638
  • 5
  • 8
  • let me try as you said – 0xxxD Apr 02 '17 at 11:19
  • @0xDatou Please check updated version, I fixed one minor thing: properties must be declared with `strong`, not `assign` ownership qualifiers. – 0xNSHuman Apr 02 '17 at 11:21
  • although accepted answer, but I not think should be declared with strong. – 0xxxD Apr 02 '17 at 12:06
  • @0xDatou `NSNumber`, as an object, must be declared as `strong` or `weak` depending on your final goals, but certainly not as `assign`. Otherwise you'll never get your boolean out of it, even if you put it there. Related question: http://stackoverflow.com/questions/11013587/differences-between-strong-and-weak-in-objective-c – 0xNSHuman Apr 02 '17 at 12:15
  • @0xDatou `strong` reference in your particular case is the safest option without any negative effects. – 0xNSHuman Apr 02 '17 at 12:20