【iOS】——用单例类封装网络请求

文章目录


一、JSONModel

1.JSONModel的简单介绍

JSONModel一个第三方库,这个库用来将网络请求到的JSON格式的数据转化成Foundation框架下的Model类的属性,这样我们就可以直接通过访问Model类的属性来访问网络请求到的数据。

2.JSONModel的使用

要使用JSONModel库首先需要通过CocoaPods下载第三方库到目标文件中。接着在文件中创建一个Model类并且继承于JSONModel类。根据网络请求的JSON格式数据确定创建的类和属性。

例如JSON数据格式如下:

那么就需要在Model类中声明接收数据的协议并实现继承于JSONModel的类,这里我声明了storiesModel和top_StoriesModel两个协议并实现继承于JSONModel类的storiesModel和top_StoriesModel类来实现接收网络请求的数据。

GetModel.h

objectivec 复制代码
@protocol storiesModel

@end

@protocol top_StoriesModel

@end
#import <JSONModel/JSONModel.h>
#import "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) 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 GetModel : JSONModel
@property (nonatomic, copy) NSString* date;
@property (nonatomic, copy) NSArray<storiesModel>* stories;
@property (nonatomic, copy) NSArray<top_StoriesModel>* top_stories;
@end

GetModel.m

objectivec 复制代码
#import "GetModel.h"

@implementation GetModel

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

@end

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

@implementation top_StoriesModel

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

@end

在GetModel.m中使用+ (BOOL)propertyIsOptional:(NSString *)propertyName方法来指定模型类中的属性是否为可选的。默认情况下,所有的属性都被认为是必需的,也就是说在 JSON 数据中必须存在对应的键值。但是,也可以重写该方法并返回 YES 或 NO 来指定特定属性是否可以在 JSON 数据中不出现。

二、单例类和Block传值

在iOS开发中,一般要通过一些管理类来封装特定的属性或成员变量,这时就可以用单例类来实现。原因是单例类在程序运行时只创建一次,当程序结束后才被销毁,这样会提高运行效率并且降低代码风险,但是实现单例类时又需要考虑线程安全问题,所以这里用到GCD写法来创建单例类。

在Manager.h中声明类方法

objectivec 复制代码
+(instancetype)sharedSingleton;

在Manager.m中定义一个局部全局变量并实现接口部分声明的类方法。

objectivec 复制代码
static Manager* manager = nil;
+ (instancetype)sharedSingleton {
    if (manager == nil) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            manager = [[Manager alloc] init];
        });
    }
    return manager;
}

dispatch_ once _t: 使用 dispatch_once 方法能保证某段代码在程序运行过程中只被执行 1 次,并且即使在多线程的环境下,dispatch _once也可以保证线程安全。

在单例类中要封装网络请求并实现传值,因此需要用到Block传值

在Manager.h中定义两个Block块来接收请求到的数据并声明一个方法来封装网络请求

objectivec 复制代码
typedef void (^GetModelBlock)(GetModel * _Nullable mainModel);
typedef void (^ErrorBlock)(NSError * _Nullable error);
- (void)NetWorkGetWithData:(GetModelBlock)mainModelBlock andError:(ErrorBlock)errorBlock;

在Manager.m中实现该方法

objectivec 复制代码
- (void)NetWorkGetWithData:(GetModelBlock)mainModelBolck andError:(ErrorBlock)errorBlock {
	//创建一个网络请求
    NSString *json = @"https://news-at.zhihu.com/api/4/news/latest";
    json = [json stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    NSURL *netWorkDataURL = [NSURL URLWithString:json];
    NSURLRequest *netWorkDataRequest = [NSURLRequest requestWithURL:netWorkDataURL];
    //创建请求会话
    NSURLSession *netWorkDataSession = [NSURLSession sharedSession];
    //根据会话创建任务
    NSURLSessionDataTask *netWorkDataTask = [netWorkDataSession dataTaskWithRequest:netWorkDataRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error == nil) {
            GetModel *allGetData = [[GetModel alloc] initWithData:data error:nil];
            //使用Block传值
            mainModelBolck(allGetData);
        } else {
            errorBlock(error);
        }
    }];
    //启动任务
    [netWorkDataTask resume];
}

在主函数中

objectivec 复制代码
 [[Manager sharedSingleton] NetWorkGetWithData:^(GetModel * _Nullable mainModel) {
        NSLog(@"%@", mainModel.stories[1]);
        NSLog(@"获取成功");
    } andError:^(NSError * _Nullable error) {
        NSLog(@"请求失败");
    }];

运行结果如下:


相关推荐
2501_915918412 小时前
怎么把 Python 写的 Flet 应用打包成 iOS App 并上架 App Store?
android·ios·小程序·https·uni-app·iphone·webview
李游Leo4 小时前
HarmonyOS 7 实战开发 04:适配手机、折叠屏与大屏布局
ios·harmonyos
终端安全笔记4 小时前
iOS 27 强制 TLS 1.2:租赁设备的注册链路会在哪一环断
android·网络·安全·ios·智能手机
黑科技iOS上架5 小时前
iOS深度混淆flutter应用的最佳实践
flutter·ios·混淆·审核·深度混淆
思盛iOS签名上架6 小时前
IOS企业签名作用(核心作用一)
ios·testfight
黑科技iOS上架1 天前
unity3D 应用AppStore4.3被拒怎么自查
ios·审核·unity3d混淆
用户38034165882971 天前
FFmpeg 在 iOS 上的裁剪、集成与包体控制
ios·音视频开发
黑科技iOS上架1 天前
Cocos应用App Store4.3被拒怎么自查
macos·ios·objective-c·cocoa·审核·ios混淆·cocos混淆
00后程序员张1 天前
怎么用 Egret(白鹭引擎)打包 iOS 应用并上架 App Store?
android·ios·小程序·https·uni-app·iphone·webview
风雨_1 天前
show-me + grill-me 结合使用总结
ios