對于一個程序員來說软能,如果使用了第三方框架饰潜,最好是包一層再去操作硝烂,比如使用AFN時箕别,封裝一個網(wǎng)絡工具類(例如:NetworkTool),然后在項目中直接使用這個類進行網(wǎng)絡請求,這樣做的好處的如果以后作者不更新了串稀, 你要換一個網(wǎng)絡框架的話直接在該類中修改即可除抛,就不用跑到每個發(fā)網(wǎng)絡請求的地方進行修改。實際項目中對于Model的解析我一般會在Base中新建一個BaseModel,然后項目中的所有Model都繼承于BaseModel.
目錄:
一:自己寫一個框架自動轉模型思路分析
二母截、 MJExtension框架與KVC的底層實現(xiàn)的區(qū)別
三到忽、為什么要用MJExtension?
四清寇、對MJExtension框架進行封裝
五喘漏、MJExtension能做什么?(結合實際情況進行操作)
1.字典轉模型(最常見)
2.JSON字符串轉模型(很少見)
3.模型中嵌套模型
4.模型中有個數(shù)組屬性华烟,數(shù)組字典里面嵌套數(shù)組字典
5.模型中的屬性名和字典中的key不相同
6.將一個字典數(shù)組轉成模型數(shù)組<<見下篇文章>>
7.將一個模型轉成字典<<見下篇文章>>
8.將一個模型數(shù)組轉成字典數(shù)組<<見下篇文章>>
9.統(tǒng)一轉換屬性名(比如駝峰轉下劃線)<<見下篇文章>>
六翩迈、項目中的實際操作
1.單獨取某個字段
2.字典轉模型
3.JSON字符串轉模型
4.模型中嵌套模型
5.數(shù)組字典,又包含數(shù)組字典
一盔夜、如果要自己寫一個框架自動轉模型,大致思路如下:
1> 遍歷模型中的屬性,然后拿到屬性名作為鍵值去字典中尋找值.
2> 找到值后根據(jù)模型的屬性的類型將值轉成正確的類型
3> 賦值
二负饲、 MJExtension框架與KVC的底層實現(xiàn)的區(qū)別
1> KVC是通過遍歷字典中的所有key,然后去模型中尋找對應的屬性
2> MJ框架是通過先遍歷模型中的屬性,然后去字典中尋找對應的key,所以用MJ框架的時候,模型中的屬性和字典可以不用一一對應,同樣能達到給模型賦值的效果.
三、為什么要用MJExtension喂链?
1.上手快返十,使用簡單。
2.大牛寫的框架椭微,值得認可洞坑,考慮比較謹慎。
3.現(xiàn)在已經(jīng)到了3.0版本赏表,比較穩(wěn)定检诗。
4.如果是自己通過KVC自動映射的話,切必須要保證模型中的屬性名要和字典中的key一一對應,否則使用KVC運行時會報錯的.
四瓢剿、對MJExtension框架進行封裝
.h文件
@interface BaseModel : NSObject
//id
@property(nonatomic,copy)NSString *ID;
//通過字典來創(chuàng)建一個模型
+ (instancetype)objectWithDic:(NSDictionary*)dic;
//通過JSON字符串轉模型
+ (instancetype)objectWithJSONStr:(NSString *)jsonStr;
//通過字典數(shù)組來創(chuàng)建一個模型數(shù)組
+ (NSArray*)objectsWithArray:(NSArray<NSDictionary*>*)arr;
.m文件
+ (NSDictionary *)mj_replacedKeyFromPropertyName{
return @{@"ID":@"id"};
}
+ (instancetype)objectWithDic:(NSDictionary*)dic{
//容錯處理
if (![dic isKindOfClass:[NSDictionary class]]||!dic) {
return nil;
}
NSString *className = [NSString stringWithUTF8String:object_getClassName(self)];
return [NSClassFromString(className) mj_objectWithKeyValues:dic];
}
+ (instancetype)objectWithJSONStr:(NSString *)jsonStr{
//容錯處理
if (![jsonStr isKindOfClass:[NSString class]]||!jsonStr) {
return nil;
}
NSString *className = [NSString stringWithUTF8String:object_getClassName(self)];
return [NSClassFromString(className) mj_objectWithKeyValues:jsonStr];
}
+ (NSArray*)objectsWithArray:(NSArray<NSDictionary*>*)arr{
//獲取子類名
NSString * className = [NSString stringWithUTF8String:object_getClassName(self)];
return [NSClassFromString(className) mj_objectArrayWithKeyValuesArray:arr];
}
五逢慌、MJExtension能做什么?(結合實際情況進行操作)
1.字典轉模型(最常見)
/***************** UserModel***************/
import "BaseModel.h"
typedef enum {
SexMale,
SexFemale
} Sex;
@interface UserModel : BaseModel
@property(nonatomic,copy)NSString *name;
@property (nonatomic,assign) Sex sex;
@property (nonatomic,assign) NSInteger age;
@end
/***********************************************/
NSDictionary *dic = @{@"id":@"1234",
@"name":@"flowerflower",
@"age":@20,
@"sex": @(SexFemale)
};
UserModel *model = [UserModel objectWithDic:dic];
NSLog(@"dic = %@ \n id= %@,name= %@,age:%zd,sex:%zd",dic,model.ID,model.name,model.age,model.sex);
2.JSON字符串轉模型(很少見)
NSString *jsonStr = @"{\"id\":\"1234\",\"name\":\"flowerflower\", \"age\":20}";
UserModel *model = [UserModel objectWithJSONStr:jsonStr];
NSLog(@"jsonStr = %@ \n id= %@,name= %@,age:%zd",jsonStr,model.ID,model.name,model.age);
3.模型中嵌套模型
/***************** UserModel***************/
#import "BaseModel.h"
#import "DogModel.h"
typedef enum {
SexMale,
SexFemale
} Sex;
@interface UserModel : BaseModel
@property(nonatomic,strong)DogModel *dogModel;
@property(nonatomic)NSDictionary *dog;
@property(nonatomic,copy)NSString *msg;
@property(nonatomic,copy)NSString *name;
@property (nonatomic,assign) Sex sex;
@property (nonatomic,assign) NSInteger age;
@end
/***************** DogModel***************/
#import "BaseModel.h"
@class UserModel;
@interface DogModel : BaseModel
@property(nonatomic,copy)NSString *name;
@property(nonatomic,copy)NSString *height;
@property(nonatomic)UserModel *user;
/***********************************************/
NSDictionary *dic = @{
@"msg":@"成功",
@"dog":@{
@"name":@"小花貓",
@"height":@"0.5",
@"user":@{
@"name":@"小小狗",
@"age":@15,
}
},
};
UserModel *model = [UserModel objectWithDic:dic];
DogModel *dogModel = [DogModel objectWithDic:model.dog];
NSString *msg = model.msg;
NSString *name = dogModel.name;
NSString *height = dogModel.height;
NSString *userName = dogModel.user.name;
NSInteger userAge = dogModel.user.age;
NSLog(@"dic = %@, \n msg=%@, name = %@, height = %@ userName = %@ userAge = %zd",dic,msg,name,height,userName,userAge);
4.模型中有個數(shù)組屬性间狂,數(shù)組字典里面嵌套數(shù)組字典
對于我們前端來說無非便是【解析數(shù)據(jù)->獲取數(shù)據(jù)->展示數(shù)據(jù)】攻泼。例如上面截圖,下面會在項目中的實際操作貼上代碼鉴象。無非就是多了一層嵌套忙菠,沒有嵌套是怎么做的,那么現(xiàn)在嵌套了一層也是一樣的做法纺弊,無非就是多遍歷一次即可牛欢。具體闡述見下面的示例demo.
5.模型中的屬性名和字典中的key不相同
例如id屬于系統(tǒng)的關鍵字,所有建議寫成大寫的ID淆游,直接
+ (NSDictionary *)mj_replacedKeyFromPropertyName{
return @{@"ID":@"id"};
}
這里就不做過多的演示
六傍睹、項目中的實際操作
1.單獨取某個字段
NSString *dayStr= resposeObject[@"data"][@"day"];
后臺返回示例
(lldb) po resposeObject
{
data = {
continueDay = 3;
day = "27;28";
};
msg = "\U83b7\U53d6\U8fde\U7eed\U7b7e\U5230\U5929\U6570";
result = 0;
systemTime = 1498637374374;
}
2.字典轉模型
/***************** JYWalletModel***************/
#import "BaseModel.h"
@interface JYWalletModel : BaseModel
@property(nonatomic,assign)long accountAmount;
@property(nonatomic,copy)NSString *accountNo;
@property(nonatomic,copy)NSString *accountTotal;
/********************字典轉模型***************************/
JYWalletModel *model = [JYWalletModel objectWithDic:resposeObject[@"data"]];
3.JSON字符串轉模型
例如調(diào)用支付寶時隔盛,后臺返回
/***************** JYPayInfoModel***************/
@interface JYPayInfoModel : BaseModel
@property(nonatomic,copy)NSString *payInfo;
@end
/***********************字典轉模型************************/
JYPayInfoModel *user = [JYPayInfoModel objectWithDic:resposeObject[@"data"]];
最后拿到user.payInfo丟給支付寶即可。
4.模型中有個數(shù)組屬性拾稳,數(shù)組字典里面嵌套數(shù)組字典
再這里將請到的數(shù)據(jù)寫成了plist吮炕,寫了示例demo。
- (NSArray *)groupArr{
if (!_groupArr) {
NSDictionary *contentDic = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"content" ofType:@"plist"]];
NSArray *dictArray = contentDic[@"groups"];
NSMutableArray *temp = [NSMutableArray array];
for (NSDictionary *dic in dictArray) {
GroupModel *group = [GroupModel objectWithDic:dic];
NSMutableArray *temp1 = [NSMutableArray array];
for (NSDictionary *dic1 in dic[@"students"]) {
StudentModel *model = [StudentModel objectWithDic:dic1];
[temp1 addObject:model];
}
group.students = temp1;
[temp addObject:group];
}
_groupArr = temp;
}
return _groupArr;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return self.groupArr.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
GroupModel * model = self.groupArr[section];
return model.students.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
GroupModel *model = self.groupArr[indexPath.section];
StudentModel *studentModel = model.students[indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellID"];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cellID"];
}
cell.textLabel.text = studentModel.name;
cell.detailTextLabel.text = studentModel.department;
return cell;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
UILabel *headerView = [[UILabel alloc]init];
GroupModel *model = self.groupArr[section];
headerView.text =model.group_name;
return headerView;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return 30;
}
曬個圖圖更美觀
5.數(shù)組字典访得,又包含數(shù)組字典
處理方式:
/***************** JYCategorysModel***************/
@interface JYCategorysModel : BaseModel
@property(nonatomic,copy)NSString *name; //商品名稱
@property(nonatomic,copy)NSString *icon; //商品icon
@property (nonatomic, copy) NSString *pid;
//當前是否選定
@property (nonatomic, assign) BOOL isSelected;
@property(nonatomic,copy)NSArray *childrenListArr;
@end
@implementation JYCategorysModel
+ (NSDictionary *)mj_replacedKeyFromPropertyName{
return@{@"childrenListArr":@"child"
};
}
/********************轉模型過程步驟***************************/
//控制器類
self.categorysArr = [JYCategorysModel objectsWithArray:resposeObject[@"data"]];
self.funView.dataArr = self.categorysArr;
- (JYFunView *)funView{
if (!_funView) {
_funView = [[JYFunView alloc]initWithFrame:CGRectMake(0, 0, Screen_Width, funHight+bannerHight)];
JYWeakSelf;
_funView.isNeedBannerHeader = YES;
_funView.FunDidSelectItemAtIndexPath = ^(NSArray *leftArr){
weakSelf.leftArr = [JYChildrenListMoel objectsWithArray:leftArr];
if ([[weakSelf.leftArr firstObject] ID] == nil) {
[weakSelf.goodsListArr removeAllObjects];
[weakSelf.tableView reloadData];
}else{
[weakSelf.goodsListArr removeAllObjects];
[weakSelf.viewModel SelectedProducts:[[weakSelf.leftArr firstObject] ID]];
}
[weakSelf tableView:weakSelf.leftTableView didSelectRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
[weakSelf.leftTableView reloadData];
};
}
return _funView;
}
JYFunView類
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
for (JYCategorysModel *model in self.dataArr) {
model.selectedFlag = NO;
}
if (self.dataArr.count <= 0) return;
JYCategorysModel *catgoryModel = self.dataArr[indexPath.row];
catgoryModel.selectedFlag = YES;
JYCategorysModel *model = [self.dataArr safeObjectAtIndex:indexPath.row];
if (_FunDidSelectItemAtIndexPath) {
_FunDidSelectItemAtIndexPath(model.childrenListArr);
}
[collectionView reloadData];
}