Alamofire 多部分请求

Posted

技术标签:

【中文标题】Alamofire 多部分请求【英文标题】:Alamofire Multipart request 【发布时间】:2017-11-28 11:58:30 【问题描述】:

我是快速编程的新手。我正在尝试通过 alamofire 进行多部分请求。问题是我的参数中的一个值是对象数组。我的问题是如何将对象数组附加到多部分请求。 这是我的参数。

 let parameters = [
        "originguid":"63d6sd5",
        "signees":[Signess], //Here is issue "signees"is an array of objects
        "customer":"yes"
        ] as [String : Any]

这是我的要求

Alamofire.upload(
    .POST,
    URLString: myUrl,
    multipartFormData:  multipartFormData in

        if let img = self.imagePicked 
            multipartFormData.append(UIImageJPEGRepresentation(img, 0.2)!, withName: "fileset",fileName: "file.png", mimeType: "image/jpg")
        
        if let file = self.filePicked
            let fileData = try! Data(contentsOf: file)
            multipartFormData.append(fileData as Data, withName:"test.pdf", mimeType:"application/pdf")
        

        for (key, value) in parameters 

            if key == "signees"
                   multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
            

            else
                multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
            


        

    ,

    ...
)

将签名者附加到多部分请求时应用程序崩溃。 这是我在参数中使用的对象。

class Signee: NSObject, NSCoding 
var name = ""
var email = ""
var phoneNo = ""
func encode(with aCoder: NSCoder) 
    aCoder.encode(name, forKey: "name")
    aCoder.encode(email, forKey: "email")
    aCoder.encode(phoneNo, forKey: "phoneNo")

init(name: String, email: String, phone: String) 
    self.name = name
    self.email = email

    self.phoneNo = phone


required convenience init(coder aDecoder: NSCoder) 
    let name = aDecoder.decodeObject(forKey: "name") as! String
    let email = aDecoder.decodeObject(forKey: "email") as! String
    let phoneNo = aDecoder.decodeObject(forKey: "phoneNo") as! String
    self.init(name: name, email: email, phone: phoneNo)

请帮忙。在此先感谢,我浪费了两天时间尝试不同的东西。

【问题讨论】:

为什么不对字符串使用编码字节编码 抱歉没看懂 你应该添加基本类型的键值对,例如Int、String等 我的问题是如何将对象数组附加到多部分请求中。 【参考方案1】:

与 Alamofire 的多部分

let headerDic: HTTPHeaders = [ "YOUR_HEADER_DIC" ]

let paramDic: Parameters = [ "YOUR_PARAMETER_DIC" ]

Alamofire.upload(multipartFormData:  (MultipartFormData) in

            MultipartFormData.append("YOUR_IMAGEDATA", withName: "YOUR_IMAGE_PARAMETER_NAME", fileName: "YOUR_IMAGENAME", mimeType: "image/jpeg")

            for (key, value) in paramDic 

                MultipartFormData.append(((value as AnyObject).data(using: String.Encoding.utf8.rawValue))!, withName: key)
            

        , to: "YOUR_WEBSERVICE_NAME", method: .post, headers: headerDic)  (result) in

            switch result 

            case .success(let upload, _, _):

                upload.responseJSON  response in

                    if let value = response.result.value 

                        let responseDic: NSDictionary = value as! NSDictionary

                             "YOUR_WEB_RESPONSE_SUCCESS_MESSEGE"

                         else 

                            "YOUR_WEB_RESPONSE_ERROR_MESSEGE"
                        
                    
                

            case .failure(let encodingError):

                var messege: String = String()

                if encodingError.localizedDescription.characters.count <= 0 

                    messege = "Please check your Internet Conneciton!"

                 else 

                    messege = encodingError.localizedDescription
                
                print("Error Messege:\(messege)")
            
        

【讨论】:

完全不相关的答案【参考方案2】:

使用almofire的多部分请求

数据发送到多部分

struct AGImageInfo 
    var fileName: String
    var type: String
    var data: Data

请求

let header: HTTPHeaders = [
    "Content-Type":"application/x-www-form-urlencoded"
]

let parameters: Parameters = [
    "someParam": "value",
    "Image": AGImageInfo(fileName: "nameOfImage.jpeg", type: "image/jpeg", data: #imageLiteral(resourceName: "TO").toData()!)
]

Alamofire.upload(multipartFormData:  (multipartFormData) in

    for (key, value) in parameters 
        if let imageData = value as? AGImageInfo 
            multipartFormData.append(imageData.data, withName: key, fileName: imageData.fileName, mimeType: imageData.type)
        
        multipartFormData.append(((value as AnyObject).data(using: String.Encoding.utf8.rawValue))!, withName: key)
    

, to: "URL", method: .post, headers: header)  (result) in

    switch result 
    case .success(let upload, _, _):

        upload.responseJSON  response in
            switch response.result 
            case .success(let value):
                debugPrint(value)
                break

            case .failure(let error):
                debugPrint(error)
                break
            
        

    case .failure(let error):
        debugPrint(error)
        break
    

【讨论】:

*** 由于未捕获的异常 'NSInvalidArgumentException' 导致应用程序终止,原因:'-[Swift._SwiftDeferredNSArray dataUsingEncoding:]:无法识别的选择器发送到实例 0x1c4421fa0'【参考方案3】:
struct File 
    var data: Data
    var name: String
    var mimeType: String

.upload(
         multipartFormData:  multipartFormData in
              for (key, value) in yourDictionnary 
                    if let file = value as? File 
                        multipartFormData.append(
                                file.data,
                                withName: key,
                                fileName: file.name,
                                mimeType: file.mimeType
                        )
                     else 
                          multipartFormData.append(
                                (value as AnyObject).data(using: String.Encoding.utf8.rawValue)!,
                                withName: key
                            )
                        
                    
                ,
                to: "Your URL"
            )

不要忘记 else 的情况,因为你会进入 if 和第二个 multipart.append 你会得到这样的错误 '-[Swift._SwiftDeferredNSArray dataUsingEncoding:]: 无法识别的选择器发送到实例 0x1c4421fa0'

【讨论】:

以上是关于Alamofire 多部分请求的主要内容,如果未能解决你的问题,请参考以下文章

Alamofire 4 - 使用 gzip 编码上传多部分

使用 Alamofire 的多部分 POST

Alamofire 4 多部分

使用 multipartFormData 上传图像时 Alamofire 请求正文为零

Alamofire - 多部分表单数据键:值

Alamofire 2.0 多部分表单数据错误