在iOS Swift中使用Alamofire使用MultipartFormData发送POST参数

Ank*_*ush 54 http ios swift alamofire

我第一次使用Alamofire.我使用的是最新版本Alamofire 1.3.1.我想在一次API调用中发送一个图像,一个视频和一些POST参数.我正在使用多部分表单数据.多部分模块正在运行.我发送额外的POST参数时遇到问题params.以下是我的代码."params"是包含额外参数的字典?如何在请求中附加这些POST参数.请帮忙

        var fullUrl :String = Constants.BASE_URL + "/api/CompleteChallenge"
         var params = [
        "authKey": Constants.AuthKey,
        "idUserChallenge": "16",
        "comment": "",
        "photo": imagePath,
        "video": videoPath,
        "latitude": "1",
        "longitude": "1",
        "location": "india"
    ]

    let imagePathUrl = NSURL(fileURLWithPath: imagePath!)
    let videoPathUrl = NSURL(fileURLWithPath: videoPath!)

        Alamofire.upload(
        .POST,
        URLString: fullUrl, // http://httpbin.org/post
        multipartFormData: { multipartFormData in
            multipartFormData.appendBodyPart(fileURL: imagePathUrl!, name: "photo")
            multipartFormData.appendBodyPart(fileURL: videoPathUrl!, name: "video")
        },
        encodingCompletion: { encodingResult in
            switch encodingResult {
            case .Success(let upload, _, _):
                upload.responseJSON { request, response, JSON, error in

                  }
                }
            case .Failure(let encodingError):

            }
        }
    )
Run Code Online (Sandbox Code Playgroud)

Ank*_*ush 73

我终于找到了解决办法.

我们可以将请求中的数据作为multipartformdata附加.

以下是我的代码.

  Alamofire.upload(
        .POST,
        URLString: fullUrl, // http://httpbin.org/post
        multipartFormData: { multipartFormData in
            multipartFormData.appendBodyPart(fileURL: imagePathUrl!, name: "photo")
            multipartFormData.appendBodyPart(fileURL: videoPathUrl!, name: "video")
            multipartFormData.appendBodyPart(data: Constants.AuthKey.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"authKey")
            multipartFormData.appendBodyPart(data: "\(16)".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"idUserChallenge")
            multipartFormData.appendBodyPart(data: "comment".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"comment")
            multipartFormData.appendBodyPart(data:"\(0.00)".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"latitude")
            multipartFormData.appendBodyPart(data:"\(0.00)".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"longitude")
            multipartFormData.appendBodyPart(data:"India".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name :"location")
        },
        encodingCompletion: { encodingResult in
            switch encodingResult {
            case .Success(let upload, _, _):
                upload.responseJSON { request, response, JSON, error in


                }
            case .Failure(let encodingError):

            }
        }
    )
Run Code Online (Sandbox Code Playgroud)

编辑1:对于那些试图发送数组而不是float,int或string的人,他们可以在Json String中转换他们的数组或任何类型的数据结构,将此JSON字符串作为普通字符串传递.并在后端解析此json字符串以获取原始数组

  • 我可以打印multipartFormData,以便知道我要发送给服务器的内容吗? (3认同)
  • 任何人都可以为swift 3和Alamofire 4更新它.将参数传递给append函数时,我无法将参数转换为类型数据. (3认同)

Ale*_*olz 31

在Alamofire 4中,添加文件数据之前添加正文数据非常重要!

let parameters = [String: String]()
[...]
self.manager.upload(
    multipartFormData: { multipartFormData in
        for (key, value) in parameters {
            multipartFormData.append(value.data(using: .utf8)!, withName: key)
        }
        multipartFormData.append(imageData, withName: "user", fileName: "user.jpg", mimeType: "image/jpeg")
    },
    to: path,
    [...]
)
Run Code Online (Sandbox Code Playgroud)

  • “在Alamofire 4中,在添加文件数据之前添加主体数据很重要”。这一行对我来说意义重大。我被困了2天只是因为我先添加图像,然后机身和服务器返回400。谢谢,但是在我以前使用alamofire 4的应用程序中并没有发生。这是第一次,而且很奇怪。谁能解释为什么?+1 (3认同)

Mur*_*niz 17

这就是我如何解决我的问题

let parameters = [
            "station_id" :        "1000",
            "title":      "Murat Akdeniz",
            "body":        "xxxxxx"]

let imgData = UIImageJPEGRepresentation(UIImage(named: "1.png")!,1)



    Alamofire.upload(
        multipartFormData: { MultipartFormData in
        //    multipartFormData.append(imageData, withName: "user", fileName: "user.jpg", mimeType: "image/jpeg")

            for (key, value) in parameters {
                MultipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
            }

        MultipartFormData.append(UIImageJPEGRepresentation(UIImage(named: "1.png")!, 1)!, withName: "photos[1]", fileName: "swift_file.jpeg", mimeType: "image/jpeg")
        MultipartFormData.append(UIImageJPEGRepresentation(UIImage(named: "1.png")!, 1)!, withName: "photos[2]", fileName: "swift_file.jpeg", mimeType: "image/jpeg")


    }, to: "http://platform.twitone.com/station/add-feedback") { (result) in

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

            upload.responseJSON { response in
                print(response.result.value)
            }

        case .failure(let encodingError): break
            print(encodingError)
        }


    }
