iOS——JSONModel

什么是JSONModel

所以JSONModel就是Objective-c的一个开源第三方库,他可以帮我们处理网络请求到的数据,当我们向服务器发送一个请求之后,通过JSONModel把数据转成model就可以很方便我们使用了。

如何使用JSONModel

首先是需要配置环境,当配置好环境后才可以使用JSONModel。

配置环境

首先要在终端中配置CocoaPod,这边可以参考一下之前写的一篇文章,Masonry
接下来打开终端,cd到需要使用JSONModel的目录,输入touch Podfile文件,打开Podfile文件,修改文件内容为以下:

platform:ios,'9.0'
target 'JSONModel' do
pod 'JSONModel'
end

然后保存文件,在终端输入pod install这样就配置完成了

实际使用

现在有一个知乎接口如下:

https://news-at.zhihu.com/api/4/version/ios/2.3.0

这是他的JSON数据:

{
    "status":1,
    "msg":"【更新内容】\r\n\r\n★ 多图有标记 流量壕忽略\r\n★ 出门前离线 没网也能看\r\n★ 喜欢请好评 不喜快吐槽\r\n★ 萌妹工程师 邮箱在下面\r\nmua@zhihu.com\r\n(一般人我们不告诉他)",
    "latest":"2.5"
}

之前我们需要使用字典去存储接受到的数据,现在我们利用JSONModel可以创建Model模型去直接接受数据。
创建一个TextModel继承JSONModel类,属性对应JSON数据的名称。

@interface TestModel : JSONModel
@property (nonatomic, assign) int status;
@property (nonatomic, copy) NSString *msg;
@property (nonatomic, copy) NSString *latest;

这里属性的和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


接下来需要使用网络请求获得JSON数据。

//
//  ViewController.m
//  JSONModelDemo
//
//  Created by 差不多先生 on 2021/10/11.
//

#import "ViewController.h"
#import "TextModel.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    NSString* json = @"https://news-at.zhihu.com/api/4/version/ios/2.3.0";
    json = [json stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    NSURL* textUrl = [NSURL URLWithString:json];
    NSURLRequest* textRequest = [NSURLRequest requestWithURL:textUrl];
    NSURLSession* textSession = [NSURLSession sharedSession];
    NSURLSessionDataTask *testDataTask = [textSession dataTaskWithRequest:textRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
       //这个TestModel就是上面说到的类
    TextModel* country = [[TextModel alloc] initWithData:data error:nil]; 
           NSLog(@"%@",country);
           }];
       //任务启动
           [testDataTask resume];
    
}


@end

最后就完成了一个简单的JSONMOdel的使用。

用Manager去封装一个网络请求并实现JSONModel的嵌套使用

我们需要将网络请求单独出来,如何进行网络请求,这里可以用单例模式,创建一个全局的Manger类,用实例manger来执行网络请求方法,顺便用manger传递请求数据,在model里完成数据解析。

为什么要使用单例模式?

1.在iOS开发过程中,需要使用到一些全局变量以及管理方法,可以将这些变量以及方法封装在一个管理类中,这是符合MVC开发模式的,这就需要使用单例(singleton)。
2.使用单例模式的变量在整个程序中只需要创建一次,而它生命周期是在它被使用时创建一直到程序结束后进行释放的,类似于静态变量,所以我们需要考虑到它的生命周期,唯一性以及线程安全。在这里,我们需要实用GCD来实现单例模式:
(保证线程安全, 不能确定代码的执行顺序,线程是不安全的)
这里有两种方式去创建单例。

1.

//
//  Manager.m
//  JSONModelDemo
//
//  Created by 差不多先生 on 2021/10/14.
//

#import "Manager.h"
static Manager* manager = nil;
@implementation Manager
+(instancetype)shareManager {
    i f (!manager) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            manager = [Manager new];
        });
    }
    return manager;
}

@end

代码中的dispatch_once_t:可以保证某段代码在程序运行过程中只被执行 1 次,并且即使在多线程的环境下,dispatch _once也可以保证线程安全。
还有一种方法:
2.

static id obj = nil;
+(instancetype)shareManager
{
    @synchronized(self) {
        if (!obj) {
            obj = [[Manager alloc] init];
        }
    }
    return obj;
}

