如何在地幔中声明可选的属性?
How to declare optional property in Mantle?
具体情况详情:
在我现在的照片应用中,有这样的情况:先让用户体验而不登录,
但 JSON 中没有从后端响应的某些字段(例如:投票、购买等)。如果用户登录,
该字段添加到 JSON .
我将展示我的实现细节如下:
PhotoListResponseModel(直接继承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
对应的JSON例子如下:
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
}
],
...
...
}
那么,如何让新字段兼容我现有的代码?
可选属性? (我不知道该怎么做。)
或者添加继承自 PhotoListResponseModel & PhotoModel 的子类?
或者任何好主意:)
更新:我注意到了this information,但还是不知道怎么做。
可选属性仅在 Swift 中可用,但 Obj-C 的类似想法 — 具有可能的 nil
值的对象 — 应该运作良好。您可以将以下 NSNumber
属性添加到您的 PhotoModel
:
@property (nonatomic, strong) NSNumber *voted;
@property (nonatomic, strong) NSNumber *purchased;
并在 PhotoModel
对象创建期间从解析的 JSON 中分配您的 BOOL 值,如下所示:
photoModelObject.voted = [NSNumber numberWithBool:[parsedJson valueForKey:@"voted"]];
photoModelObject.purchased = [NSNumber numberWithBool:[parsedJson valueForKey:@"purchased"]];
接下来,当您引用照片对象时,只需检查这些属性是否具有 nil
值。如果是——您的用户没有登录,您不需要显示它们。否则,像这样从它们中提取 BOOL 值:
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
}
具体情况详情:
在我现在的照片应用中,有这样的情况:先让用户体验而不登录, 但 JSON 中没有从后端响应的某些字段(例如:投票、购买等)。如果用户登录, 该字段添加到 JSON .
我将展示我的实现细节如下:
PhotoListResponseModel(直接继承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
对应的JSON例子如下:
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
}
],
...
...
}
那么,如何让新字段兼容我现有的代码?
可选属性? (我不知道该怎么做。)
或者添加继承自 PhotoListResponseModel & PhotoModel 的子类?
或者任何好主意:)
更新:我注意到了this information,但还是不知道怎么做。
可选属性仅在 Swift 中可用,但 Obj-C 的类似想法 — 具有可能的 nil
值的对象 — 应该运作良好。您可以将以下 NSNumber
属性添加到您的 PhotoModel
:
@property (nonatomic, strong) NSNumber *voted;
@property (nonatomic, strong) NSNumber *purchased;
并在 PhotoModel
对象创建期间从解析的 JSON 中分配您的 BOOL 值,如下所示:
photoModelObject.voted = [NSNumber numberWithBool:[parsedJson valueForKey:@"voted"]];
photoModelObject.purchased = [NSNumber numberWithBool:[parsedJson valueForKey:@"purchased"]];
接下来,当您引用照片对象时,只需检查这些属性是否具有 nil
值。如果是——您的用户没有登录,您不需要显示它们。否则,像这样从它们中提取 BOOL 值:
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
}