【问题标题】:How to declare optional property in Mantle?如何在 Mantle 中声明可选属性?
【发布时间】:2017-08-27 07:20:08
【问题描述】:

具体情况详解:

在我目前的拍照应用中,有这样的情况:先让用户体验,无需登录, 但从后端响应的 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,但仍然不知道该怎么做。

【问题讨论】:

    标签: ios objective-c jsonserializer github-mantle


    【解决方案1】:

    可选属性仅在 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
    }
    

    【讨论】:

    • 照你说的让我试试
    • @0xDatou 请检查更新版本,我修复了一个小问题:必须使用 strong 声明属性,而不是 assign 所有权限定符。
    • 虽然接受了答案,但我认为不应该用strong来声明。
    • @0xDatou NSNumber,作为一个对象,必须声明为strongweak,具体取决于您的最终目标,但肯定不是assign。否则,即使你把它放在那里,你也永远不会得到你的布尔值。相关问题:stackoverflow.com/questions/11013587/…
    • @0xDatou strong 在您的特定情况下参考是最安全的选择,没有任何负面影响。
    猜你喜欢
    • 2019-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-31
    • 2015-02-13
    • 2018-09-23
    • 2021-09-19
    • 2014-05-17
    相关资源
    最近更新 更多