模型解析之iOS笔记摘录

目录
  1. JSONModel
  2. MJExtension(建议)
  3. YYModel

前言

原本使用的一直是JSONModel,因为后台的一次失误(数组类型的字段偶尔返回成字符串),造成数据解析不出来。
而且JSONModel侵入性较高(1.需要继承JSONModel;2.处理元素类型为类类型的数组属性时繁琐)。

因此,果断放弃使用JSONModel,改用MJExtension。

1. JSONModel

  1. 使用

第一步 :cocoaPods引入

# JSONModel
pod 'JSONModel'

第二步:存入pch

#import <JSONModel/JSONModel.h>    

第三步:自定义模型

// 每一个模型,继承JSONModel
YTPersonModel : JSONModel

第四步:转换

字典转模型

// 方式一
PersonModel *personM=[[PersonModel alloc] initWithDictionary:dic error:nil]
// 方式二
_guideArr=[YTPublishDZModel arrayOfModelsFromDictionaries:gjArr error:nil];
// 模型转字典
NSDictionary* dict = [personM toDictionary];

// 模型转字符串
NSString* string = [personM toJSONString];
  1. 注意事项
  1. 属性可选(有不需要和后台字段映射的属性)
// 方式一:指定属性可选
@property (strong, nonatomic) NSString<Optional>* name;

// 方式二:全部属性可选(推荐)
+(BOOL)propertyIsOptional:(NSString *)propertyName{
    return true;
}

// 方式三:指定属性忽略
@property (strong, nonatomic) NSString<Ignore>* customProperty;

2.当属性名和后台字段不一致时 (自定义属性:后台属性)

+(JSONKeyMapper *)keyMapper{
    return [[JSONKeyMapper alloc]initWithModelToJSONDictionary:@{
      @"themeId":@"id",
      @"Description":@"description"
    }];
}

// 如果只是将下划线转为驼峰,则使用
+(JSONKeyMapper *)keyMapper{
    // 将后台返回的_a 改为 A    (将驼峰模式改为下划线模式)
    return [JSONKeyMapper mapperForSnakeCase];
}
  1. 当属性为类类型属性,不需做额外处理。
  1. 当属性是数组,元素类型为类类型
数组(类类型) 属性

// 方式一
@protocol NewsDetailItem
@end
@property(nonatomic, strong) NSArray<NewsDetailItem>  *ewsDetailItemArray;


// 方式二
// 当使用arrayOfModelsFromDictionaries转换时,会调用此方法
-(instancetype)initWithDictionary:(NSDictionary *)dict error:(NSError *__autoreleasing *)err{
    self=[super initWithDictionary:dict error:err];
    if(self){
        _currentRoundM=[[ZYDDataScheduleItemModel arrayOfModelsFromDictionaries:@[dict[@"current_round"]] error:nil]firstObject];
        //
        NSArray *dayNumArr=dict[@"tripDayList"];
        _tripDayList=[YTDayModel arrayOfModelsFromDictionaries:dayNumArr error:nil];
        
        // 
        if(dict[@"readyTime"]){  
            _readyTime=[dict[@"readyTime"] intValue];
        }else if(dict[@"redayTime"]){
            _readyTime=[dict[@"redayTime"] intValue];
        }
    }
    
    return self;
}

2. MJExtension

第一步 :cocoaPods引入

pod 'MJExtension'

第二步:自定义模型(不需要继承)

BaseModel.h
#import <Foundation/Foundation.h>
@interface BaseModel : NSObject
@property (nonatomic, copy) NSString *ID;
@end

BaseModel.m
#import "BaseModel.h"
@implementation BaseModel
@end

第三步:转换

// 字典转模型
BaseModel *model = [BaseModel objectWithKeyValues:dict];

