美文网首页iOS YYModel
使用YYModel中遇到的问题

使用YYModel中遇到的问题

作者: 天空中的球 | 来源:发表于2016-05-31 23:59 被阅读8779次

下班之前被一个 Bug托住了,后台返回了一段类似下面这样的 JSON 字符串,解析老是出问题的。

 {
        "name" = "yang",
        age = 14,
        id = 01,
 },
 {
        "name" = "Tang",
        age = 15,
        id = 03,
 }

就是显示某些字段参数没有加引号,不知道是什么情况,最后貌似发现与这个又无关啦。。。

以为解析出问题了,于是决定先来了解下 JSON,它作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式。目前在我们的 app 中基本都是JSON,以前我们也常用SBJSONJSONKit,当然现在也有用的,但是目前来说,用系统的解析 JSON 也可以满足我们的大部分需求,性能也是比较好的,此处先来记录下系统NSJSONSerialization

+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;
typedef NS_OPTIONS(NSUInteger, NSJSONReadingOptions) { 
      NSJSONReadingMutableContainers = (1UL << 0), 
      NSJSONReadingMutableLeaves = (1UL << 1), 
      NSJSONReadingAllowFragments = (1UL << 2)
} NS_ENUM_AVAILABLE(10_7, 5_0);

参数 NSJSONReadingOptions

  • NSJSONReadingMutableContainers
    // 创建出来的数组和字典就是可变
  • NSJSONReadingMutableLeaves
    // 数组或者字典里面的字符串是可变的(暂时不太好用)
  • NSJSONReadingAllowFragments
    // 意思是需要格式化的json字符串最外层可以不是数组和字典,只要是正确的json格式就行。

推荐使用 ** NSJSONReadingMutableContainers**

NSError *error = nil;
NSDictionary *resultDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
if (error) {
        NSLog(@"error == %@",error.description);
}

然而并没有打印类似Error Domain=NSCocoaErrorDomain Code=3840 的错误,所以继续看是不是 YYModel 用错了

最后我总结出来就是如何解析一个类似的数据:

NSDictionary *testDic = @{@"groupId":@"01",
                            @"result":@[
                                        @{@"name":@"Lucy",  @"sex":@"male"},
                                        @{@"name":@"Lily",  @"sex":@"feMale"},
                                        @{@"name":@"Limei", @"sex":@"male"}
                                        ]
                              };

此处我设置 GroupUserModel 和 UserModel

@interface GroupUserModel : NSObject<YYModel>

@property (nonatomic, copy) NSString *groupId;
@property (nonatomic, strong) NSArray  *result;

@end

#import "GroupUserModel.h"
#import "UserModel.h"

@implementation GroupUserModel
 // 包含
+ (NSDictionary *)modelContainerPropertyGenericClass {
    return @{
             @"result" : [UserModel class],
             @"groupId" : @"groupId"
             };
}

// 白名单
+ (NSArray *)modelPropertyWhitelist {
    return @[@"result",
             @"groupId"];
}
@end
@interface UserModel : NSObject<YYModel>

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *sex;

@end

#import "UserModel.h"

@implementation UserModel


// custom
+ (NSDictionary *)modelCustomPropertyMapper {
    return @{@"name" : @"name",
             @"sex" : @"sex",
             };
}

// 白名单
+ (NSArray *)modelPropertyWhitelist {
    return @[@"name",
             @"sex"];
}

@end
解决
 self.groupUserModel = [GroupUserModel yy_modelWithDictionary:testDic];
 self.dataArray = [NSMutableArray arrayWithArray:self.groupUserModel.result];
 for (UserModel *model in self.dataArray) {
        NSLog(@"name === %@",model.name);
 }

我之前一直写错的原因是下面两个方法写反了

+ (instancetype)arrayWithObject:(ObjectType)anObject;
+ (instancetype)arrayWithArray:(NSArray<ObjectType> *)array;
问题二: 有时我们Model中 .m 文件中写下面几个方法,老是没有提示,需要人工复制。。。
+ (nullable NSDictionary<NSString *, id> *)modelContainerPropertyGenericClass;
+ (nullable NSDictionary<NSString *, id> *)modelCustomPropertyMapper;
+ (nullable NSArray<NSString *> *)modelPropertyWhitelist;
+ (nullable NSArray<NSString *> *)modelPropertyBlacklist;

其实只要让 model 遵从<YYModel>协议就 OK 啦

问题三:直接用数组转 Model
@interface NSDictionary (YYModel)

+ (nullable NSDictionary *)yy_modelDictionaryWithClass:(Class)cls json:(id)json;

注意这个方法,直接套就 OK 啦

总的来说,github 中的说明文档足够可以满足我们的需求,细心阅读,我出问题也是没有详细了解的原因。

备注参考
https://github.com/ibireme/YYModel
http://zhizhi.betahouse.us/2015/11/27/jsonshu-ju-jie-xi-ios/

相关文章

网友评论

  • edison0428:楼主,怎么把一个属性影射到json中的一个数组下的某一个元素
    NSDictionary *dict = @{
    @"id" : @"20",
    @"desciption" : @"好孩子",
    @"name" : @{
    @"newName" : @"lufy",
    @"oldName" : @"kitty",
    @"info" : @[
    @"test-data",
    @{@"nameChangedTime" : @"2013-08-07"}
    ]
    },
    @"other" : @{
    @"bag" : @{
    @"name" : @"小书包",
    @"price" : @100.7
    }
    }
    };

    我的模型类:
    @interface MJStudent : NSObject

    @property (copy, nonatomic) NSString *nameChangedTime;

    @EnD

    怎么把这个属性
    nameChangedTime和json数据的对上呢
    edison0428:@天空中的球 不能直接影射?比如mj的可以:
    @"nameChangedTime" : @"name.info[1].nameChangedTime",
    YYModel的我还不找出这样的方式
    天空中的球:直接的说将其当做一个 Model 啊,再套一层的咯
    TestDataModel *testDataModel
    然后再里面再放入 nameChangedTime
  • 兜麦:像对于模型中如:id关键字,你是直接写重写modelCustomPropertyMapper这方法?
    MyiOS:+ (NSDictionary *)modelCustomPropertyMapper {
    return @{@"name" : @"n",
    @"page" : @"p",
    @"desc" : @"ext.desc",
    @"bookID": @[@"id", @"ID", @"book_id"]};
    }
    天空中的球:@兜麦 对啊,return @{@"channelId" : @"id"}
  • 西西西瓜sama:你好 我还是没太懂用yymodel 怎么把json放到数组里面 像MJ有mj_objectArrayWithKeyValuesArray:responseObject 用你对象类调用 直接放到数组里面 ,YYmodel呢?
    西西西瓜sama:@天空中的球 才看到 不好意思 非常感谢您的回复 我还是用for循环弄得 :joy::joy::joy:
    天空中的球:@西西西瓜sama 你是说的下面这个方法吧?+ (NSArray *)yy_modelArrayWithClass:(Class)cls json:(id)json,此时 json 相当于我们返回的 array(等待转化的),里面首先通过判断验证后,直接用yy_modelWithDictionary转化成我们需要的 Model,再用数组添加起来,形成我们要用数组 model,然后也就是一个我们需要的 array啦。

本文标题:使用YYModel中遇到的问题

本文链接:https://www.haomeiwen.com/subject/juxhdttx.html