每日热文:Swift HTTP加载请求Loading Requests教程
发布时间:2023-05-27 12:15:08 文章来源:脚本之家
这篇文章主要为大家介绍了SwiftHTTP加载请求LoadingRequests教程示例,有需要的朋友可以借鉴参考下,希望能
目录
正文遵循HTTPLoading协议创建Result用法

正文

到目前为止,我们已经看了一个简单的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 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加载请求的资料请关注脚本之家其它相关文章!

标签:

资讯播报

乐活HOT

  • 《熊出没·伴我“熊芯”》票房破10亿 打破内地影史春节档动画片纪录
    《熊出没·伴我“熊芯”》票房破

    据各方数据,1月31日上午10时许,深圳出品的动画电影《熊出没·伴我熊芯》票房突破10亿元,在首日票房、档期票房、连续破亿天数等多方面打

  • 今年春节深圳游客出境游订单量大幅增加 曼谷等地成为最受欢迎目的地
    今年春节深圳游客出境游订单量大

    1月27日,携程发布的《2023年春节旅游总结报告》显示,今年春节,深圳游客的出境游订单量同比去年增长近5倍。相较国内热门景点的人山人海,

  • 2023年春节黄金周深圳共接待游客469.25万人次 旅游收入31.58亿元
    2023年春节黄金周深圳共接待游客

    1月27日,记者从深圳市文化广电旅游体育局获悉,2023年春节黄金周期间(1月21日至27日),深圳共接待游客469 25万人次,旅游收入31 58亿元,

  • 深圳机场连续多日客流量超过10万人次 卫星厅迎来首个大客流春运
    深圳机场连续多日客流量超过10万

    据深圳市春运办统计,1月15日和16日连续两天,深圳对外发送旅客人数都在48万左右,春运进入客流高峰期。1月15日,深圳春运对外旅客发送量达

  • 深圳交响乐团将将举办两场音乐会 以世界经典管弦乐和歌剧咏叹调为主
    深圳交响乐团将将举办两场音乐会

    新年音乐会是观众喜闻乐见的年度重要文化品牌活动,多年来已成为深圳市民跨岁迎新的例牌项目。12月30日、31日晚,深圳交响乐团将在深圳音乐

  • 深圳大力推进实施人才强市战略 深圳市人才总量已达到663万人
    深圳大力推进实施人才强市战略

    作为来深科研人员中的一员,中山大学附属第八医院的助理研究员郭雅婕对深圳在人才服务方面的举措赞不绝口:我作为基础研究人员,很希望自己

  • 2023年故宫年票正式开售 有消费者目前仍对购买年票持观望态度
    2023年故宫年票正式开售 有消费

    12月1日晚8点,2023年故宫年票正式开售。相比于去年,今年购票顺畅了许多。据了解,2022年故宫年票发售时,因短时间内购买年票人数过多,曾

  • 御寒类商品消费需求有所上升 羽绒服的整体销售额同比增长达100%
    御寒类商品消费需求有所上升 羽

    昨日,冷空气到达,广州气温逐步下降。据商超方面预测,随着气温的逐渐下降,市民对于御寒类商品消费需求有所上升,不少广州商超准备了有关

  • 深圳全市共排查窨井盖约350万个 发现存在问题的窨井盖约3.2万个
    深圳全市共排查窨井盖约350万个

    小井盖、大民生。今年以来,深圳开展全市窨井盖专项治理工作成效显著。截至11月20日,全市共排查窨井盖约350万个,发现存在问题的窨井盖约3

  • 汕汕铁路汕头站公布最新动态 首期工程预计将于2024年11月完成
    汕汕铁路汕头站公布最新动态 首

    备受关注的汕汕(汕头至汕尾)铁路汕头站及站区工程近日传出最新动态:项目已顺利完成工程招标工作,由中铁建设集团有限公司中标承建。目前,

娱乐LOVE

精彩推送