模型解析之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];
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容