一、什么是JSONModel?
一个解析
JSON
数据的开源库,可以将JSON
数据直接解析成自定义的model
JSONModel
是用Objective-C
写的开源库。它包含了接受发送、解析JSON
数据,用JSON
数据驱动初始化你的类,还能够检验JSON
和嵌套模型等功能。
二、导入JSONModel库
首先,JSONModel类是和Masonry一样要从cocoapods里导入,倒入方法:
第一步:
打开终端,输入以下内容
cd ‘拖动你需要导入的文件到这里’
显示如下:
第二步:
输入:
touch podFile
此时打开创建的项目文件夹,里面会出现一个新的名为podFile的文件夹
第三步:
打开podFile这个文件夹,并在里面输入:
platform :ios, '7.0'
target 'JSONModel嵌套' do
pod 'JSONModel'
end
//其中targe后输入项目名称
输入之后保存
第四步:
继续在终端里输入:
pod install
显示如下,说明导入成功,生成新的文件之后就直接打开xcworkspace文件进行编程就可以了。
三、JSONModel的使用
1、JSONModel的简单使用
这里我用这个接口来演示:https://news-at.zhihu.com/api/4/version/ios/2.3.0
(1)首先我们先要知道我们申请到的API里的内容
(2)创建一个TestModel类继承于JSONModel
(3)根据我们网络请求到的API里的内容,在TestModel
的.h
文件中:定义和内容对应的属性
#import "JSONModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface TestModel : JSONModel
@property (nonatomic, assign) int status;
@property (nonatomic, copy) NSString* msg;
@property (nonatomic, copy) NSString* latest;
@end
对于属性的声明,需要注意的是,在这里定义的属性名称必须和网络请求到的内容名称一致,类型也必须要一致,否则不能请求到数据
(4)在TestModel
的.m
文件中:需要写一个方法,这个方法的功能是:
指示具有给定名称的属性是否为可选。要让一个模型的所有属性都是可选的,只需返回YES。该方法在默认情况下返回NO,因为默认行为是拥有所需的所有属性。
也就是说:如果定义属性时只定义了部分属性与网络请求到的部分内容对应时,即你写的属性中对应原来的是不全的,需要写这个方法,否则系统会报错。
#import "TestModel.h"
@implementation TestModel
+ (BOOL)propertyIsOptional:(NSString *)propertyName {
return YES;
}
@end
默认情况下,返回值为no。
在ViewController.h
文件中:进行网络请求(这里之前在写天气预报时使用过)
[super viewDidLoad];
// Do any additional setup after loading the view.
//1.创建请求地址
NSString* urlString = [[NSString alloc] init];
urlString = @"https://news-at.zhihu.com/api/4/version/ios/2.3.0";
//处理字符
urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
//创建URL
NSURL *url = [NSURL URLWithString:urlString];
NSLog(@"%@", urlString);
//2.创建请求类
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.创建会话
NSURLSession* session = [NSURLSession sharedSession];
//4.根据会话创建任务
NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error == nil) {
TestModel* country = [[TestModel alloc] initWithData:data error:nil];
NSLog(@"%@",country);
} else {
NSLog(@"请求失败");
}
}];
//5.启动任务
[dataTask resume];
请求到的数据如下:
2、JSONModel的嵌套
上面有关JSONModel的使用因为需要请求的内容结构很简单只有三条信息,只需要定义两个个字符串类型和一个int类型的属性进行存储即可。
我们用以下这个接口来演示:
https://news-at.zhihu.com/api/4/news/latest
但是这个API里的内容更为复杂哦,它有数组,有嵌套。
对于这种嵌套模型我们该怎么处理呢?
我们应该把每一个要嵌套都写成一个类,但并不是意味着要写成多个类文件,而是只需要在一个类文件里通过声明协议, 如下代码:
在TestModel.h文件中:
#import "JSONModel.h"
NS_ASSUME_NONNULL_BEGIN
@protocol StoriesModel//协议里不需要定义方法
@end
@protocol Top_StoriesModel
@end
需要注意,这些协议里面都没有约定任何方法,它们也不会用来实现的,其作为属性的一种标记,例如将属性添加StoriesModel
协议,则JSONModel
不会对这个属性进行解析、使用这种方式来进行本地数据的管理.
@interface TestModel : JSONModel
@property (nonatomic, copy) NSString* date;
@property (nonatomic, copy) NSArray<StoriesModel>* stories;
@property (nonatomic, copy) NSArray<Top_StoriesModel>* top_stories;
@end
@interface StoriesModel : JSONModel
@property (nonatomic, copy) NSString* title;
@property (nonatomic, copy) NSString* ga_prefix;
@property (nonatomic, copy) NSString* id;
@end
@interface Top_StoriesModel : JSONModel
@property (nonatomic, copy) NSString* title;
@property (nonatomic, copy) NSString* ga_prefix;
@property (nonatomic, copy) NSString* id;
@end
注意:在这里定义的属性名称必须和网络请求到的内容名称一致,类型也必须要一致,否则不能请求到数据
在TestModel.m文件中:
要记得写三个类对应的接口
#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
这里即使不写这个方法也不会报错,可以正常输出数据。
在ViewController.h中:和前面的网络请求进行的操作相同
[super viewDidLoad];
//1.创建请求地址
NSString* urlString = [[NSString alloc] init];
urlString = @"https://news-at.zhihu.com/api/4/news/latest";
//处理字符
urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
//创建URL
NSURL *url = [NSURL URLWithString:urlString];
NSLog(@"%@", urlString);
//2.创建请求类
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.创建会话
NSURLSession* session = [NSURLSession sharedSession];
//4.根据会话创建任务
NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error == nil) {
TestModel* value = [[TestModel alloc] initWithData:data error:nil];
NSLog(@"%@",value.date);
NSLog(@"%@",value.stories[0]);
NSLog(@"%@",value.top_stories[1]);
} else {
NSLog(@"请求失败");
}
}];
//5.启动任务
[dataTask resume];
运行结果: