[iOS开发]JSONModel的使用
发表时间:2020-10-18
发布人:葵宇科技
浏览次数:50
一、什么是JSONModel?
JSONModel是json转model的第三方开源库。当我们向服务器发送一个请求之后,通过JSONModel把数据转成model中的属性就可以很方便的供给我们使用了。
二、JSONModel的最基本使用方法
以最简单的一个知乎版本检查API请求到的json数据为例
发送的版本为2.3版本 那么此时的json数据为
这个就是我们发送网络请求得到的json数据
我们接下来的步骤就是:
- 创建一个Model的类,这个类是继承自JSONModel的
- 将请求到的json的数据在.h文件中声明为属性,.m文件中暂时不需要做其他事情(如果涉及到嵌套会有其他的)
#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
NS_ASSUME_NONNULL_END
- 使用网络请求到的数据将model初始化
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSString* json = @"http://news-at.zhihu.com/api/4/version/ios/2.3.0";
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就是上面说到的类
TestModel* country = [[TestModel alloc] initWithData:data error:nil];
NSLog(@"%@",country);
}];
//任务启动
[testDataTask resume];
}
如果传过来的JSON合法,你所定义的所有的属性都会与该JSON的值想对应,甚至JSONModel会尝试去转换数据为你期望的类型 JSONValueTransformer类可以支持我们做许多转换 如下:
NSMutableString <-> NSString
NSMutableArray <-> NSArray
NS(Mutable)Array <- JSONModelArray
NSMutableDictionary <-> NSDictionary
NSSet <-> NSArray
BOOL <-> number/string
string <-> number
string <-> url
string <-> time zone
string <-> date
number <-> date
此时我们就可以看到输出了
三、集合、嵌套型数据
还是知乎API的一个请求
这次的数据很复杂他有嵌套, 有数组,我们应该怎样处理这种嵌套模型呢?我们应该对每一个要嵌套的都写成一个类,但并不是意味着要写成多个类文件,而是只需要在一个类文件里把该有的写好就行 如下代码:
//
// TestModel.h
// JSONModel
//
// Created by young_jerry>//
@protocol StoriesModel
@end
@protocol Top_StoriesModel
@end
#import "JSONModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface StoriesModel : JSONModel
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *ga_prefix;
@property (nonatomic, copy) NSString *type;
@property (nonatomic, copy) NSString *image_hue;
@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 *type;
@property (nonatomic, copy) NSString *image_hue;
@property (nonatomic, copy) NSString *id;
@end
@interface TestModel : JSONModel
@property (nonatomic, copy) NSString *date;
@property (nonatomic, copy) NSArray<StoriesModel>* stories;
@property (nonatomic, copy) NSArray<Top_StoriesModel>* top_stories;
//
//@property (nonatomic, assign) int status;
//@property (nonatomic, copy) NSString *msg;
//@property (nonatomic, copy) NSString *latest;
@end
NS_ASSUME_NONNULL_END
在.m文件中我们则要完成类的实现,不然会报错
#import "TestModel.h"
@implementation Top_StoriesModel
+ (BOOL)propertyIsOptional:(NSString *)propertyName {
return YES;
}
@end
@implementation StoriesModel
+ (BOOL)propertyIsOptional:(NSString *)propertyName {
return YES;
}
@end
@implementation TestModel
+ (BOOL)propertyIsOptional:(NSString *)propertyName {
return YES;
}
@end
我们在网络请求赋值结束后打印一下第一组top_stories的值,可以看见已经获取成功了
四、注意的几点
-
+(BOOL)propertyIsOptional:(NSString *)propertyName 作用是不想因为服务器的某个值没有返回(nil)就使程序崩溃, 我们会加关键字Optional,如果不想每一条属性都添加,我们也可以在.m文件中重写方法 这个就是重写了方法
比如第一个API的msg如果版本已经最新了,那么msg就没有返回值 如果不写就会造成程序的崩溃 -
在刚开始写demo时,所有的正确,但是网络请求就是失败
查询到以下信息:
iOS9引入了新特性:App Transport Security (ATS),新特性要求App内访问的网络必须使用HTTPS协议。
但是现在公司的项目使用的是HTTP协议,使用私有加密方式保证数据安全。现在也不能马上改成HTTPS协议传输。
最终找到以下解决办法:
在Info中添加如下
- 怎么样可以获取镶嵌数组中的元素呢
可以看到点语法是行不通的 由于是model嵌套model所以不能直接调用
我们可以再声明一下需要的被嵌套的model,然后给其赋值,就可以直接调用了。
-
key设置全局键映射(应用于所有model)
在.m文件中实现 作用是给变量换名字
换名:
-
自动把下划线方式的命名转为驼峰命名属性。还有类似的,如大写转为小写的方法:mapperFromUpperCaseToLowerCase