我的编程空间,编程开发者的网络收藏夹
学习永远不晚

SwiftHTTP加载请求LoadingRequests教程

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

SwiftHTTP加载请求LoadingRequests教程

正文

到目前为止,我们已经看了一个简单的Request/Response的结构体和实现。接下来,我们来讨论一下发送请求和接收响应。

如果我们回想一下第一节,我们会用HTTP回调给他,我们发送了一个请求,并且最终得到了一个响应(忽略Error)没有任何“任务”或者代理亦或其他什么东西。我们发送(或加载)一个请求,最终都会得到一个响应。

如果我们用一个方法来描述那个功能,那么这个方法如下所示

func load(request: HTTPRequest, completion: @escaping (HTTPResponse) -> Void)

我们发送了一个请求,在未来的某个节点,闭包将会被执行,表里涵盖的是我们要的响应。当然,单个方法并不是我们想要的;换句话说,我们想要表述的是一个接口。所以,我们会把他封装进一个protocol中:

public protocol HTTPLoading {
    func load(request: HTTPRequest, completion: @escaping (HTTPResponse) -> Void)
}

当然,我们可能会得到一个error响应。所以,我们要用自己的“results”重命名(typealiase)来替换HTTPResponse:

    func load(request: HTTPRequest, completion: @escaping (HTTPResult) -> Void)

让我们停下来欣赏一下。 这个方法就是我们定义网络框架的核心功能所需要的全部。 就是这样:一个方法。 棒极了。

遵循HTTPLoading协议

URLSession就像“路上的橡胶”,这是在我们的请求通过空中(或有线)发送到我们指定的服务器之前需要清除的最后一个障碍。 因此,我们在 URLSession 上实现 HTTPLoading 是为了将 HTTPRequest 转换为会话需要的 URLRequest,这是有道理的:

extension URLSession: HTTPLoading {
    public func load(request: HTTPRequest, completion: @escaping (HTTPResult) -> Void)
        guard let url = request.url else {
            // we couldn't construct a proper URL out of the request's URLComponents
            completion(.failure(...))
            return
        }
        // construct the URLRequest
        var urlRequest = URLRequest(url: url)
        urlRequest.httpMethod = request.method.rawValue
        // copy over any custom HTTP headers
        for (header, value) in request.headers {
            urlRequest.addValue(value, forHTTPHeaderField: header)
        }
        if request.body.isEmpty == false {
            // if our body defines additional headers, add them
            for (header, value) in request.body.additionalHeaders {
                urlRequest.addValue(value, forHTTPHeaderField: header)
            }
            // attempt to retrieve the body data
            do {
                urlRequest.httpBody = try request.body.encode()
            } catch {
                // something went wrong creating the body; stop and report back
                completion(.failure(...))
                return
            }
        }
        let dataTask = session.dataTask(with: urlRequest) { (data, response, error) in
            // construct a Result<HTTPResponse, HTTPError> out of the triplet of data, url response, and url error
            let result = HTTPResult(request: request, responseData: data, response: response, error: error)
            completion(result)
        }
        // off we go!
        dataTask.resume()
    }
}

这应该很容易理解。 我们正在执行从 HTTPRequest 值中提取信息并将其应用于 URLRequest 的步骤。 如果在任何时候出现问题,那么我们将报告错误。 (您需要自己填写 ... 部分以构造适当的 HTTPError 值)

假设构建一切顺利,我们最终会得到一个 URLRequest,我们可以将其转换为 URLSessionDataTask 并执行它。 当它完成时,我们将获取响应值,将它们转换为 HTTPResult,并通过完成块报告回来。

创建Result

在传输过程中的任何时候,我们的请求都可能失败。 如果我们处于飞行模式或其他“未连接”状态,则请求可能永远不会发送。 如果我们正在发送请求(在我们得到响应之前),网络连接可能会断开。 或者它可能会在我们发送后但在我们收到回复之前掉线。 或者它可能会在我们开始收到响应之后但在完全接收到响应之前下降。

这就是我们在定义请求和响应类型时创建 HTTPError 结构的原因,这意味着我们需要更加努力地构建我们的结果,而不是简单地检查“我是否得到了一些数据”。

在高层次上,初始化 HTTPResult 的逻辑大致如下所示:

var httpResponse: HTTPResponse?
if let r = response as? HTTPURLResponse {
    httpResponse = HTTPResponse(request: request, response: r, body: responseData ?? Data())
}
if let e = error as? URLError {
    let code: HTTPError.Code
    switch e.code {
        case .badURL: code = .invalidRequest
        case .unsupportedURL: code = ...
        case .cannotFindHost: code = ...
        ...
        default: code = .unknown
    }
    self = .failure(HTTPError(code: code, request: request, response: httpResponse, underlyingError: e))
} else if let someError = error {
    // an error, but not a URL error
    self = .failure(HTTPError(code: .unknown, request: request, response: httpResponse, underlyingError: someError))
} else if let r = httpResponse {
    // not an error, and an HTTPURLResponse
    self = .success(r)
} else {
    // not an error, but also not an HTTPURLResponse
    self = .failure(HTTPError(code: .invalidResponse, request: request, response: nil, underlyingError: error))
}

