iOS--jsonModel的使用和Manager封装网络请求

JSONModel的使用和manager单例封装网络请求

  • manager单例封装网络请求
    • 为什么要用单例模式
    • 单例模式的实现
    • manager对网络请求方法的封装
    • manager进行网络请求
  • JSONModel的使用
    • pod引入jsonModel的第三方库
    • 将网络请求到的data转化为jsonModel类对象存储 ;
  • controller文件
    • .m

manager单例封装网络请求

为什么要用单例模式

1.在iOS开发过程中,需要使用到一些全局变量以及管理方法,可以将这些变量以及方法封装在一个管理类中,这是符合MVC开发模式的,这就需要使用单例(singleton)。

2.使用单例模式的变量在整个程序中只需要创建一次,而它生命周期是在它被使用时创建一直到程序结束后进行释放的,类似于静态变量,所以我们需要考虑到它的生命周期,唯一性以及线程安全。在这里,我们需要实用GCD来实现单例模式:
(保证线程安全, 不能确定代码的执行顺序,线程是不安全的)

不过GCD我还只是了解了一下概念,在这里的单例模式中的体现应该就是锁的使用 ;
下面是GCD的概念 ;

GCD (Grand Central Dispatch) 是苹果公司提供的一种多核编程的解决方案,用于简化多线程编程和并发任务的调度。它是一种基于队列的执行模型,可以有效地利用系统上可用的处理器内核,从而提高应用程序的性能和响应性。

单例模式的实现

单例模式其实有很多种实现方式,这里就只写了一种,也是demo里用到的 ;看代码 ;

static Manager* manager = nil ;
@implementation Manager

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

dispatch_once 是 GCD 提供的一个函数,用于确保代码块只执行一次。它通常用于实现单例模式或执行一次性初始化的任务。

manager对网络请求方法的封装

这里的manager对网络请求的封装实际上就是将网络请求方法的调用放在manager单例的方法中,实现通过manager单例调用方法实现网络请求,而无需了解网络请求中的详细带代码 ;

这里用到的block传值 ;

#import <Foundation/Foundation.h>
#import "TestModel.h"
typedef void(^TestModelBlock)(TestModel* _Nullable mainModel);
typedef void(^ErrorModelBlack)(NSError* _Nullable error);

NS_ASSUME_NONNULL_BEGIN

@interface Manager : NSObject
+ (instancetype)shareSingleton ;

- (void)NetWorkGetWithData : (TestModelBlock) mainModelBolack andError : (ErrorModelBlack) errorBlock ;

@end

NS_ASSUME_NONNULL_END

上面的NetWorkGetWithData方法可以实现网络·请求的全过程 ;
该方法通过两个Block参数传回网络请求到的数据和请求失败时的error ;

.m文件

- (void) NetWorkGetWithData:(TestModelBlock)mainModelBolack andError:(ErrorModelBlack)errorBlock {
    NSString* jsonstr = @"https://news-at.zhihu.com/api/4/news/latest" ;
    jsonstr = [jsonstr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]] ;
    NSURL* testurl = [NSURL URLWithString:jsonstr] ;
    NSURLRequest* resquest = [NSURLRequest requestWithURL:testurl] ;
//    AFURLSessionManager* sessionmanager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]] ;
    NSURLSession* session = [NSURLSession sharedSession] ;
    NSURLSessionTask* sessiontask = [session dataTaskWithRequest:resquest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            errorBlock(error) ;
        } else {
            TestModel* model = [[TestModel alloc] initWithData:data error:nil] ;
            mainModelBolack(model) ;
//            NSLog(@"%@",model) ;
            self.model01 = model.stories[1] ;
//            NSLog(@"%@",model.stories[0]) ;
        }
    }] ;
   
    [sessiontask resume] ;
}

manager进行网络请求

   NSString* jsonstr = @"https://news-at.zhihu.com/api/4/news/latest" ;
    jsonstr = [jsonstr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]] ;
    NSURL* testurl = [NSURL URLWithString:jsonstr] ;
    NSURLRequest* resquest = [NSURLRequest requestWithURL:testurl] ;
