欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Swift HTTP加載請(qǐng)求Loading Requests教程

 更新時(shí)間:2023年02月06日 14:51:12   作者:莊周曉夢(mèng)  
這篇文章主要為大家介紹了Swift HTTP加載請(qǐng)求Loading Requests教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

到目前為止,我們已經(jīng)看了一個(gè)簡(jiǎn)單的Request/Response的結(jié)構(gòu)體和實(shí)現(xiàn)。接下來,我們來討論一下發(fā)送請(qǐng)求和接收響應(yīng)。

如果我們回想一下第一節(jié),我們會(huì)用HTTP回調(diào)給他,我們發(fā)送了一個(gè)請(qǐng)求,并且最終得到了一個(gè)響應(yīng)(忽略Error)沒有任何“任務(wù)”或者代理亦或其他什么東西。我們發(fā)送(或加載)一個(gè)請(qǐng)求,最終都會(huì)得到一個(gè)響應(yīng)。

如果我們用一個(gè)方法來描述那個(gè)功能,那么這個(gè)方法如下所示

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

我們發(fā)送了一個(gè)請(qǐng)求,在未來的某個(gè)節(jié)點(diǎn),閉包將會(huì)被執(zhí)行,表里涵蓋的是我們要的響應(yīng)。當(dāng)然,單個(gè)方法并不是我們想要的;換句話說,我們想要表述的是一個(gè)接口。所以,我們會(huì)把他封裝進(jìn)一個(gè)protocol中:

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

當(dāng)然,我們可能會(huì)得到一個(gè)error響應(yīng)。所以,我們要用自己的“results”重命名(typealiase)來替換HTTPResponse:

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

讓我們停下來欣賞一下。 這個(gè)方法就是我們定義網(wǎng)絡(luò)框架的核心功能所需要的全部。 就是這樣:一個(gè)方法。 棒極了。

遵循HTTPLoading協(xié)議

URLSession就像“路上的橡膠”,這是在我們的請(qǐng)求通過空中(或有線)發(fā)送到我們指定的服務(wù)器之前需要清除的最后一個(gè)障礙。 因此,我們?cè)?URLSession 上實(shí)現(xiàn) HTTPLoading 是為了將 HTTPRequest 轉(zhuǎn)換為會(huì)話需要的 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()
    }
}

這應(yīng)該很容易理解。 我們正在執(zhí)行從 HTTPRequest 值中提取信息并將其應(yīng)用于 URLRequest 的步驟。 如果在任何時(shí)候出現(xiàn)問題,那么我們將報(bào)告錯(cuò)誤。 (您需要自己填寫 ... 部分以構(gòu)造適當(dāng)?shù)?HTTPError 值)

假設(shè)構(gòu)建一切順利,我們最終會(huì)得到一個(gè) URLRequest,我們可以將其轉(zhuǎn)換為 URLSessionDataTask 并執(zhí)行它。 當(dāng)它完成時(shí),我們將獲取響應(yīng)值,將它們轉(zhuǎn)換為 HTTPResult,并通過完成塊報(bào)告回來。

創(chuàng)建Result

在傳輸過程中的任何時(shí)候,我們的請(qǐng)求都可能失敗。 如果我們處于飛行模式或其他“未連接”狀態(tài),則請(qǐng)求可能永遠(yuǎn)不會(huì)發(fā)送。 如果我們正在發(fā)送請(qǐng)求(在我們得到響應(yīng)之前),網(wǎng)絡(luò)連接可能會(huì)斷開。 或者它可能會(huì)在我們發(fā)送后但在我們收到回復(fù)之前掉線。 或者它可能會(huì)在我們開始收到響應(yīng)之后但在完全接收到響應(yīng)之前下降。

這就是我們?cè)诙x請(qǐng)求和響應(yīng)類型時(shí)創(chuàng)建 HTTPError 結(jié)構(gòu)的原因,這意味著我們需要更加努力地構(gòu)建我們的結(jié)果,而不是簡(jiǎn)單地檢查“我是否得到了一些數(shù)據(jù)”。

在高層次上,初始化 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(...)
        }
    }
}

我想在這里指出,我們?cè)谌魏螘r(shí)候都不會(huì)解釋Response的狀態(tài)代碼。 獲得 500 Internal Server Error404 Not Found 響應(yīng)是成功的響應(yīng)。 在這一層,“成功”意味著“我們得到了回應(yīng)”,而不是“回應(yīng)表明某種語義錯(cuò)誤”。 解釋狀態(tài)代碼是特定于應(yīng)用程序的邏輯。 在未來的帖子中,我們將允許基于狀態(tài)代碼的可定制的、特定于應(yīng)用程序的行為(例如跟隨重定向或重試請(qǐng)求)。

