[iOS开发]JSONModel的使用

语言: CN / TW / HK

一、什么是JSONModel?

JSONModel是json转model的第三方开源库。当我们向服务器发送一个请求之后,通过JSONModel把数据转成model中的属性就可以很方便的供给我们使用了。

二、JSONModel的最基本使用方法
以最简单的一个知乎版本检查API请求到的json数据为例
在这里插入图片描述

发送的版本为2.3版本 那么此时的json数据为

在这里插入图片描述

这个就是我们发送网络请求得到的json数据
我们接下来的步骤就是:

  1. 创建一个Model的类,这个类是继承自JSONModel的
  2. 将请求到的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
  1. 使用网络请求到的数据将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 on 2020/10/12.
//
@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的值,可以看见已经获取成功了
在这里插入图片描述

四、注意的几点

  1. +(BOOL)propertyIsOptional:(NSString *)propertyName 作用是不想因为服务器的某个值没有返回(nil)就使程序崩溃, 我们会加关键字Optional,如果不想每一条属性都添加,我们也可以在.m文件中重写方法 这个就是重写了方法
    比如第一个API的msg如果版本已经最新了,那么msg就没有返回值 如果不写就会造成程序的崩溃

  2. 在刚开始写demo时,所有的正确,但是网络请求就是失败
    在这里插入图片描述

查询到以下信息:
iOS9引入了新特性:App Transport Security (ATS),新特性要求App内访问的网络必须使用HTTPS协议。

但是现在公司的项目使用的是HTTP协议,使用私有加密方式保证数据安全。现在也不能马上改成HTTPS协议传输。

最终找到以下解决办法:

在Info中添加如下
在这里插入图片描述

  1. 怎么样可以获取镶嵌数组中的元素呢
    可以看到点语法是行不通的 由于是model嵌套model所以不能直接调用 在这里插入图片描述

我们可以再声明一下需要的被嵌套的model,然后给其赋值,就可以直接调用了。
在这里插入图片描述
在这里插入图片描述

  1. key设置全局键映射(应用于所有model)
    在.m文件中实现 作用是给变量换名字
    换名:
    在这里插入图片描述


  2. 自动把下划线方式的命名转为驼峰命名属性。还有类似的,如大写转为小写的方法:mapperFromUpperCaseToLowerCase

在这里插入图片描述

分享到: