基于AF的HTTP

2023-11-01

搬搬砖头而已!

iOS 基于AF的HTTP请求类

OKHTTPRequestManager.h

//
//  OKHTTPRequestManager.h
//  LL
//
//  Created by Morris_ on 2020/9/22.
//  Copyright © 2020 LL Technologies. All rights reserved.
//

#import <Foundation/Foundation.h>

#ifndef okDispatch_queue_async_safe
#define okDispatch_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 okDispatch_main_async_safe
#define okDispatch_main_async_safe(block) okDispatch_queue_async_safe(dispatch_get_main_queue(), block)
#endif

NS_ASSUME_NONNULL_BEGIN

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

@interface OKHTTPRequestManager : 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;
// POST.
- (void)POSTWithRequestTag:(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, nullable) NSHashTable *dataTaskSet;

// Get task with requestTag
- (nullable NSURLSessionDataTask *)taskWithRequestTag:(NSInteger)requestTag;

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

// Set User-Agent
- (void)setUserAgent:(NSString *)userAgent;

@end

NS_ASSUME_NONNULL_END

OKHTTPRequestManager.m

//
//  OKHTTPRequestManager.m
//  LL
//
//  Created by Morris_ on 2020/9/22.
//  Copyright © 2020 LL Technologies. All rights reserved.
//

#import "OKHTTPRequestManager.h"
#import "AFHTTPSessionManager.h"

@interface OKHTTPRequestManager ()

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

@end

@implementation OKHTTPRequestManager

- (AFHTTPSessionManager *)httpSessionManager {
    if (_httpSessionManager == nil) {
        // httpSessionManager
        _httpSessionManager = [[AFHTTPSessionManager alloc] init];
        // request out time set
        _httpSessionManager.requestSerializer.timeoutInterval = 30.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];
        // HTTP redirection
        [_httpSessionManager setTaskWillPerformHTTPRedirectionBlock:^NSURLRequest * _Nonnull(NSURLSession * _Nonnull session, NSURLSessionTask * _Nonnull task, NSURLResponse * _Nonnull response, NSURLRequest * _Nonnull request) {
            return request ? request : nil;
        }];
    }
    return _httpSessionManager;
}

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

+ (instancetype)manager {
    static OKHTTPRequestManager *_manager;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _manager = [[OKHTTPRequestManager alloc] init];
        [_manager httpSessionManager];
    });
    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 = [self.httpSessionManager GET:URLString parameters:parameters headers:nil progress:^(NSProgress * _Nonnull uploadProgress){
        if (progressCallback) {
            progressCallback(uploadProgress);
        }
    } 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;
            }
    
            okDispatch_main_async_safe(^{
                [weakSelf removeTask:task];
            });
    
            if (successCallback) {
                successCallback(task,response);
            }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            okDispatch_main_async_safe(^{
                [weakSelf removeTask:task];
            });
            if (failureCallback) {
                failureCallback(task,error);
            }
    }];
    [task resume];

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

- (void)POSTWithRequestTag:(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 = [self.httpSessionManager POST:URLString parameters:parameters headers:nil progress:^(NSProgress * _Nonnull uploadProgress) {
        if (progressCallback) {
            progressCallback(uploadProgress);
        }
    } 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;
        }
        okDispatch_main_async_safe(^{
            [weakSelf removeTask:task];
        });
        if (successCallback) {
            successCallback(task,response);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        okDispatch_main_async_safe(^{
            [weakSelf removeTask:task];
        });

        if (failureCallback) {
            failureCallback(task,error);
        }
    }];
    [task resume];

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

#pragma mark - task manager

- (nullable NSURLSessionDataTask *)taskWithRequestTag:(NSInteger)requestTag
{
    NSString *taskDescription = [self getTaskDescription:requestTag];
    if (taskDescription && taskDescription.length) {
        for (NSURLSessionDataTask *task in self.taskSet) {
            if ([task.taskDescription isEqualToString:taskDescription]) {
                return task;
            }
        }
    }
    return nil;
}

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

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

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