//    AFURLSessionManager* sessionmanager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]] ;
    NSURLSession* session = [NSURLSession sharedSession] ;
    NSURLSessionTask* sessiontask = [session dataTaskWithRequest:resquest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            NSLog(@"Error: %@",error) ;
        } else {
            TestModel* model = [[TestModel alloc] initWithData:data error:nil] ;
            NSLog(@"%@",model) ;
//            self.model01 = model.stories[1] ;
            NSLog(@"%@",model.stories[0]) ;
            
            self.Model = model.stories[0] ;
//            NSLog(@"%d",self.Model == nil) ;
            NSLog(@"%@",self.Model.title) ;
            NSDictionary* dict = [[NSDictionary alloc] init] ;
            dict = [model toDictionary];
            NSLog(@"%@", dict[@"stories"][0][@"title"]) ;
        
         }
    }] ;
   
    [sessiontask resume] ;

JSONModel的使用

“JSONModel” 可以指代以下两种不同的概念:
JSONModel 数据模型:这是一种将 JSON 数据映射到编程语言对象的模型。它描述了如何定义和组织对象,以便与 JSON 数据进行相应的转换。JSONModel 数据模型通常使用注解、属性映射或配置文件等方式,将 JSON 数据的键值对映射到对象的属性。这种模型可以简化开发人员在处理 JSON 数据时的操作,提供了方便的访问和操作方式。
JSONModel 框架:这是一个特定的软件框架或库,用于在特定编程语言中实现 JSON 数据模型的转换。这样的框架通常提供了一组工具和方法,用于将 JSON 数据解析为对象、将对象序列化为 JSON 数据,以及处理对象属性和嵌套关系等。JSONModel 框架可以根据特定编程语言的需求和约定,提供更高层次的抽象和功能,以简化 JSON 数据的处理。

iOS中就这里的使用应该只涉及到了JSONModel 数据模型 ;
我们这里的jsonModel使用的步骤:
1.pod引入jsonModel的第三方库
2.将网络请求到的data转化为jsonModel类对象存储 ;
3.将jsonModel类对象转化为字典,然后输出(非必要)

pod引入jsonModel的第三方库

引入第三方库的方法可以看我之前的博客,其他步骤基本不变,只需将podfile中的代码改为**pod ‘JSONModel’**就行了 ;

将网络请求到的data转化为jsonModel类对象存储 ;

首先,我们要创建一个jsonModel的子类,但这里我们的uRL请求到的数据分类较复杂,所以这里创建了多个子类 ;

#import "JSONModel.h"
#import <JSONModel/JSONModel.h>
NS_ASSUME_NONNULL_BEGIN
@protocol storiesModel

@end

@protocol top_StoriesModel

@end

@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) NSArray* images;

@end

@interface top_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* image;
@property (nonatomic, copy) NSString* type;
@end


@interface TestModel : 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

上面的两个协议其实没有声明任何方法,他们的作用在给定的代码中,@protocol 关键字用于定义两个协议,分别是 storiesModel 和 top_StoriesModel。这些协议可能用于指定特定的数据模型类型。更像是两个标记
在.m文件中要注意重写一个方法,+ (BOOL)propertyIsOptional:(NSString *)propertyName
,如果不重写这个方法,可能会导致程序奔溃,但不绝对 ;

注意属性的名字要与接受到字典的key一一对应,不然会无法请求数据,甚至导致程序奔溃

            TestModel* model = [[TestModel alloc] initWithData:data error:nil] ;
            NSLog(@"%@",model) ;
//            self.model01 = model.stories[1] ;
            NSLog(@"%@",model.stories[0]) ;
            
            self.Model = model.stories[0] ;
//            NSLog(@"%d",self.Model == nil) ;
            NSLog(@"%@",self.Model.title) ;
            NSDictionary* dict = [[NSDictionary alloc] init] ;
            dict = [model toDictionary];
            NSLog(@"%@", dict[@"stories"][0][@"title"]) ;

上面那段代码有个要注意的点,即直接对获取到的model访问他的属性会直接使程序奔溃,但具体原因不是特别清楚(主要是不知道为什么奔溃);

controller文件

.m

#import “ViewController.h”
#import
//#import “AFNetworking.h”
#import “TestModel.h”
#import “Manager.h”
@interface ViewController ()