// 字典数组转模型数组
NSArray *selecteds = [BaseModel mj_objectArrayWithKeyValuesArray:dic[@"response"][@"selected"]
// 模型转字典
NSDictionary *personDict = personModel.keyValues;

// 模型数组转字典数组
NSArray *dictArray = [PersonModel keyValuesArrayWithObjectArray:personArray];
  1. 注意事项

1、当属性为类类型属性,不需做额外处理。


2、当属性是数组,元素类型为类类型。

+ (NSDictionary *)objectClassInArray{    
    return @{         
              @"personArray" : @"PersonModel",         
              @"teamArray" : @"TeamModel",     
    };
}
/*
另外2种方式(不推荐,要引入头文件):

+ (NSDictionary *)objectClassInArray{    
    return @{         
              @"personArray" : [PersonModel class],         
              @"teamArray" : [TeamModel  class],     
    };
}
+ (Class)objectClassInArray:(NSString *)propertyName{    
    if ([propertyName isEqualToString:@"personArray"]) {        
        return [PersonModel class];    
    } else if ([propertyName isEqualToString:@"teamArray"]) {        
        return [TeamModel class];    
    }    
    return nil;
}
*/

3、当属性名和后台字段不一致时

+ (NSDictionary *)replacedKeyFromPropertyName{
    NSDictionary *dict = @{
      @"ID": @[@"id",@"houseId"] ,
      @"descriptions":@"description"
    };
    return dict;
}

3. YYModel

// 字典转模型
/**
类型不匹配时
     `NSString` or `NSNumber` -> c语言类型 number, such as BOOL, int, long, float, NSUInteger...
     `NSString` -> NSDate, parsed with format "yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd HH:mm:ss" or "yyyy-MM-dd".
     `NSString` -> NSURL.
     `NSValue` -> struct or union, such as CGRect, CGSize, ...
     `NSString` -> SEL, Class.
*/
+ (nullable instancetype)modelWithDictionary:(NSDictionary *)dictionary;
// json转模型。json: `NSDictionary`, `NSString` or `NSData
+ (nullable instancetype)modelWithJSON:(id)json;
// 模型转NSObject
- (nullable id)modelToJSONObject;
// 模型转NSData
- (nullable NSData *)modelToJSONData;
// 模型转json字符串
- (nullable NSString *)modelToJSONString;
// 模型深拷贝
- (nullable id)modelCopy;
// 判断模型是否相等
- (BOOL)modelIsEqual:(id)model;
// 当属性名和后端字段不一致时使用
+ (nullable NSDictionary<NSString *, id> *)modelCustomPropertyMapper;
// 元素为类类型的数组属性
+ (nullable NSDictionary<NSString *, id> *)modelContainerPropertyGenericClass;
// 属性黑名单,忽略
+ (nullable NSArray<NSString *> *)modelPropertyBlacklist;
// 属性白名单,仅处理
+ (nullable NSArray<NSString *> *)modelPropertyWhitelist;
// JSON 转为 Model 完成后调用,返回false该model会被忽略
- (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic;
// Model 转为 JSON 完成后调用,返回false该model会被忽略
- (BOOL)modelCustomTransformToDictionary:(NSMutableDictionary *)dic
  1. 使用

第一步 :cocoaPods引入

pod 'YYKit'

第二步:自定义模型(不需要继承)

BaseModel.h
#import <Foundation/Foundation.h>
@interface BaseModel : NSObject
@property (nonatomic, copy) NSString *ID;
@end

BaseModel.m
#import "BaseModel.h"
@implementation BaseModel
@end

第三步:转换

// 字典转模型
FQUserTagModel *tagM=[FQUserTagModel modelWithDictionary:dic];
  1. 注意事项
  1. 当属性名和后台字段不一致时
@property (nonatomic,copy) NSString *tagId; // 后端返回id

+ (nullable NSDictionary<NSString *, id> *)modelCustomPropertyMapper{
    return @{
        @"tagId":@"id",
    //   @"tagId":@[@"id",@"uid",@"ID"]
    };
}
  1. 当属性是数组,元素类型为类类型
@property (nonatomic,copy) NSArray *childrenArr;

+ (NSDictionary *)modelContainerPropertyGenericClass {
    return @{
        @"childrenArr" : @"FQUserTagModel",
    };
}
  1. 取sexDic中的sex @{@"sexDic":@{@"sex":@"boy"}}
@property (nonatomic,copy) NSString *sex; 

+ (NSDictionary *)modelContainerPropertyGenericClass {
    return @{
        @"sex":@"sexDic.sex",  
    };
}
  1. 黑白名单
// 以下两个方法不同时使用

// 忽略该列表内的所有属性
+ (NSArray *)modelPropertyBlacklist {
  return @[@"sex", @"languages"];
}
// 仅处理该列表内的属性。
+ (NSArray *)modelPropertyWhitelist {
  return @[@"eats"];
}
  1. 完成转换后的调用方法
// 当 JSON 转为 Model 完成后调用。
- (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic {
  //  ...自定义处理

  return YES;
}

// 当 Model 转为 JSON 完成后调用。
- (BOOL)modelCustomTransformToDictionary:(NSMutableDictionary *)dic {
  // ...自定义处理

    return YES;
}
  1. 深拷贝
FQUserTagModel *tagTmpM=[tagM modelCopy];
  1. NSCoding
<NSCoding>

- (void)encodeWithCoder:(NSCoder *)aCoder {
    [self modelEncodeWithCoder:aCoder];
}
- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super init];
    return [self modelInitWithCoder:aDecoder];
}
  1. modelIsEqual
- (BOOL)isEqual:(id)object {
    return [self modelIsEqual:object];
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,784评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,745评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,702评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,229评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,245评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,376评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,798评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,471评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,655评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,485评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,535评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,235评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,793评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,863评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,096评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,654评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,233评论 2 341

推荐阅读更多精彩内容