Alamofire4.x开源代码分析(五)进阶用法

Alamofire基于URLSession和Foundation URL的加载机制,为了更充分的了解和使用本框架,建议大家深刻的学习底层的网络实现.

建议阅读

Session Manager

Alamofire.request就是我们最外层的方法方法,内部通过Alamofire.SessionManager和默认的URLSessionConfiguration实现
下面两者是等价的

1Alamofire.request("https://httpbin.org/get") 2 3 4let sessionManager = Alamofire.SessionManager.default 5sessionManager.request("https://httpbin.org/get")

通过URLSessionConfiguration我们可以自由的修改http请求头,超时时间等.应用程序可以未后台和临时会话创建管理器

Creating a Session Manager with Default Configuration

1let configuration = URLSessionConfiguration.default 2let sessionManager = Alamofire.SessionManager(configuration: configuration)

Creating a Session Manager with Background Configuration

1let configuration = URLSessionConfiguration.background(withIdentifier: "com.example.app.background") 2let sessionManager = Alamofire.SessionManager(configuration: configuration)

Creating a Session Manager with Ephemeral Configuration

1let configuration = URLSessionConfiguration.ephemeral 2let sessionManager = Alamofire.SessionManager(configuration: configuration)

自定义Session Configuration

1var defaultHeaders = Alamofire.SessionManager.defaultHTTPHeaders 2defaultHeaders["DNT"] = "1 (Do Not Track Enabled)" 3 4let configuration = URLSessionConfiguration.default 5configuration.httpAdditionalHeaders = defaultHeaders 6 7let sessionManager = Alamofire.SessionManager(configuration: configuration)

对于Authorization和Content-Type,不建议通过configuration来修改,Alamofire.request API提供的header来配置.

Session Delegate

默认情况下,Alamofire SessionManager会创建一个SessionDelegate对象来处理URLSession生成的所有各种回调,从中抽出最简单的实现方法. 对于特定需求的开发者,需要覆盖这些方法. ####重写闭包 第一种自定义SessionDelegate方法是重写闭包,每个闭包都对应着SessionDelegate的实现. 举例

1/// Overrides default behavior for URLSessionDelegate method `urlSession(_:didReceive:completionHandler:)`. 2open var sessionDidReceiveChallenge: ((URLSession, URLAuthenticationChallenge) -> (URLSession.AuthChallengeDisposition, URLCredential?))? 3 4/// Overrides default behavior for URLSessionDelegate method `urlSessionDidFinishEvents(forBackgroundURLSession:)`. 5open var sessionDidFinishEventsForBackgroundURLSession: ((URLSession) -> Void)? 6 7/// Overrides default behavior for URLSessionTaskDelegate method `urlSession(_:task:willPerformHTTPRedirection:newRequest:completionHandler:)`. 8open var taskWillPerformHTTPRedirection: ((URLSession, URLSessionTask, HTTPURLResponse, URLRequest) -> URLRequest?)? 9 10/// Overrides default behavior for URLSessionDataDelegate method `urlSession(_:dataTask:willCacheResponse:completionHandler:)`. 11open var dataTaskWillCacheResponse: ((URLSession, URLSessionDataTask, CachedURLResponse) -> CachedURLResponse?)? 12

以下是如何使用taskWillPerformHTTPRedirection避免重定向到任何apple.com的问题

1let sessionManager = Alamofire.SessionManager(configuration: URLSessionConfiguration.default) 2let delegate: Alamofire.SessionDelegate = sessionManager.delegate 3 4delegate.taskWillPerformHTTPRedirection = { session, task, response, request in 5 var finalRequest = request 6 7 if 8 let originalRequest = task.originalRequest, 9 let urlString = originalRequest.url?.urlString, 10 urlString.contains("apple.com") 11 { 12 finalRequest = originalRequest 13 } 14 15 return finalRequest 16}

###子类覆盖父类方法 另一种方法就是通过子类来重写父类方法

1class LoggingSessionDelegate: SessionDelegate { 2 override func urlSession( 3 _ session: URLSession, 4 task: URLSessionTask, 5 willPerformHTTPRedirection response: HTTPURLResponse, 6 newRequest request: URLRequest, 7 completionHandler: @escaping (URLRequest?) -> Void) 8 { 9 print("URLSession will perform HTTP redirection to request: \(request)") 10 11 super.urlSession( 12 session, 13 task: task, 14 willPerformHTTPRedirection: response, 15 newRequest: request, 16 completionHandler: completionHandler 17 ) 18 } 19}

####Request request,download, upload stream这四个方法的返回值分别为DataRequest, DownloadRequest, UploadRequest StreamRequest,并且他们都继承自Request.每个子类都有专用的方法,如authenticate,validate,responseJSON和uploadProgress,都会返回调用者的实例,方便使用. Request可以被暂停,恢复,取消:

  • suspend() 暂停
  • resume() 恢复, 在SessionManager中有一个属性:startRequestsImmediately。他控制这请求是不是立刻发起,默认的值为true。
  • cancel() 取消 同时该请求的每一个监听对象都会受到一个错误回调

####Routing Requests 随着应用程序的扩展,在构建网络堆栈时,采用通用模式很重要. 该设计的重要部分是如何路由您的请求. Alamofire URLConvertible和URLRequestConvertible协议以及路由器设计模式就是为之设计的. 路由的概念就是中转站的意思,在Alamofire中,String, URL, URLComponents实现了URLConvertible协议.

1let urlString = "https://httpbin.org/post" 2Alamofire.request(urlString, method: .post) 3 4let url = URL(string: urlString)! 5Alamofire.request(url, method: .post) 6 7let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true)! 8Alamofire.request(urlComponents, method: .post)

采用URLConvertible协议的类型可用于构造URL,然后用于内部构造URL请求。 默认情况下,string,URL和URLComponent准守URLConvertible协议,允许将任何一个作为URL参数传递发送请求,上传和下载等方法:

1let urlString = "https://httpbin.org/post" 2Alamofire.request(urlString, method: .post) 3 4let url = URL(string: urlString)! 5Alamofire.request(url, method: .post) 6 7let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true)! 8Alamofire.request(urlComponents, method: .post)

遵守URLConvertible协议,可以方便我们便捷的使用model与服务器生成映射关系.

1extension User: URLConvertible { 2 static let baseURLString = "https://example.com" 3 4 func asURL() throws -> URL { 5 let urlString = User.baseURLString + "/users/\(username)/" 6 return try urlString.asURL() 7 } 8} 9let user = User(username: "mattt") 10Alamofire.request(user) // https://example.com/users/mattt
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Alamofire4.x开源代码分析(五)进阶用法 - HelloWorld