我們定義的這個(gè)單一方法看似簡(jiǎn)單,但也不完整。 我們還沒有指出任何主動(dòng)取消請(qǐng)求的方法,我們需要調(diào)整我們的 HTTPLoading 協(xié)議以添加更多功能。 我們還將把它從協(xié)議轉(zhuǎn)換為類,原因我將在以后的帖子中解釋。

盡管存在這些小漏洞,該協(xié)議在其簡(jiǎn)單性方面仍然很漂亮,它展示了一個(gè)好的問題概念化如何能夠產(chǎn)生強(qiáng)大而美麗的東西。

簡(jiǎn)單是最終的復(fù)雜。

在下一篇文章中,我們將研究使用 HTTPLoading 協(xié)議來簡(jiǎn)化單元測(cè)試。

以上就是Swift HTTP加載請(qǐng)求Loading Requests教程的詳細(xì)內(nèi)容,更多關(guān)于Swift HTTP加載請(qǐng)求的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Swift 4.2使用self做為變量名淺析

    Swift 4.2使用self做為變量名淺析

    這篇文章主要給大家介紹了關(guān)于Swift 4.2使用self做為變量名的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09
  • Swift流程控制之循環(huán)語句和判斷語句詳解

    Swift流程控制之循環(huán)語句和判斷語句詳解

    這篇文章主要介紹了Swift流程控制之循環(huán)語句和判斷語句詳解,文中還使用了一個(gè)游戲例子來講解循環(huán)語句和判斷語句的使用,需要的朋友可以參考下
    2014-07-07
  • RxSwift實(shí)現(xiàn)替換delegate的方法示例

    RxSwift實(shí)現(xiàn)替換delegate的方法示例

    這篇文章主要給大家介紹了關(guān)于RxSwift實(shí)現(xiàn)替換delegate的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用RxSwift具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 深入講解Swift的內(nèi)存管理

    深入講解Swift的內(nèi)存管理

    不管在什么語言里,內(nèi)存管理的內(nèi)容都很重要,Swift使用自動(dòng)引用計(jì)數(shù)來管理應(yīng)用程序的內(nèi)存使用。這表示內(nèi)存管理已經(jīng)是Swift的一部分,在大多數(shù)情況下,你并不需要考慮內(nèi)存的管理。本文主要介紹了Swift中內(nèi)存管理的相關(guān)資料,需要的朋友可以參考。
    2017-03-03
  • Swift UIButton使用教程

    Swift UIButton使用教程

    這篇文章主要介紹了Swift UIButton的使用方法,幫助大家更好的理解和學(xué)習(xí)swift編程,感興趣的朋友可以了解下
    2020-09-09
  • Swift?指針底層探索分析

    Swift?指針底層探索分析

    這篇文章主要為大家介紹了Swift?指針底層探索分析,主要包括指針的基本使用,以及指針的內(nèi)存綁定進(jìn)行詳細(xì)分析,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • Swift實(shí)現(xiàn)表格視圖單元格單選(1)

    Swift實(shí)現(xiàn)表格視圖單元格單選(1)

    這篇文章主要為大家詳細(xì)介紹了Swift實(shí)現(xiàn)表格視圖單元格單選,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Swift中的類class與結(jié)構(gòu)體struct體學(xué)習(xí)筆記

    Swift中的類class與結(jié)構(gòu)體struct體學(xué)習(xí)筆記

    和C++一樣,Swfit中同時(shí)擁有類與結(jié)構(gòu)體,能夠充分滿足開發(fā)者面向?qū)ο蠛兔嫦蜻^程編程的需求,這里我們就來看一下Swift中的類class與結(jié)構(gòu)體struct體學(xué)習(xí)筆記
    2016-07-07
  • Swift 中閉包的簡(jiǎn)單使用

    Swift 中閉包的簡(jiǎn)單使用

    這篇文章主要介紹了Swift 中閉包的簡(jiǎn)單使用的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • Swift免費(fèi)短信驗(yàn)證碼實(shí)現(xiàn)及動(dòng)態(tài)倒計(jì)時(shí)功能

    Swift免費(fèi)短信驗(yàn)證碼實(shí)現(xiàn)及動(dòng)態(tài)倒計(jì)時(shí)功能

    這篇文章主要介紹了Swift免費(fèi)短信驗(yàn)證碼實(shí)現(xiàn)及動(dòng)態(tài)倒計(jì)時(shí)功能的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-02-02

最新評(píng)論