使用AFNetworking(二)

2023-11-18

写代码没有什么具体的规范和方式,只是哪个更加合理罢了。

老的项目HTTP请求使用的是AFNetworking找个优秀的第三方框架。由于使用不当导致各种代码耦合到一个类里,功能是满足了,但是可读性比较差,所以我对此进行了重构。

HIHTTPSessionManager

这个类是AFHTTPSessionManager的一个管理类,不涉及任何业务的代码。

.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

/// This class is a manager of the HTTP request, there will use AFNetworking send a request in this class. Never add the App business code in this class.

@interface HIHTTPSessionManager : NSObject

+ (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
                             parameters:(nullable id)parameters
                               progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
                                success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

+ (nullable NSURLSessionDataTask *)GET:(NSString *)URLString
                            parameters:(nullable id)parameters
                              progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgress
                               success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                               failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

@end

.m

#import "HIHTTPSessionManager.h"
#import "AFHTTPSessionManager.h"

@implementation HIHTTPSessionManager

static AFHTTPSessionManager *_httpSessionManager = nil;

+ (AFHTTPSessionManager *)httpSessionManager {
    if (_httpSessionManager == nil) {
        // httpSessionManager
        _httpSessionManager = [[AFHTTPSessionManager alloc] init];
        // request out time set
        _httpSessionManager.requestSerializer.timeoutInterval = 20.f;
        // response serializer set
        AFHTTPResponseSerializer *responseSerializer = [AFHTTPResponseSerializer serializer];
        responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", @"text/xml", @"text/plain", nil];
        _httpSessionManager.responseSerializer = responseSerializer;
        // none securityPolicy
        _httpSessionManager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
    }
    return _httpSessionManager;
}

+ (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
                             parameters:(nullable id)parameters
                               progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
                                success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure
{
    return [[HIHTTPSessionManager httpSessionManager] POST:URLString parameters:parameters progress:uploadProgress success:success failure:failure];
}

+ (nullable NSURLSessionDataTask *)GET:(NSString *)URLString
                            parameters:(nullable id)parameters
                              progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgress
                               success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                               failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure
{
    return [[HIHTTPSessionManager httpSessionManager]GET:URLString parameters:parameters progress:downloadProgress success:success failure:failure];
}

@end

HIHTTPRequestManager

这个类是对HIHTTPSessionManager的封装,对HTTP请求任务的封装,也不涉及业务代码。

.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

/// Ues this class to send the http request and manager the request task.

@interface HIHTTPRequestManager : NSObject

// Init
- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)manager;

// GET.
- (void)GETWithRequestTag:(NSInteger)requestTag
                URLString:(NSString *)URLString
               parameters:(nullable id)parameters
                 progress:(nullable void (^)(NSProgress *progress))progressCallback
                  success:(nullable void (^)(NSURLSessionDataTask * _Nullable task, id result))successCallback
                  failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failureCallback;

// the requesting task set.
@property (nonatomic, strong, readonly) NSMutableSet *taskSet;

// cancel a request, cancel the request when dismiss before controller.
- (void)cancelTask:(NSInteger)requestTag;

@end

NS_ASSUME_NONNULL_END

.m

#import "HIHTTPRequestManager.h"
#import "HIHTTPSessionManager.h"

@interface HIHTTPRequestManager ()

@property (nonatomic, strong, readwrite) NSMutableSet *taskSet;

@end

@implementation HIHTTPRequestManager

- (NSMutableSet *)taskSet {
    if (!_taskSet) {
        _taskSet = [[NSMutableSet alloc] init];
    }
    return _taskSet;
}

+ (instancetype)manager {
    static HIHTTPRequestManager *_manager;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _manager = [[HIHTTPRequestManager alloc] init];
    });
    return _manager;
}

- (void)GETWithRequestTag:(NSInteger)requestTag
                URLString:(NSString *)URLString
               parameters:(nullable id)parameters
                 progress:(nullable void (^)(NSProgress *progress))progressCallback
                  success:(nullable void (^)(NSURLSessionDataTask * _Nullable task, id result))successCallback
                  failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failureCallback
{
    __weak typeof(self)weakSelf = self;
    NSURLSessionDataTask *task = [WMSHTTPSessionManager GET:URLString parameters:parameters progress:progressCallback success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        NSString *jsonString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
        NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
        NSError *err;
        id response = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&err];
        if (err) {
            response = jsonString;
        }
        
        wmsDispatch_main_async_safe(^{
            [weakSelf removeTask:task];
        });
        
        if (successCallback) {
            successCallback(task,response);
        }

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

        wmsDispatch_main_async_safe(^{
            [weakSelf removeTask:task];
        });

        if (failureCallback) {
            failureCallback(task,error);
        }
    }];
    
    NSString *taskDescription = [self getTaskDescription:requestTag];
    if (taskDescription) {
        task.taskDescription = taskDescription;
        [weakSelf.taskSet addObject:task];
    }
}

#pragma mark - task manager

- (void)cancelTask:(NSInteger)requestTag
{
    NSString *taskDescription = [self getTaskDescription:requestTag];
    for (NSURLSessionDataTask *task in self.taskSet) {
        if ([task.taskDescription isEqualToString:taskDescription]) {
            if (task.state < NSURLSessionTaskStateCanceling) {
                [task cancel];
            }
            [self.taskSet removeObject:task];
        }
    }
}

- (void)removeTask:(NSURLSessionDataTask *)task
{
    if ([self.taskSet containsObject:task]) {
        [self.taskSet removeObject:task];
    }
}
- (void)addTask:(NSURLSessionDataTask *)task
{
    [self.taskSet addObject:task];
}

- (NSString *)getTaskDescription:(NSInteger)requestTag
{
    return [NSString stringWithFormat:@"WMSHTTPRequest: %ld",(long)requestTag];
}

@end

这里taskSet不要使用集合了,建议使用HashTable,使用集合会产生对象释放问题。

@interface HIHTTPRequestManager ()

@property (nonatomic, strong, readwrite, nullable) NSHashTable *taskSet;

@end

@implementation HIHTTPRequestManager

- (NSHashTable *)taskSet {
    if (!_taskSet) {
        _taskSet = [NSHashTable weakObjectsHashTable];
    }
    return _taskSet;
}

HIHTTPRequest

在这个类里面去处理项目的业务请求,通过HIHTTPRequestManager来发起HTTP请求。

这个类里面我们可以添加一些自己项目的业务代码,比如发请求时候检查网络状态,保存请求日志,检查Session是否过期等的业务代码。

注意事项

1、AFHTTPSessionManager弄成全局的

2、使用的时候注意下请求完后回调是在主线程还是异步线程,如果是在主线程的话,就不用再返回主线程了。

#ifndef wmsDispatch_queue_async_safe
#define wmsDispatch_queue_async_safe(queue, block)\
    if (dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) == dispatch_queue_get_label(queue)) {\
        block();\
    } else {\
        dispatch_async(queue, block);\
    }
#endif

