关于JSONModel
- JSONModel是json转model的第三方开源库。当我们向服务器发送一个请求之后,通过JSONModel把数据转成model就可以很方便我们使用了。
下载JSONModel 库
pod 'JSONModel'
基本使用
- 首先学会网络请求 - 网络请求
- 现在需要获取一个新闻网站的信息的解析如下
 - 主要步骤
- 创建一个TestModel类,继承于JSONModel
 - 从上图可以看出我们要解析的数据有一个字符串类的
date 属性,两个数组属性stories 和 top_Stories ,里面存放了各种数据。我们创建stories 和 top_Stories 的协议,并且创建stories 和 top_Stories 两个类分别继承与JSONModel
@protocol storiesModel
@end
@protocol top_StoriesModel
@end
#import <JSONModel/JSONModel.h>
#import "JSONModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface storiesModel : JSONModel
@property (nonatomic, copy) NSString* image_hue;
@property (nonatomic, copy) NSString* title;
@property (nonatomic, copy) NSString* url;
@property (nonatomic, copy) NSString* hint;
@property (nonatomic, copy) NSString* ga_prefix;
@property (nonatomic, copy) NSArray* images;
@end
@interface top_StoriesModel : JSONModel
@property (nonatomic, copy) NSString* image_hue;
@property (nonatomic, copy) NSString* title;
@property (nonatomic, copy) NSString* url;
@property (nonatomic, copy) NSString* hint;
@property (nonatomic, copy) NSString* ga_prefix;
@property (nonatomic, copy) NSString* image;
@property (nonatomic, copy) NSString* type;
@end
- 完了之后我们在TestModel类里声明storiesModel 和 top_StoriesModel类的属性并添加协议
@interface TestModel : JSONModel
@property (nonatomic, copy) NSString* date;
@property (nonatomic, copy) NSArray<storiesModel>* stories;
@property (nonatomic, copy) NSArray<top_StoriesModel>* top_stories;
@end
- 但是为了防止由于服务器数据返回空导致JSONModel异常(程序崩溃)我们可以在TestModel.m文件里面分别重写实现三个类的一个重要方法
+ (BOOL)propertyIsOptional:(NSString *)propertyName
#import "TestModel.h"
@implementation TestModel
+ (BOOL)propertyIsOptional:(NSString *)propertyName {
return YES;
}
@end
@implementation storiesModel
+ (BOOL)propertyIsOptional:(NSString *)propertyName {
return YES;
}
@end
@implementation top_StoriesModel
+ (BOOL)propertyIsOptional:(NSString *)propertyName {
return YES;
}
@end
测试及学习过程中的错误
#import "ViewController.h"
#import "TestModel.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *json = @"https://news-at.zhihu.com/api/4/news/latest";
json = [json stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSURL *testUrl = [NSURL URLWithString:json];
NSURLRequest *testRequest = [NSURLRequest requestWithURL:testUrl];
NSURLSession *testSession = [NSURLSession sharedSession];
NSURLSessionDataTask *testDataTask = [testSession dataTaskWithRequest:testRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
TestModel* JsonModelX = [[TestModel alloc] initWithData:data error:nil];
NSLog(@"%@", JsonModelX.date);
}];
[testDataTask resume];
}
@end
注意一定要对应基本数据类型
- 在开始的时候我请求数据成功但是打印出来的东西一直为空
 - 原因是在json数据解析下的过程中images是数组类型的数据但是我写成了字符串类型导致虽然请求到了数据但是在model类的类别设置错了导致返回了空的data
 
访问更深层的数据
- 要访问叠加model的数据内容 此时采用点语法无法访问,例如访问
 - 我们需要添加一步,声明一个jsonmodel的子属性类
 - 然后赋值

涉及到循环引用(暂未了解)
- 这里的调用系统会提示你需要使用self而不是下划线,因为是在Blcok解析函数参数里面的Block是局部的block(栈上),block内部引用self不会造成循环引用;是否会循环引用只看函数内部是否copy了这个block(比如把它付给全局的Block)
下划线自动转为驼峰命名法
- 如果解析数据里有含有下划线的类型,我们可以设置属性的时候就设置成驼峰命名,然后实现一个方法,系统自定义把下划线字段解析为驼峰命名属性
mapperFromUpperCaseToLowerCase
{
"order_id": 104,
"order_product" : @"Product#1",
"order_price" : 12.95
}
@interface OrderModel : BaseModel
@property (nonatomic, strong) NSString *orderId;
@property (nonatomic, assign) float orderPrice;
@property (nonatomic, strong) NSString *orderProduct;
@end
@implementation OrderModel
+ (JSONKeyMapper *)keyMapper {
return [JSONKeyMapper mapperFromUnderscoreCaseToCamelCase];
}
@end
总结
- 这里讲解了一个基础的使用,接下来的一个月要实现知乎日报,后续更详细的使用过程学习JSONModel数据解析
|