到目前为止,我们已经看了一个简单的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)
让我们停下来欣赏一下。 这个方法就是我们定义网络框架的核心功能所需要的全部。 就是这样:一个方法。 棒极了。
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 Resultout 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
,并通过完成块报告回来。
在传输过程中的任何时候,我们的请求都可能失败。 如果我们处于飞行模式或其他“未连接”状态,则请求可能永远不会发送。 如果我们正在发送请求(在我们得到响应之前),网络连接可能会断开。 或者它可能会在我们发送后但在我们收到回复之前掉线。 或者它可能会在我们开始收到响应之后但在完全接收到响应之前下降。
这就是我们在定义请求和响应类型时创建 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 Error
或 404 Not Found
响应是成功的响应。 在这一层,“成功”意味着“我们得到了回应”,而不是“回应表明某种语义错误”。 解释状态代码是特定于应用程序的逻辑。 在未来的帖子中,我们将允许基于状态代码的可定制的、特定于应用程序的行为(例如跟随重定向或重试请求)。
我们定义的这个单一方法看似简单,但也不完整。 我们还没有指出任何主动取消请求的方法,我们需要调整我们的 HTTPLoading
协议以添加更多功能。 我们还将把它从协议转换为类,原因我将在以后的帖子中解释。
尽管存在这些小漏洞,该协议在其简单性方面仍然很漂亮,它展示了一个好的问题概念化如何能够产生强大而美丽的东西。
简单是最终的复杂。
在下一篇文章中,我们将研究使用 HTTPLoading
协议来简化单元测试。
以上就是Swift HTTP加载请求Loading Requests教程的详细内容,更多关于Swift HTTP加载请求的资料请关注脚本之家其它相关文章!
标签:
据各方数据,1月31日上午10时许,深圳出品的动画电影《熊出没·伴我熊芯》票房突破10亿元,在首日票房、档期票房、连续破亿天数等多方面打
1月27日,携程发布的《2023年春节旅游总结报告》显示,今年春节,深圳游客的出境游订单量同比去年增长近5倍。相较国内热门景点的人山人海,
1月27日,记者从深圳市文化广电旅游体育局获悉,2023年春节黄金周期间(1月21日至27日),深圳共接待游客469 25万人次,旅游收入31 58亿元,
据深圳市春运办统计,1月15日和16日连续两天,深圳对外发送旅客人数都在48万左右,春运进入客流高峰期。1月15日,深圳春运对外旅客发送量达
新年音乐会是观众喜闻乐见的年度重要文化品牌活动,多年来已成为深圳市民跨岁迎新的例牌项目。12月30日、31日晚,深圳交响乐团将在深圳音乐
作为来深科研人员中的一员,中山大学附属第八医院的助理研究员郭雅婕对深圳在人才服务方面的举措赞不绝口:我作为基础研究人员,很希望自己
12月1日晚8点,2023年故宫年票正式开售。相比于去年,今年购票顺畅了许多。据了解,2022年故宫年票发售时,因短时间内购买年票人数过多,曾
昨日,冷空气到达,广州气温逐步下降。据商超方面预测,随着气温的逐渐下降,市民对于御寒类商品消费需求有所上升,不少广州商超准备了有关
小井盖、大民生。今年以来,深圳开展全市窨井盖专项治理工作成效显著。截至11月20日,全市共排查窨井盖约350万个,发现存在问题的窨井盖约3
备受关注的汕汕(汕头至汕尾)铁路汕头站及站区工程近日传出最新动态:项目已顺利完成工程招标工作,由中铁建设集团有限公司中标承建。目前,
天天快看点丨ETC设备免费领,“发行
记者刘震山东高速官方APP上有着“ETC免费领”的服务项目,但是点击进去之后多个套餐均需缴纳50元至200元不
民航客运市场持续升温 青岛机场携手
随着国内民航市场持续升温,青岛至上海、广州、深圳等地航空出行需求快速增长。为更好地满足旅客乘机需求,
休闲、遛娃、健身……贮水山儿童公园
5月26日,记者在市北区贮水山儿童公园看到公园内大型儿童活动设施、雕塑、亭廊、喷泉、阅览室等基础设施十
青岛二实验交出亮眼成绩单 近百人通
半岛网5月26日讯(记者李京媛)近日,青岛自招考试录取名单陆续公示,市北区初中的成绩尤为亮眼。其中,青
静音!护航高考,李沧交警开展交通秩
为全力做好2023年高考保障工作,为广大考生提供安静、舒适的备考应考环境,交警李沧大队提前开展护航高考交
布鲁斯-布朗:还没想过下一份合同的
今天,掘金队举行了一场新闻发布会,布鲁斯-布朗出席并接受了媒体的采访。布朗谈到了自己本赛季的表现,透
全国名老中医药专家李娟教授名医工作
5月26日上午,全国老中医药专家、广东省医学领军人才、南方医科大学教授李娟“名中医工作室”揭牌仪式在南
丑八怪歌曲原唱完整版_丑八怪歌曲
1、《丑八怪》是薛之谦演唱的一首歌曲,由甘世佳填词,李荣浩谱曲,收录在薛之谦2013年发行的专辑《意
全球插画产业(佛山)中心落户美陶湾
文、图 羊城晚报全媒体记者景瑾瑾通讯员陈思行5月26日,全球插画产业(佛山)中心在佛山美陶湾正式揭牌,该
克六:跳投最帅五人咋选?网友:马里
直播吧5月27日讯 今天,贾马尔-克劳福德发推:“问你们一个问题,不是最佳射手,你见过的跳投最帅的五位球
@宝爸宝妈:儿童化妆品、护肤品要避
25日是国际爱肤日,六一儿童节马上也快到了,一起关注儿童化妆品安全问题。国家药监局制定的《儿童化妆品监
静音!护航高考,李沧交警开展交通秩
为全力做好2023年高考保障工作,为广大考生提供安静、舒适的备考应考环境,交警李沧大队提前开展护航高考交
每日时讯!广州南沙一男子为实施盗窃
为了方便自己“大展拳脚”,盗窃嫌疑人吴某竟在事主隔壁无人居住的空房子睡了一夜,“耐心”等待作案时机…
布鲁斯-布朗:迫不及待想知道总决打
直播吧5月27日讯 今天,掘金球员布鲁斯-布朗在训练结束后接受了采访。“我们迫不及待地想知道我们总决赛的
今年前四月,全省十大重点产业链累计
今年前四月,全省十大重点产业链累计营收1588 2亿元,主流媒体,山西门户。山西新闻网是经国务院新闻办审核批
我省宣传推进社会信用体系建设-世界
我省宣传推进社会信用体系建设,主流媒体,山西门户。山西新闻网是经国务院新闻办审核批准,由山西日报报业集
世界热推荐:生命读本_关于生命读本
生命读本,关于生命读本介绍这个很多人还不知道,我们一起来看看!1、《生命读本》是2010年中国物资出版社出
省气象台预报5月28日至30日将出现降
省气象台预报5月28日至30日将出现降雨天气,主流媒体,山西门户。山西新闻网是经国务院新闻办审核批准,由山
游千里太行览大美风光|天天短讯
游千里太行览大美风光,主流媒体,山西门户。山西新闻网是经国务院新闻办审核批准,由山西日报报业集团主管、
生命誓言_关于生命誓言介绍|全球新动
生命誓言,关于生命誓言介绍这个很多人还不知道,我们一起来看看!1、《生命誓言》是连载于起点中文网的一部
生命要继续_关于生命要继续介绍|每日
生命要继续,关于生命要继续介绍这个很多人还不知道,我们一起来看看!1、《生命要继续》,是由黄崇旭作词,
生命要设防_关于生命要设防介绍
生命要设防,关于生命要设防介绍这个很多人还不知道,我们一起来看看!1、《生命要设防》是2008年湖北科学技
生命表的构造理论_关于生命表的构造
生命表的构造理论,关于生命表的构造理论介绍这个很多人还不知道,我们一起来看看!1、《生命表的构造理论》
马龙:不管总决赛对手是谁 我们都有
直播吧5月27日讯 昨日东决G5,绿军110-97战胜热火,大比分扳为2-3。今天,掘金主帅马龙在接受采访时这样说
18支龙舟队将齐聚“龙舟之乡”
为进一步提高人民群众非遗保护意识,传承弘扬中华优秀传统文化,彰显岭南文化底蕴,推动人文湾区建设,5月2
山西银保监局组织召开专场新闻发布会
山西银保监局组织召开专场新闻发布会,主流媒体,山西门户。山西新闻网是经国务院新闻办审核批准,由山西日报
福建某小学∶老教师上班备课刷剧,怒
在很多人看来,老师这份工作也就平时给学生们上上课,非常的轻松而惬意。殊不知,上课只是教师工作中很小的
焦点速讯:延安市安塞区召开第一次民
延安市安塞区召开第一次民营企业“周解难”会议
供应压力仍在 菜油弱势下调
菜油市场价格走势图表据生意社商品行情分析系统监测:5月19日菜籽油现货市场均价8383元 吨,5月25日菜籽油
美国一极右翼组织成员因参与国会大厦
新湖南,主流新媒体,移动新门户。-分享自@新湖南