#ifndef wmsDispatch_main_async_safe
#define wmsDispatch_main_async_safe(block) wmsDispatch_queue_async_safe(dispatch_get_main_queue(), block)
#endif
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用AFNetworking(二) 的相关文章

  • 在电子邮件中使用协议相对 URL 安全吗?

    关于在 HTML 中使用协议相对 URL 已有讨论 1 但是电子邮件呢 电子邮件客户端或 Gmail 等服务提供商在 HTML 电子邮件中使用时是否会删除或修改协议相对 URL 1 我可以将所有 http 链接更改为 吗 https sta
  • Angular 显示每个 HTTP 请求的微调器,只需很少的代码更改

    我正在开发一个现有的 Angular 应用程序 版本是 Angular 4 该应用程序从许多不同的组件对 REST API 进行 HTTP 调用 我想为每个 HTTP 请求显示一个自定义微调器 由于这是一个现有的应用程序 因此有很多地方调用
  • 您可以在分块的 http 响应预告片中设置 Location 标头吗?

    HTTP 1 1 响应可以分块 spec https www rfc editor org rfc rfc2616 section 3 6 1 在最后一个块的末尾 服务器可以发送一个 预告片 其中包含附加标头 问题是 你能包括一个Locat
  • 无法在服务器端 NodeJS 启用 CORS

    我无法启用CORS在服务器端 我的前端和后端服务器有不同的端口 服务器端的实现方式如下 http createServer function req res Here you can create your data response in
  • 使用矩阵参数创建 GET 请求

    我将使用的网络服务需要矩阵参数 http tester com v1 customers lastname Jackson firstname Tim bookingreference 7Y9UIY 而不是通常的 http tester c
  • Node.js 中的 HTTPS 代理服务器

    我正在开发一个node js代理服务器应用程序 我希望它支持HTTP and HTTPS SSL 协议 作为服务器 我目前正在使用node http proxy https github com nodejitsu node http pr
  • JavaScript:发送 POST,重定向到响应

    我有一个带有 onclick 的图像 当单击事件触发时 我想发送 HTTP POST 并将 window location 重定向到 POST 的响应 我怎样才能做到这一点 只需将按钮绑定到表单元素的提交方法 重定向就会自然发生
  • HTTP 查询字符串和 []

    PHP 使用 在查询参数名称中 以确保多次出现的参数都出现在 GET超全局变量 否则只出现最后一次出现的情况 还有其他软件可以做到这一点吗 但从RFC 3986 https www rfc editor org rfc rfc3986 以及
  • 反向代理受 NTLM 保护的网站

    如何将请求代理到受 NTLM 保护的网站 例如团队基金会 and 共享点 我不断得到401 身份验证错误 根据这篇 Microsoft TechNet 文章 https www microsoft com technet prodtechn
  • AWS ALB 截断 HTTP 响应

    我有一个带有目标组的 ALB 和运行 PHP API 的 ECS 集群 我正在尝试查询 API 以获得 CSV 响应 但如果请求通过 ALB 我会得到被截断的结果 当我通过 SSH 连接到运行集群的 EC2 实例并尝试手动运行curl 通过
  • 为什么使用 HTTP 动词?

    因为动词的目标是像 server domain getallrecords 或 server domain delete1record 或类似的 URL 而getallrecords delete1record都是专门为特定目的而设计的 为
  • ReverseProxy取决于golang中的request.Body

    我想构建一个 http 反向代理 它检查 HTTP 主体 然后将 HTTP 请求发送到它的上游服务器 你怎么能在 Go 中做到这一点 初始尝试 如下 失败 因为 ReverseProxy 复制传入请求 修改它并发送 但正文已被读取 func
  • Vertx HttpClient getNow 不工作

    我的 vertx HttpClient 有问题 下面的代码显示使用 vertx 和纯 java 测试 GET Vertx vertx Vertx vertx HttpClientOptions options new HttpClientO
  • Go中如何自定义http.Client或http.Transport超时重试?

    我想实现一个自定义http Transport对于标准http Client 如果客户端超时 它将自动重试 附 由于某种原因 习俗http Transport is a 一定有 我已经查过了hashcorp go retryablehttp
  • 如何使用 http 将 Android 中的文件从移动设备发送到服务器?

    在android中 如何使用http将文件 数据 从移动设备发送到服务器 很简单 您可以使用 Post 请求并将文件作为二进制 字节数组 提交 String url http yourserver File file new File En
  • iOS 上的多个 HTTP 请求与单个 TCP 连接

    我正在开发一个 iPhone 应用程序 它使用我控制的基于 Web 的 API 连接到持续打开的 TCP 端口并通过 TCP API 发出请求 或者为我想要获取的所有数据发出新的 HTTP 请求 会更快或更高效吗 我认为差异可以忽略不计 但
  • RestSharp RestClient的默认超时值是多少?

    任何人都知道默认超时值休息锐利 https github com restsharp 休息客户端 RestSharp 在底层使用 HttpWebRequest 它有一个默认超时 https msdn microsoft com en us
  • Android - API 请求

    我开发了一个应用程序 它也在 iPhone 上 问题出在 api 请求上 我为所有请求设置了超时 有时会出现 30 60 秒的中断 看起来这个应用程序执行了几个请求 然后就中断了 一直超时 大约 45 秒后一切正常 不知道是服务器问题还是安
  • $http.get() 与 JSON 数据

    我正在编写一个服务器应用程序 并希望客户端使用正文中的数据来参数化我的 GET 方法 如下所示 http v GET http localhost 3000 url text 123 foo bar GET url HTTP 1 1 Acc
  • JS 库请求的常见 HTTP 标头是什么?

    使用JavaScript 框架原型 http www prototypejs org 我注意到 Ajax 请求通过一个名为X Requested With 其他 JavaScript 库 如 jQuery dojo 和 YUI 是否会向其