Run Code Online (Sandbox Code Playgroud)


dfr*_*fri 8

Swift 3/Alamofire 4.0 (接受答案的附录)

要附加到multipartFormDataSwift 3/Alamofire 4.0中,请使用以下方法MultipartFormData:

public func append(_ data: Data, withName name: String) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

并且,转换StringData,data(using:)方法String.例如,

multipartFormData.append("comment".data(using: .utf8)!, withName: "comment")
Run Code Online (Sandbox Code Playgroud)


Suh*_*til 7

Alamofire 5 及以上版本

AF.upload(multipartFormData: { multipartFormData in
    multipartFormData.append(Data("one".utf8), withName: "one")
    multipartFormData.append(Data("two".utf8), withName: "two")
    multipartFormData.append(imageData, withName: "file", fileName: "photo.jpg", mimeType: "image/jpg")
}, 
to: "https://httpbin.org/post").responseDecodable(of: MultipartResponse.self) { response in
        debugPrint(response)
}
Run Code Online (Sandbox Code Playgroud)

文档链接:分段上传


imi*_*ike 5

对于 Swift 4.2 / Alamofire 4.7.3

Alamofire.upload(multipartFormData: { multipart in
    multipart.append(fileData, withName: "payload", fileName: "someFile.jpg", mimeType: "image/jpeg")
    multipart.append("comment".data(using: .utf8)!, withName :"comment")
}, to: "endPointURL", method: .post, headers: nil) { encodingResult in
    switch encodingResult {
    case .success(let upload, _, _):
        upload.response { answer in
            print("statusCode: \(answer.response?.statusCode)")
        }
        upload.uploadProgress { progress in
            //call progress callback here if you need it
        }
    case .failure(let encodingError):
        print("multipart upload encodingError: \(encodingError)")
    }
}
Run Code Online (Sandbox Code Playgroud)

你也可以看看CodyFire 库,它使 API 调用更容易使用 Codable。使用 CodyFire 的多部分调用示例

//Declare your multipart payload model
struct MyPayload: MultipartPayload {
    var attachment: Attachment //or you could use just Data instead
    var comment: String
}

// Prepare payload for request
let imageAttachment = Attachment(data: UIImage(named: "cat")!.jpeg(.high)!,
                                 fileName: "cat.jpg",
                                 mimeType: .jpg)
let payload = MyPayload(attachment: imageAttachment, comment: "Some text")

//Send request easily
APIRequest("endpoint", payload: payload)
    .method(.post)
    .desiredStatus(.created) //201 CREATED
    .onError { error in
        switch error.code {
        case .notFound: print("Not found")
        default: print("Another error: " + error.description)
        }
    }.onSuccess { result in
        print("here is your decoded result")
    }
//Btw normally it should be wrapped into an extension
//so it should look even easier API.some.upload(payload).onError{}.onSuccess{}
Run Code Online (Sandbox Code Playgroud)

您可以查看lib 的自述文件中的所有示例


bla*_*arl 5

Swift 5,将 @Ankush 的Alamofire代码更新为

     var fullUrl = "http://httpbin.org/post" // for example

           Alamofire.upload(multipartFormData: { (multipartFormData) in
                multipartFormData.append( imagePathUrl! , withName: "photo")
                multipartFormData.append( videoPathUrl!,  withName: "video")
                multipartFormData.append(Constants.AuthKey.data(using: .utf8, allowLossyConversion: false)!, withName: "authKey")
                multipartFormData.append("16".data(using: .utf8, allowLossyConversion: false)!, withName: "idUserChallenge")
                multipartFormData.append("111".data(using: .utf8, allowLossyConversion: false)!, withName: "authKey")
                multipartFormData.append("comment".data(using: .utf8, allowLossyConversion: false)!, withName: "comment")
                multipartFormData.append("0.00".data(using: .utf8, allowLossyConversion: false)!, withName: "latitude")
                multipartFormData.append("0.00".data(using: .utf8, allowLossyConversion: false)!, withName: "longitude")
                multipartFormData.append("India".data(using: .utf8, allowLossyConversion: false)!, withName: "location")

            }, to: fullUrl, method: .post) { (encodingResult) in
                switch encodingResult {
                case .success(request: let upload, streamingFromDisk: _, streamFileURL: _):
                    upload.responseJSON { (response) in   // do sth     }
                case .failure(let encodingError):
                    ()
                }
            }
Run Code Online (Sandbox Code Playgroud)