- (void)setUserAgent:(NSString *)userAgent
{
    NSString *value = [NSString stringWithFormat:@"%@ %@ %@", userAgent, [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model]];
    [self.httpSessionManager.requestSerializer setValue:value forHTTPHeaderField:@"User-Agent"];
}


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

基于AF的HTTP 的相关文章

  • 用 C++ 解析 HTTP 标头

    我正在使用curl 与服务器通信 当我发出数据请求时 我收到 HTTP 标头 后跟由边界分隔的 jpeg 数据 如下所示 我需要解析出 边界字符串 内容长度 我已将传入数据复制到 char 数组 如下所示 static size t OnR
  • XCode 7 中的 AWSS3TransferManagerUploadRequest

    我今天升级到 Xcode 7 Swift 2 0 我的项目正在使用 CocoaPods 我正在 POD 文件中导入所有与 AWS 相关的文件 我已经设置了桥接标头 并导入了 Amazon 告诉我的所有文件 在升级到 Swift 2 0 之前
  • 从 PCAP 嗅探重建数据

    我试图通过 libpcap 嗅探 HTTP 数据 并在处理 TCP 有效负载后获取所有 http 内容 标头 有效负载 根据我的讨论编写 http 嗅探器 或任何其他应用程序级嗅探器 https stackoverflow com ques
  • 为 Swift 对象/属性设置观察者

    我一直在寻找一种在连接到 Mac 的显示器数量发生变化时触发方法的方法 我知道我可以获得 NSScreen screens count 的值 但我需要找到一种方法来在该值发生变化时创建通知或其他内容 或者指示所连接的显示器数量发生变化的其他
  • 将自定义图像设置为 UIBarButtonItem 但它不显示任何图像

    我想将自定义图像设置为 UIBarButtonItem 但它只显示周围的矩形框并且不显示实际图像 func setupBrowserToolbar let browser UIToolbar frame CGRect x 0 y 20 wi
  • 以编程方式从底部裁剪图像

    我正在开发自定义相机应用程序 一切进展顺利 但我在从底部裁剪图像时遇到了问题 即 裁剪后的图像与原始图像具有完全相同的宽度 但高度将为原始图像的 1 3 并且必须从底部开始 斯威夫特3解决方案 func cropBottomImage im
  • 从手机访问本地主机[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我正在使用
  • Xcode 10 Beta 5 — clang:错误:链接器命令失败,退出代码为 1

    有人可以帮我吗 我的项目一切正常 但更新到 Xcode10 Beta5 后 尝试在 iPhone 上运行该应用程序时出现此错误 然而模拟器可以工作 请帮助我 我已经对这个问题进行了网络搜索并发现this https stackoverflo
  • Angular 2 - Http - 正确忽略空结果

    我有很多处理请求并简单返回 200 的 REST 端点 我注意到将结果映射为错误json 如果我尝试不进行任何类型的映射 我会看到浏览器警告它无法解析 XML 由于不返回任何内容是很常见的 我很好奇我应该如何处理响应 这是一个基本的代码示例
  • iOS 电池监控 Swift

    我已将监控设置为启用 但模拟器和设备中的电池电量仍然为 1 UIDevice currentDevice batteryMonitoringEnabled true var level UIDevice currentDevice batt
  • Swift:如何减少 didupdatelocations 调用

    我想出了一些代码来打印我所在位置的地址和邮政编码 这是在 didupdatelocation 函数中完成的 我遇到的唯一问题是 didupdatelocation 函数每秒都会更新该地址 因为这电池效率非常低 所以我一直在寻找使用间隔的方法
  • SwiftUI:状态栏颜色

    有没有办法将 SwiftUI 视图的状态栏更改为白色 我可能错过了一些简单的东西 但我似乎找不到在 SwiftUI 中将状态栏更改为白色的方法 到目前为止我只看到 statusBar hidden Bool 状态栏文本 色调 前景色可以通过
  • 在 SwiftUI 中使用分段式选取器在两个页面之间滑动

    我有一个Picker with pickerStyle SegmentedPickerStyle 使其成为分段控件 我想让页面在之间平滑滑动 而不是使用条件语句替换视图 这是我迄今为止所做的 gif 这是到目前为止的代码 由if 而不是在不
  • 所需框架与静态库

    构建现代框架 https developer apple com videos play wwdc2014 416 says 每个应用程序都有自己的自定义框架副本 https stackoverflow com a 15262463 242
  • 使用 WCF 支持“application/x-www-form-urlencoded”发布数据的最佳方式?

    我正在基于 W3C 规范构建 WCF 服务 该规范定义了接受 application x www form urlencoded 发布数据的 RESTful Web 服务端点 默认情况下 WCF 不支持这种类型的消息编码 我发现了许多创建如
  • init 中的 Swift 通用约束

    我有通用的 我希望能够用特定的约束来初始化它 约束仅用于初始化 班里的其他人并不关心 这是一个简化的示例 struct Generic
  • IPV6 快速可达性

    我是 swift 和 xcode 的新手 并且我的应用程序因 IPV6 而被拒绝 性能 2 1 当我们执行以下操作时 您的应用程序会在运行 iOS 9 3 5 并连接到 IPv6 网络的 iPad 和 iPhone 上崩溃 具体来说 当我们
  • CGPoint 标量乘法 Swift

    我正在 SpriteKit 中构建一个平台游戏 并将为我的实体实现更新功能 以便它们根据重力和速度移动 但是 我需要使添加的速度量与增量时间成比例 以防止帧速率影响我的实体的移动方式 因此我将导入 GLKit 以便我可以使用标量函数 但是
  • Swift 3 中是否提供内置内部函数?

    我可以在 Xcode 自动完成弹出窗口中看到各种内置函数 如 builtin popount builtin clz 等 我不确定这些是从哪里获取的 单击命令不会导致快速定义或任何文档 Swift 3 中是否有 builtin 或等效的内部
  • 是否可以将请求标头添加到 CORS 预检请求中?

    我有一个从外部服务器 不是服务器 访问 API 的网站 为网站提供服务 通过简单的XmlHttpRequest 见下文 那个API 需要将用于访问服务的 API 密钥添加为请求标头 然而 正如这些CORS https developer m

随机推荐

  • vue 按需引入 element-ui 组件

    新建 plugins element ui js 文件 在里面写入需要引入的组件 import Vue from vue import Button Dialog Form FormItem Loading Message Paginati
  • java char判断相等_java面试题-基础

    1 一个 java 源文件中是否可以包括多个类 不是内部类 有什么限制 可以有多个类 但只能有一个public的类 并且public的类名必须与文件名相一致 2 Java有没有goto java中的保留字 现在没有在java中使用 3 说说
  • 搭建: canal部署与实例运行

    1 准备 github https github com alibaba canal 里面有包括canal的文档 server端 client端的 例子 源码包等等 2 canal概述 canal是应阿里巴巴存在杭州和美国的双机房部署 存在
  • Adobe XD 连不上网用不了插件的解决办法

    安装了xd想用插件发现 提示 请先链接网络 只要注册一个所在地在美国的账号即可联网成功 操作如下 1 依次点击菜单栏帮助 登录 2 点击创建账户 3 输入邮箱和密码 邮箱可以随便输入 但要记住密码方便后期登录 但如果后期忘记了密码可以通过邮
  • Linux(CentOS)安装Zookeeper

    前置环境是装好Java环境 然后去zookeeper官网下载 http mirror bit edu cn apache zookeeper 下载好后把压缩包上传到服务器 去到服务器地下解压 tar zxvf apache zookeepe
  • 96. 不同的二叉搜索树

    96 不同的二叉搜索树 给你一个整数 n 求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种 返回满足题意的二叉搜索树的种数 二叉搜索树的定义 二叉搜索树是一个有序树 若它的左子树不空 则左子树上所有结点的值均小
  • Java架构直通车——Kafka介绍和高性能原因

    文章目录 Kafka介绍 Kafka高性能原因 Kafka介绍 Kafka以前说过很多次了 包括了Kafka单独的介绍 Kafka与Fabric 这里知识简单说说 Kafka的主要特点就是基于Pull模式来处理消息消费 追求高吞吐量 一开始
  • JavaScript应该被放在什么位置

    1 JavaScript被放在中 首先我们要知道的是HTML 文档加载顺序是从上至下被加载的 而且加载途中遇到JavaScript的代码时就会把JavaScript的代码放入缓冲中 当浏览器找到与它相关的标签时才进行匹配 当我们把JavaS
  • IRQL的理解和认识

    介绍 中断请求 IRQ Interrupt Request 一般有两种 一种是外部中断 也就是硬件产生的中断 例如 键盘中断 打印机中断 定时器中断 另一种是由软件指令 int n 产生的中断 例如 INT 3 断点中断 INT 1 单步中
  • (附源码)springboot+mysql+基于Java web的电动车销售平台 毕业设计201524

    电动车销售平台的设计与实现 摘 要 信息化社会内需要与之针对性的信息获取途径 但是途径的扩展基本上为人们所努力的方向 由于站在的角度存在偏差 人们经常能够获得不同类型信息 这也是技术最为难以攻克的课题 针对电动车销售平台等问题 对电动车销售
  • ES系列--分析器

    一 前言 ES进行文档分析就会涉及到分析器 无论是内置的分析器 还是自定义的分析器 都是由一个分词器 tokenizers 0或多个词项过滤器 token filters 0或多个字符过滤器 character filters 组成 二 内
  • 数据结构基本概念、线性表、顺序表

    一 头文件 head h ifndef HEAD H define HEAD H include
  • 蓝桥杯每日一题(30)单词分析(python)

    Topic 试题 G 单词分析 时间限制 1 0s 内存限制 512 0MB 本题总分 20 分 问题描述 小蓝正在学习一门神奇的语言 这门语言中的单词都是由小写英文字母组成 有些单词很长 远远超过正常英文单词的长度 小蓝学了很长时间也记不
  • 简述前端MVVM框架

    一张图说明 1 一句话总结 vm层 视图模型层 通过接口从后台m层 model层 请求数据 vm层继而和v view层 实现数据的双向绑定 2 mvc和mvvm的关系 c 控制层 被换成了vm viewmodel 层 MVVM是Model
  • TypeScript 总结

    文章目录 TypeScript 总结 概述 运行ts文件 方式一 方式二 基础 声明变量 类型 数组 元组 联合类型 取值限制 枚举类型 any unknown void undefined 类型适配 面向对象 函数 普通函数 箭头函数 可
  • 2.2-base-num-str

    for i in range 9 0 1 for j in range 1 i 1 print f j i str i j ljust 2 end print 1 9 9 2 9 18 3 9 27 4 9 36 5 9 45 6 9 54
  • 网络设备自动化运维工具——ansible入门笔记

    Ansible概述 Ansible是一款自动化运维工具 基于Python开发 集合了众多运维工具 Puppet CFengine Chef SaltStack 的优点 实现了批量系统配置 批量程序部署 批量运行命令等功能 Ansible是基
  • 管理者一定要戒掉这五个毛病,否则迟早被淘汰出局

    在职场中 很多人都想升职加薪 但是不是每个人都有能力当一个好的领导 有的人不断的为之努力 有的好不容易当上了领导 可以结果时间不长反而被辞退 并不是他们不够努力 而是当员工和领导有很大的差别 你的思维要及时调整 如果思维还停留在以前 那么只
  • rsyslog无法发送日志到server端问题定位

    问题描述 网络正常的情况下 代码端中使用openlog无法正常将日志发往syslog服务器 即使使用logger也无法正常发送 环境 ARM设备充当client端 pc虚拟机Ubuntu充当server端 验证方式 通过wireshark抓
  • 基于AF的HTTP

    搬搬砖头而已 iOS 基于AF的HTTP请求类 OKHTTPRequestManager h OKHTTPRequestManager h LL Created by Morris on 2020 9 22 Copyright 2020 L