用法

HTTPLoading 使用方法:

public class StarWarsAPI {
    private let loader: HTTPLoading = URLSession.shared
    public func requestPeople(completion: @escaping (...) -> Void) {
        var r = HTTPRequest()
        r.host = "swapi.dev"
        r.path = "/api/people"
        loader.load(request: r) { result in
            // TODO: interpret the result
            completion(...)
        }
    }
}

我想在这里指出,我们在任何时候都不会解释Response的状态代码。 获得 500 Internal Server Error404 Not Found 响应是成功的响应。 在这一层,“成功”意味着“我们得到了回应”,而不是“回应表明某种语义错误”。 解释状态代码是特定于应用程序的逻辑。 在未来的帖子中,我们将允许基于状态代码的可定制的、特定于应用程序的行为(例如跟随重定向或重试请求)。

我们定义的这个单一方法看似简单,但也不完整。 我们还没有指出任何主动取消请求的方法,我们需要调整我们的 HTTPLoading 协议以添加更多功能。 我们还将把它从协议转换为类,原因我将在以后的帖子中解释。

尽管存在这些小漏洞,该协议在其简单性方面仍然很漂亮,它展示了一个好的问题概念化如何能够产生强大而美丽的东西。

简单是最终的复杂。

在下一篇文章中,我们将研究使用 HTTPLoading 协议来简化单元测试。

以上就是Swift HTTP加载请求Loading Requests教程的详细内容,更多关于Swift HTTP加载请求的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

SwiftHTTP加载请求LoadingRequests教程

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

SwiftHTTP加载请求LoadingRequests教程

这篇文章主要为大家介绍了SwiftHTTP加载请求LoadingRequests教程示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-02-06

Vue如何优雅地处理API请求与数据加载?

Vue.js提供了多种优雅处理API请求和数据加载的功能,包括:Axios集成、Vuex状态管理、生命周期钩子、异步组件、Promise和async/await、错误处理、分页和无限滚动,以及缓存。通过采用这些最佳实践,开发人员可以创建响应迅速、健壮且用户友好的Vue.js应用程序,从而提升用户体验和简化开发流程。
Vue如何优雅地处理API请求与数据加载?
2024-04-02

Vue实现网页首屏加载动画及页面内请求数据加载loading效果

Loading加载动画组件看起来很简单不重要,实际上它是保证用户留存的关键一环,下面这篇文章主要给大家介绍了关于Vue实现网页首屏加载动画及页面内请求数据加载loading效果的相关资料,需要的朋友可以参考下
2023-02-10

python selenium禁止加载某些请求的实现是怎样的

这篇文章给大家介绍python selenium禁止加载某些请求的实现是怎样的,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。问题描述通过selenium请求目标网站时候, 真实数据(我这里是验证码图片)已经加载出来,
2023-06-22

mybatis教程之延迟加载详解

延迟加载1 使用延迟加载意义在进行数据查询时,为了提高数据库查询性能,尽量使用单表查询,因为单表查询比多表关联查询速度要快。如果查询单表就可以满足需求,一开始先查询单表,当需要关联信息时,再关联查询,当需要关联信息再查询这个叫延迟加载。 m
2023-05-31

Java网络编程教程之设置请求超时的方法

一、引言随着企业系统的发展,应用多采用分布式结构,严重依赖于网络的稳定性。但由于网络天生的不稳定性,系统开发过程中需要考虑网络不稳定情况下如何保证应用的鲁棒性。 设置网络超时是其中一种保证应用健壮性的手段。 设置网络超时设置后,请求在设定时
2023-05-30

Vue使用ajax(axios)请求后台数据的方法教程

在vue中经常会用到数据请求,下面这篇文章主要给大家介绍了关于Vue使用ajax(axios)请求后台数据的方法教程,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
2022-11-13

Ajax 请求队列解决方案并结合elementUi做全局加载状态

这篇文章主要介绍了Ajax 请求队列解决方案并结合elementUi做全局加载状态,使用消息队列制作请求防抖,防止重复请求印象服务器,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2022-11-13

VUE懒加载实战教程:让你快速掌握图片懒加载技术

VUE懒加载技术是一种图片加载优化技术,可以有效提高网站的加载速度和用户体验。本文将介绍VUE懒加载的原理、实现方法和使用技巧,帮助你快速掌握图片懒加载技术。
VUE懒加载实战教程:让你快速掌握图片懒加载技术
2024-02-13

详解linux添加硬盘分区挂载教程

基本步骤:分区——格式化——挂载——写入文件 1、首先用fdisk -l命令查看添加的硬盘名称,可以看到sdb为新增的硬盘[root@oracle ~]# fdisk -lDisk /dev/sdb: 21.5 GB, 2147483648
2022-06-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录