美文网首页
Alamofire源码解析 - Request

Alamofire源码解析 - Request

作者: wanglj | 来源:发表于2017-04-06 15:35 被阅读0次

    Request.swift代码结构主要是由Request及其它的三个子类DataRequest,DownloadRequest,UploadRequest组成,另外还有StreamRequest这个类很简单文中就没有提及。

    • Request负责发送请求和接收响应,服务器返回的相关数据,以及管理其URLSessionTas

    Request

    • 阅读这段代码注意最重要的私有属性taskDelegate,以及它对应的open属性delegateRequest的操作都是调用对应taskDelegate中的resume(),suspend(),cancel()方法。
        init(session: URLSession, requestTask: RequestTask, error: Error? = nil) {
            self.session = session
    
            switch requestTask {
            case .data(let originalTask, let task):
                taskDelegate = DataTaskDelegate(task: task)
                self.originalTask = originalTask
            case .download(let originalTask, let task):
                taskDelegate = DownloadTaskDelegate(task: task)
                self.originalTask = originalTask
            case .upload(let originalTask, let task):
                taskDelegate = UploadTaskDelegate(task: task)
                self.originalTask = originalTask
            case .stream(let originalTask, let task):
                taskDelegate = TaskDelegate(task: task)
                self.originalTask = originalTask
            }
    
            delegate.error = error
            delegate.queue.addOperation { self.endTime = CFAbsoluteTimeGetCurrent() }
        }·
    
    

    初始化的时候需要传入URLSessionRequestTask,通过不同的requestTask生成不同的TaskDelegate赋值给属性taskDelegate。这么做的原因是子类都是调用这个方法初始化,所以不同的子类传入的requestTask就不同。统一的操作是把originalTask保存了下来,这么做的目的是当请求失败后再次请求时通过originalTasktask方法生成新的URLSessionTask

    • Request的子类都定义了一个实现TaskConvertible协议的类型,用做初始化自己时使用的RequestTask参数、

    DataRequest

        struct Requestable: TaskConvertible {
            let urlRequest: URLRequest
    
            func task(session: URLSession, adapter: RequestAdapter?, queue: DispatchQueue) throws -> URLSessionTask {
                do {
                    let urlRequest = try self.urlRequest.adapt(using: adapter)
                    return queue.syncResult { session.dataTask(with: urlRequest) }
                } catch {
                    throw AdaptError(error: error)
                }
            }
        }
    
    
    • 定义TaskConvertible, 通过task()返回URLSessionTask
    • 重写了request属性,在通过父类get方法没有返回值的情况下放回 requestable.urlRequest
    • progress属性用于表示请求进度
    • var dataDelegate: DataTaskDelegate { return delegate as! DataTaskDelegate }把父类的TaskDelegate转化成DataTaskDelegate

    DownloadRequest

    两种下载方式,createIntermediateDirectories创建中间目录,removePreviousFile删除目的地之前文件

        public struct DownloadOptions: OptionSet {
            /// Returns the raw bitmask value of the option and satisfies the `RawRepresentable` protocol.
            public let rawValue: UInt
    
            /// A `DownloadOptions` flag that creates intermediate directories for the destination URL if specified.
            public static let createIntermediateDirectories = DownloadOptions(rawValue: 1 << 0)
    
            /// A `DownloadOptions` flag that removes a previous file from the destination URL if specified.
            public static let removePreviousFile = DownloadOptions(rawValue: 1 << 1)
    
            /// Creates a `DownloadFileDestinationOptions` instance with the specified raw value.
            ///
            /// - parameter rawValue: The raw bitmask value for the option.
            ///
            /// - returns: A new log level instance.
            public init(rawValue: UInt) {
                self.rawValue = rawValue
            }
        }
    
    

    两种下载方式,URLRequestData可以继续上次未完成的下载任务。

        enum Downloadable: TaskConvertible {
            case request(URLRequest)
            case resumeData(Data)
    
            func task(session: URLSession, adapter: RequestAdapter?, queue: DispatchQueue) throws -> URLSessionTask {
                do {
                    let task: URLSessionTask
    
                    switch self {
                    case let .request(urlRequest):
                        let urlRequest = try urlRequest.adapt(using: adapter)
                        task = queue.syncResult { session.downloadTask(with: urlRequest) }
                    case let .resumeData(resumeData):
                        task = queue.syncResult { session.downloadTask(withResumeData: resumeData) }
                    }
    
                    return task
                } catch {
                    throw AdaptError(error: error)
                }
            }
        }
    
    • 重写request属性
    • resumeData下载的data

    UploadRequest

    定义了三种上传的方式

    enum Uploadable: TaskConvertible {
            case data(Data, URLRequest)
            case file(URL, URLRequest)
            case stream(InputStream, URLRequest)
    
            func task(session: URLSession, adapter: RequestAdapter?, queue: DispatchQueue) throws -> URLSessionTask {
                do {
                    let task: URLSessionTask
    
                    switch self {
                    case let .data(data, urlRequest):
                        let urlRequest = try urlRequest.adapt(using: adapter)
                        task = queue.syncResult { session.uploadTask(with: urlRequest, from: data) }
                    case let .file(url, urlRequest):
                        let urlRequest = try urlRequest.adapt(using: adapter)
                        task = queue.syncResult { session.uploadTask(with: urlRequest, fromFile: url) }
                    case let .stream(_, urlRequest):
                        let urlRequest = try urlRequest.adapt(using: adapter)
                        task = queue.syncResult { session.uploadTask(withStreamedRequest: urlRequest) }
                    }
    
                    return task
                } catch {
                    throw AdaptError(error: error)
                }
            }
        }
    

    相关文章

      网友评论

          本文标题:Alamofire源码解析 - Request

          本文链接:https://www.haomeiwen.com/subject/prhqattx.html