随机推荐

  • 3、Java的If语句与For循环

    一 语句 条件语句 根据不同的条件 执行不同的语句 if if else if else if if else if else if else switch 循环语句 重复执行某些动作 for while do while 1 1 if语句
  • 深度学习算法面试常问问题(三)

    pooling层是如何进行反向传播的 average pooling 在前向传播中 就是把一个patch的值取平均传递给下一层的一个像素 因此 在反向传播中 就是把某个像素的值平均分成n份 分配给上一层 max pooling 在前向传播中
  • 用Odoo创建一个网站

    原贴地址 https www odoo com documentation 10 0 howtos website html 声明 这篇指导假设你有python的知识并安装了Odoo 请注意文件的目录结构 本文的目录结构与原文不同 创建一个
  • 快速打开CMD的几个方法

    1 在开始菜单里面找CMD EXE 很快的哟 2 在资源管理器的地址栏直接键入CMD按回车也能启动CMD 3 资源管理器 按住Shift点右键也能召唤CMD哦 选 在此处打开命令窗口 就行了
  • squirrel-foundation状态机的使用细节

    上一篇文章介绍了stateless4j spring statemachine以及squirrel foundation三款状态机引擎的实现原理 以及我为何选择squirrel foundation作为解决方案 本文主要介绍一下项目中如何使
  • sqlloader出现SQL*Loader-704和ORA-12154的错误

    1 错误描述 生成的sqlloder各个文件完好 权限也具备 但是就是导入oracle数据库的时候报错 错误为 SQL Loader 704 Internal error ulconnect OCIServerAttach 0 ORA 12
  • vue3+ts实现todolist功能

    先看一下实现效果 可以看到内部实现的内容有enter输入 单项删除 全选 以及删除选中项等功能 具体在实现前需要常见有ts的vue3项目 项目创建 具体项目创建 就是 vue create 项目名称 在创建后 选择的时候有vue2和vue3
  • CUDA10.0官方文档的翻译与学习之介绍

    背景 从这次开始 我将用数篇博客来分享前一阵我对CUDA10 0官方文档之编程指南的翻译与学习的笔记 由于内容非常多 我将每一章单独分享出来 可能有地方翻译得词不达意 所以建议大家参考原文 https docs nvidia com cud
  • 多线程实现事务回滚

    多线程实现事务回滚 特别说明CountDownLatch CountDownLatch的用法 CountDownLatch num 简单说明 主线程 mainThreadLatch await 和mainThreadLatch countD
  • 剑指 offer第62题-圆圈中最后剩下的数

    让小朋友们围成一个大圈 然后 随机指定一个数 m 让编号为 0 的小朋友开始报数 每次喊到 m 1 的那个小朋友要出列唱首歌 然后可以在礼品箱中任意的挑选礼物 并且不再回到圈中 从他的下一个小朋友开始 继续 0 m 1 报数 这样下去 直到
  • Proc批量处理需要注意的问题

    ProC中批量读取游标中的数据的时候 需要注意 最后一次批量读取游标中的数据的时候 数据被取到HostArray中 同时sqlca sqlcode被置为1403 NO DATA FOUND 如果在fetch后立即判断sqlca sqlcod
  • 隐藏selenium的特征

    1 chromedriver exe中的 cdc asdjflasutopfhvcZLmcfl 特征 cdc 是chromedriver exe的一个特征之一 很多网站会通过检测是否有这个特征来判断是否是selenium 解决方案 wind
  • centos7安装mate

    http www 45drives com wiki index php Installing MATE on CentOS 7 Note This guide assumes you have a CentOS 7 minimal ins
  • Python基础知识之5

    Python基础知识之5 文件操作 1 文件的打开与关闭 文件打开 在python 使用open函数 可以打开一个已经存在的文件 或者创建一个新文件 基本格式 open 文件名 访问模式 实例如下 f open test txt w 文件关
  • 关于soot静态分析的学习(一)

    本文中关于soot的研究使用 仅代表本人理解程度 因本人为0基础 所以如有出错 欢迎指出 一 soot是什么 Soot Java静态分析框架 其实Soot最开始设计的时候 主要目的就是为了对Java字节码程序进行优化 这里的优化就是指执行效
  • 【Qt】Qt事件系统

    00 目录 文章目录 00 目录 01 Qt事件系统概述 02 事件如何传递 03 事件类型 04 事件处理 05 事件过滤器 06 事件发送 附录 01 Qt事件系统概述 Qt 5 12 Qt Core The Event System
  • vb和asp如何用remote访问远程数据库

    访问远程数据库的情况有以下几种 1 访问远程数据库的access数据库2 访问远程mssql数据库或oracle等其他关系数据库 但是数据库通信端口被防火墙阻挡或其他网络原因造成无法使用该端口 本文仅在windows2000 advance
  • Sort List

    Sort a linked list in O n log n time using constant space complexity 题目要求用 O n log n 的时间复杂度和常数的空间复杂度来进行链表排序 O nlogn 的排序算
  • 怎么画出好看的神经网络图,神经元怎么画简笔画

    神经网络具体是什么 神经网络由大量的神经元相互连接而成 每个神经元接受线性组合的输入后 最开始只是简单的线性加权 后来给每个神经元加上了非线性的激活函数 从而进行非线性变换后输出 每两个神经元之间的连接代表加权值 称之为权重 weight
  • 使用AFNetworking(二)

    文章目录 HIHTTPSessionManager HIHTTPRequestManager HIHTTPRequest 注意事项 写代码没有什么具体的规范和方式 只是哪个更加合理罢了 老的项目HTTP请求使用的是AFNetworking找