@end

@implementation ViewController

  • (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    // NSString* jsonstr = @“https://news-at.zhihu.com/api/4/news/latest” ;
    // jsonstr = [jsonstr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]] ;
    // NSURL* testurl = [NSURL URLWithString:jsonstr] ;
    // NSURLRequest* resquest = [NSURLRequest requestWithURL:testurl] ;
    AFURLSessionManager* sessionmanager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]] ;
    // NSURLSession* session = [NSURLSession sharedSession] ;
    // NSURLSessionTask* sessiontask = [session dataTaskWithRequest:resquest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    // if (error) {
    // NSLog(@“Error: %@”,error) ;
    // } else {
    // TestModel* model = [[TestModel alloc] initWithData:data error:nil] ;
    // NSLog(@“%@”,model) ;
    self.model01 = model.stories[1] ;
    // NSLog(@“%@”,model.stories[0]) ;
    //
    // self.Model = model.stories[0] ;
    NSLog(@“%d”,self.Model == nil) ;
    // NSLog(@“%@”,self.Model.title) ;
    // NSDictionary* dict = [[NSDictionary alloc] init] ;
    // dict = [model toDictionary];
    // NSLog(@“%@”, dict[@“stories”][0][@“title”]) ;
    //
    // }
    // }] ;
    //
    // [sessiontask resume] ;
    //
    //

    [self getModel] ;
    [self postnet] ;
    [self getnet] ;
    [self postnet01] ;

}

  • (void)getModel {
    [[Manager shareSingleton] NetWorkGetWithData:^(TestModel * _Nullable mainModel) {
    NSDictionary* dict01 = [[NSDictionary alloc] init] ;
    dict01 = [mainModel toDictionary] ;
    NSLog(@“%@”,dict01) ;
    NSLog(@“%@”,dict01[@“stories”][1][@“title”]) ;
    } andError:^(NSError * _Nullable error) {
    NSLog(@“%@”,error) ;
    }] ;
    }

  • (void)getnet {
    AFHTTPSessionManager* manager = [AFHTTPSessionManager manager] ;
    [manager GET:@“https://news-at.zhihu.com/api/4/news/before/20221023” parameters:nil headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
    NSLog(@“get成功 %@”,responseObject[@“date”]) ;
    if ([responseObject isKindOfClass:[NSData class]]) {
    self.getdict = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableLeaves error:nil] ;
    NSLog(@“%@”,self.getdict) ;
    } else {
    NSLog(@“NO”) ;
    }

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@“Error : %@”,error) ;
    }] ;
    }

  • (void)postnet {
    AFHTTPSessionManager* manager = [AFHTTPSessionManager manager] ;
    [self.postdict setObject:@“Viper” forKey:@“userName”];
    [self.postdict setObject:@“Viper333” forKey:@“passWord”];
    [manager POST:@“https://news-at.zhihu.com/api/4/news/before/20221023” parameters:self.postdict headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@“error : %@”,error) ;
    }] ;
    }

  • (void)postnet01 {
    AFHTTPSessionManager* manager = [AFHTTPSessionManager manager] ;
    self.postdict = [[NSMutableDictionary alloc] init] ;
    [self.postdict setObject:@“Viper” forKey:@“userName”];
    [self.postdict setObject:@“Viper333” forKey:@“passWord”];
    [manager POST:@“https://news-at.zhihu.com/api/4/news/before/20221023” parameters:self.postdict headers:nil constructingBodyWithBlock:^(id _Nonnull formData) {
    UIImage* image = [UIImage imageNamed:@“xue.png”] ;
    NSData* imagedata = UIImagePNGRepresentation(image);
    [formData appendPartWithFileData:imagedata name:@“file” fileName:@“ImageUp.png” mimeType:@“image/png”] ;
    } progress:^(NSProgress * _Nonnull uploadProgress) {
    NSLog(@“%f”,1.0 * uploadProgress.completedUnitCount / uploadProgress.totalUnitCount) ;
    } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
    NSLog(@“success”) ;
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@“failure”) ;
    }] ;
    }

@end

上面还涉及到了AFNetworking的使用,下一篇博客写这个

你可能感兴趣的:(ios)