天天看点

iOS -Manager封装一个网络请求和JSONModel的使用

一.Manager类的使用

1. 创建一个Manager类

@implementation Manager

static Manager *manager = nil;

+ (instancetype) sharedManger {
    if(!manager) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            manager = [Manager new];
        });
    }
    return manager;
}
           

Manager类的创建使用单例模式

  • 在iOS开发过程中需要使用到一些全局变量以及管理方法,可以将这些变量以及方法封装在一个管理类中,这符合MVC开发模式,这就要用到单例模式。
  • 将需要用到的全局变量和解析方法存到一个类中。一个类中只有一个实例,减少了频繁的创建与销毁。节省资源。
  • 单例模式的变量在整个程序中只需要创建一次,考虑到它的生命周期,唯一性以及线程安全,我们这样来创建
  • static修饰全局变量,作用域仅限于当前文件,外部类是不可以访问到该全局变量的。 默认情况下,全局变量在整个程序中是可以被访问的
  • dispatch_once_t的使用保证了线程安全

2. Manager的使用

用manage封装一个请求类, 把网络请求写在manage里, 然后在model里完成数据解析

难点是 网络请求和block传值

在manager.h中定义一个块变量类型

//返回值类型(^块变量名)(形参类型)。 定义一个块变量类型
typedef void (^Block)(TestModel * _Nonnull testModel);
typedef void(^ErrorBlock)(NSError * _Nonnull error);

           

在manager.m中写网络请求的方法,并完成了网络请求

- (void) NetworkRequestSuccess:(Block) succeedBlock error:(ErrorBlock) errorBlock{
    //网络请求
    NSString *firstURLStr = [NSString stringWithFormat:@"https://news-at.zhihu.com/api/4/news/latest"];
    NSURL *firstURL = [NSURL URLWithString:firstURLStr];
    NSURLRequest *firstRequest = [NSURLRequest requestWithURL:firstURL];
    NSURLSession *firstSession = [NSURLSession sharedSession];
    NSURLSessionDataTask *firstdataTask = [firstSession dataTaskWithRequest:firstRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if(error == nil) {
            NSDictionary *resultDic = [NSJSONSerialization JSONObjectWithData:data  options:NSJSONReadingMutableContainers error:nil];
            TestModel *firstModel = [[TestModel alloc] initWithDictionary:resultDic error:&error];
            succeedBlock(firstModel);
        }else {
            errorBlock(error);
        }
    }];
    [firstdataTask resume];
}

           

把请求到的数据作为参数调用block。

在ViewController.m中

[[Manager sharedManger] NetworkRequestSuccess:^(TestModel * _Nonnull testModel) {
//这一段是在JSON数据解析出来后获取的代码
        self.myModel = [[TestModel alloc] init];
        self.myModel = testModel;
        NSLog(@"%@", _myModel.stories[0]);
        StoriesJSONModel *storiesModel = [[StoriesJSONModel alloc] init];
        storiesModel = self->_myModel.stories[0];

    } error:^(NSError * _Nonnull error) {
        NSLog(@"错误!");
    }];
           

2.JSONModel的使用

对于JSIONModel最开始时完全不懂,它是用来干什么的呢

JSONModel是json转model的第三方开源库。当我们向服务器发送一个请求之后,通过JSONModel把数据转成model中的属性就可以很方便的供给我们使用了。(简单的说就是把从网站接口上得到的一堆数据解析成自己看得懂的有效的内容并输出)

  • 使用JSON的第一步是配置一下第三方库,有关第三方库的配置可以看这篇和这篇。
  • 第二步是建立一个Model类,并且要继承与JSONModel

    请看我网络接口请求到的数据

    iOS -Manager封装一个网络请求和JSONModel的使用

    展开很长,但是其实有用的只有这么一点

    通过分析请求到的数据,来在.h文件中声明为属性

#import "JSONModel.h"

@protocol Top_storiesJSONModel

@end

@protocol StoriesJSONModel

@end

NS_ASSUME_NONNULL_BEGIN

@interface StoriesJSONModel : JSONModel
@property (nonatomic, copy) NSString *image_hue;
@property (nonatomic, copy) NSString *hint;
@property (nonatomic, copy) NSString *url;
@property (nonatomic, copy) NSString *image;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *ga_prefix;
@end

@interface Top_storiesJSONModel : JSONModel

@property (nonatomic, copy) NSString *image_hue;
@property (nonatomic, copy) NSString *hint;
@property (nonatomic, copy) NSString *url;
@property (nonatomic, copy) NSString *image;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *ga_prefix;

@end

@interface TestModel : JSONModel

@property (nonatomic, copy) NSString *date;
@property (nonatomic, copy) NSArray<Top_storiesJSONModel>*top_stories;
@property (nonatomic, copy) NSArray<StoriesJSONModel>*stories;
@end

NS_ASSUME_NONNULL_END
           

看图看代码找规律,最后要有那个JSONModel对整个写一个(包括date,top_stories,stories)。还有@protocol是自己手动添加的。

  • 第三步,在.m文件中

    每个类中添加+(BOOL)propertyIsOptional:(NSString *)propertyName

#import "TestModel.h"

@implementation StoriesJSONModel

+(BOOL)propertyIsOptional:(NSString *)propertyName{
    return  YES;
}

@end

@implementation Top_storiesJSONModel

+(BOOL)propertyIsOptional:(NSString *)propertyName{
    return  YES;
}

@end


@implementation TestModel

+(BOOL)propertyIsOptional:(NSString *)propertyName{
    return  YES;
}


@end
           

+(BOOL)propertyIsOptional:(NSString *)propertyName 作用是不想因为服务器的某个值没有返回(nil)就使程序崩溃, 我们会加关键字Optional