这里利用@synchronized加了一把锁,防止其他线程对代码块访问,但性能低,不推荐使用。

JSONModel的嵌套

下面有一个JSON数据
在这里插入图片描述

可以看到数据涉及数组以及嵌套,我们可以在一个类文件写多个Model。

//
//  TextModel.h
//  JSONModelDemo
//
//  Created by 差不多先生 on 2021/10/11.
//

@protocol StoriesModel
@end

@protocol Top_StoriesModel
@end

#import <JSONModel/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) NSString* type;
@property (nonatomic, copy) NSString* id;

@end

@interface Top_StoriesModel : JSONModel
@property (nonatomic, copy) NSString* image_hue;
@property (nonatomic, copy) NSString* hint;
@property (nonatomic, copy) NSString* url;
@property (nonatomic, copy) NSString* title;
@property (nonatomic, copy) NSString* ga_prefix;
@property (nonatomic, copy) NSString* type;
@property (nonatomic, copy) NSString* id;

@end
@interface TextModel : JSONModel

@property (nonatomic, copy) NSString *date;
@property (nonatomic, copy) NSArray<StoriesModel> *stories;
@property (nonatomic, copy) NSArray<Top_StoriesModel > *top_stories;

@end
NS_ASSUME_NONNULL_END

在.m文件中实现类

#import "TextModel.h"

@implementation Top_StoriesModel
// 重写此方法可以避免服务器的数据没有返回nil而崩溃
+ (BOOL)propertyIsOptional:(NSString *)propertyName {
    return YES;
}
@end

@implementation StoriesModel
+ (BOOL)propertyIsOptional:(NSString *)propertyName {
    return YES;
}
@end

@implementation TextModel
+ (BOOL)propertyIsOptional:(NSString *)propertyName {
    return YES;
}
@end

最后是使用Manager

首先定义两个block块去调用数据,再定义一个方法在Manager中进行网络请求。

#import <Foundation/Foundation.h>
#import "TextModel.h"
// 请求到的数据作为参数调用block
typedef void (^GetJSONBlock)(TextModel * _Nonnull mainModel);// 传递接受到的数据
typedef void (^ErrorBlock)(NSError * _Nonnull error);// 请求失败返回error

NS_ASSUME_NONNULL_BEGIN

@interface Manager : NSObject
+(instancetype)shareManager;

-(void)NetworkQuestSuccess:(GetJSONBlock) GetJSONBlock error:(ErrorBlock) errorBlock;

@end

NS_ASSUME_NONNULL_END

.m文件

#import "Manager.h"
static Manager* manager = nil;
@implementation Manager
+(instancetype)shareManager {
    if (!manager) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            manager = [Manager new];
        });
    }
    return manager;
}
- (void)NetworkQuestSuccess:(GetJSONBlock)GetJSONBlock error:(ErrorBlock)ErrorBlock {
    NSString* URLString = @"https://news-at.zhihu.com/api/4/news/latest";
    // 处理中文
    URLString = [URLString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    // 创建一个网络请求
    NSURL* textUrl = [NSURL URLWithString:URLString];
    NSURLRequest* textRequest = [NSURLRequest requestWithURL:textUrl];
    // 创建网络请求会话
    NSURLSession* textSession = [NSURLSession sharedSession];
    // 创建一个请求任务
    NSURLSessionDataTask* textDataTask = [textSession dataTaskWithRequest:textRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error == nil) {
            TextModel* ansModel = [[TextModel alloc] initWithData:data error:nil];
            GetJSONBlock(ansModel);
        } else {
            ErrorBlock(error);
        }
    }];
    // 任务启动
    [textDataTask resume];
}
@end

最后在ViewController使用即可

- (void)viewDidLoad {
    [super viewDidLoad];
    [self text];
    
}
-(void)text{
    [[Manager shareManager] NetworkQuestSuccess:^(TextModel * _Nonnull mainViewNowModel) {
        NSLog(@"%@",mainViewNowModel.stories[0]);
            NSLog(@"请求成功");
        } error:^(NSError * _Nonnull error) {
            NSLog(@"请求失败");
        }];
}

以下是结果:
在这里插入图片描述

以上就是JSONModel的简单使用。
下面是完整Demo的地址:
JSONModel

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值