什么是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:
这是他的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数据。
#import "ViewController.h"
#import "TextModel.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString* json = @"https:
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) {
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.
#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。
@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
+ (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"
typedef void (^GetJSONBlock)(TextModel * _Nonnull mainModel);
typedef void (^ErrorBlock)(NSError * _Nonnull 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:
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。
|