Alamofire4.x开源代码分析(五)进阶用法
Alamofire4.x开源代码分析(五)进阶用法
她吃西红柿 发表于5个月前
Alamofire4.x开源代码分析(五)进阶用法
  • 发表于 5个月前
  • 阅读 23
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

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

建议阅读

Session Manager

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

Alamofire.request("https://httpbin.org/get") 
let sessionManager = Alamofire.SessionManager.default
sessionManager.request("https://httpbin.org/get")

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

Creating a Session Manager with Default Configuration

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

Creating a Session Manager with Background Configuration

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

Creating a Session Manager with Ephemeral Configuration

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

自定义Session Configuration

var defaultHeaders = Alamofire.SessionManager.defaultHTTPHeaders
defaultHeaders["DNT"] = "1 (Do Not Track Enabled)"

let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = defaultHeaders

let sessionManager = Alamofire.SessionManager(configuration: configuration)

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

Session Delegate

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

/// Overrides default behavior for URLSessionDelegate method `urlSession(_:didReceive:completionHandler:)`.
open var sessionDidReceiveChallenge: ((URLSession, URLAuthenticationChallenge) -> (URLSession.AuthChallengeDisposition, URLCredential?))?

/// Overrides default behavior for URLSessionDelegate method `urlSessionDidFinishEvents(forBackgroundURLSession:)`.
open var sessionDidFinishEventsForBackgroundURLSession: ((URLSession) -> Void)?

/// Overrides default behavior for URLSessionTaskDelegate method `urlSession(_:task:willPerformHTTPRedirection:newRequest:completionHandler:)`.
open var taskWillPerformHTTPRedirection: ((URLSession, URLSessionTask, HTTPURLResponse, URLRequest) -> URLRequest?)?

/// Overrides default behavior for URLSessionDataDelegate method `urlSession(_:dataTask:willCacheResponse:completionHandler:)`.
open var dataTaskWillCacheResponse: ((URLSession, URLSessionDataTask, CachedURLResponse) -> CachedURLResponse?)?

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

let sessionManager = Alamofire.SessionManager(configuration: URLSessionConfiguration.default)
let delegate: Alamofire.SessionDelegate = sessionManager.delegate

delegate.taskWillPerformHTTPRedirection = { session, task, response, request in
    var finalRequest = request

    if
        let originalRequest = task.originalRequest,
        let urlString = originalRequest.url?.urlString,
        urlString.contains("apple.com")
    {
        finalRequest = originalRequest
    }

    return finalRequest
}

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

class LoggingSessionDelegate: SessionDelegate {
    override func urlSession(
        _ session: URLSession,
        task: URLSessionTask,
        willPerformHTTPRedirection response: HTTPURLResponse,
        newRequest request: URLRequest,
        completionHandler: @escaping (URLRequest?) -> Void)
    {
        print("URLSession will perform HTTP redirection to request: \(request)")

        super.urlSession(
            session,
            task: task,
            willPerformHTTPRedirection: response,
            newRequest: request,
            completionHandler: completionHandler
        )
    }
}

####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协议.

let urlString = "https://httpbin.org/post"
Alamofire.request(urlString, method: .post)

let url = URL(string: urlString)!
Alamofire.request(url, method: .post)

let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true)!
Alamofire.request(urlComponents, method: .post)

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

let urlString = "https://httpbin.org/post"
Alamofire.request(urlString, method: .post)

let url = URL(string: urlString)!
Alamofire.request(url, method: .post)

let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true)!
Alamofire.request(urlComponents, method: .post)

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

extension User: URLConvertible {
    static let baseURLString = "https://example.com"

    func asURL() throws -> URL {
    	let urlString = User.baseURLString + "/users/\(username)/"
        return try urlString.asURL()
    }
}
let user = User(username: "mattt")
Alamofire.request(user) // https://example.com/users/mattt
共有 人打赏支持
粉丝 33
博文 42
码字总数 21178
×
她吃西红柿
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: