Alamofire-多表单处理

Alamofire-多表单处理


HTTP请求实质上是对指定数据格式的拼接,然后将拼接后的数据进行传输。下面对多表单数据处理进行分析。
主要完成以下工作:

  • 拼接整合原始数据
  • encode为stream流
  • upload网络处理:request-task-resume

首先看应用实例:

func alamofireUploadFile(){
        
        let data = self.readLocalData(fileNameStr: "Cooci", type: "jpg")

        SessionManager.default
            .upload(multipartFormData: { (mutilPartData) in
                mutilPartData.append("Apple".data(using: .utf8)!, withName: "name")
                mutilPartData.append("Banana".data(using: .utf8)!, withName: "username")
                mutilPartData.append("Orange".data(using: .utf8)!, withName: "PASSWORD")

                //mutilPartData.append(data as! Data, withName: "fileName")
            }, to: urlString) { (result) in
                print(result)
                switch result {
                case .failure(let error):
                    print(error)
                case .success(let upload,_,_):
                    upload.response(completionHandler: { (response) in
                        print("****:\(response) ****")
                    })
                }
        }
    }

upload函数

open func upload(
        multipartFormData: @escaping (MultipartFormData) -> Void,
        usingThreshold encodingMemoryThreshold: UInt64 = SessionManager.multipartFormDataEncodingMemoryThreshold,
        with urlRequest: URLRequestConvertible,
        queue: DispatchQueue? = nil,
        encodingCompletion: ((MultipartFormDataEncodingResult) -> Void)?)
    {
        DispatchQueue.global(qos: .utility).async {
            let formData = MultipartFormData()
            multipartFormData(formData)
            ...
}

MultipartFormData类
Alamofire-多表单处理_第1张图片
嵌套结构体类,用于存储信息。主要进行设置boundary分隔符、
EncodingCharacters设置“\r\n”符号、randomBoundary设置随机boundary、设置boundaryData等一系列操作。

append函数

public func append(_ stream: InputStream, withLength length: UInt64, headers: HTTPHeaders) {
        let bodyPart = BodyPart(headers: headers, bodyStream: stream, bodyContentLength: length)
        bodyParts.append(bodyPart)
    }

构造BodyPart对象,并添加到bodyParts容器中。

BodyPart类

class BodyPart {
        let headers: HTTPHeaders
        let bodyStream: InputStream
        let bodyContentLength: UInt64
        var hasInitialBoundary = false
        var hasFinalBoundary = false

        init(headers: HTTPHeaders, bodyStream: InputStream, bodyContentLength: UInt64) {
            self.headers = headers
            self.bodyStream = bodyStream
            self.bodyContentLength = bodyContentLength
        }
    }

使用面向对象的设计模式,将contentHeaders + stream + length 封装为对象BodyPart,然后放到bodyParts容器中:bodyParts.append(bodyPart)。

bodyParts中数据的使用
我们回到upload函数:这里采用异步async调用进行处理,do循环中对bodyParts数据进行使用。
Alamofire-多表单处理_第2张图片

encode()函数
Alamofire-多表单处理_第3张图片
将bodyParts容器中的数据拼接到一起并返回。

upload:最终网络请求上传函数
Alamofire-多表单处理_第4张图片
这就回到了我们熟悉的SessionManager中的upload函数了。由于前面文章已经对upload进行了阐述,此处不再赘述。

注:为什么数据要拼接为stream进行传输呢?
Stream流传输能够减轻系统压力,节省内存。

多表单上传总结:bodyParts整合数据 -> encode为stream流数据 -> request请求 -> upload网络请求。

你可能感兴趣的:(Alamofire)