我第一次使用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):
}
}
)
答案 0 :(得分:71)
我终于找到了解决方案:)。
我们可以将请求中的数据作为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):
}
}
)
编辑1:对于那些试图发送数组而不是float,int或string的人来说,他们可以在Json String中转换他们的数组或任何类型的数据结构,传递这个JSON字符串作为普通字符串。并在后端解析此json字符串以获取原始数组
答案 1 :(得分:22)
在Alamofire 4中,添加文件数据>>之前添加正文数据非常重要!
std::cout
答案 2 :(得分: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)
}
}
答案 3 :(得分:8)
Swift 3 / Alamofire 4.0 (accepted answer的附录)
要附加到Swift 3 / Alamofire 4.0中的multipartFormData
,请使用MultipartFormData
的以下方法:
public func append(_ data: Data, withName name: String) { /* ... */ }
并且,要将String
转换为Data
,data(using:)
方法String
。如,
multipartFormData.append("comment".data(using: .utf8)!, withName: "comment")
答案 4 :(得分:3)
在Swift 3.x中,对于带参数的上传图片,我们可以使用下面的alamofire上传方法 -
static func uploadImageData(inputUrl:String,parameters:[String:Any],imageName: String,imageFile : UIImage,completion:@escaping(_:Any)->Void) {
let imageData = UIImageJPEGRepresentation(imageFile , 0.5)
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(imageData!, withName: imageName, fileName: "swift_file\(arc4random_uniform(100)).jpeg", mimeType: "image/jpeg")
for key in parameters.keys{
let name = String(key)
if let val = parameters[name!] as? String{
multipartFormData.append(val.data(using: .utf8)!, withName: name!)
}
}
}, to:inputUrl)
{ (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (Progress) in
})
upload.responseJSON { response in
if let JSON = response.result.value {
completion(JSON)
}else{
completion(nilValue)
}
}
case .failure(let encodingError):
completion(nilValue)
}
}
}
注意:此外,如果我们的参数是键对数组,那么我们可以 使用
var arrayOfKeyPairs = [[String:Any]]()
let json = try? JSONSerialization.data(withJSONObject: arrayOfKeyPairs, options: [.prettyPrinted])
let jsonPresentation = String(data: json!, encoding: .utf8)
答案 5 :(得分:3)
对于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)")
}
}
此外,您还可以查看CodyFire lib,它使用Codable对所有内容进行API调用变得更加容易。 使用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{}
您可以查看lib's readme
中的所有示例答案 6 :(得分:1)
Alamofire 5及更高版本
AF.upload(multipartFormData: { multipartFormData in
multipartFormData.append(Data("one".utf8), withName: "one")
multipartFormData.append(Data("two".utf8), withName: "two")
},
to: "https://httpbin.org/post").responseDecodable(of: MultipartResponse.self) { response in
debugPrint(response)
}
文档链接:multipart upload
答案 7 :(得分:0)
for alamofire 4使用此..
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(fileUrl, withName: "video")
//fileUrl is your file path in iOS device and withName is parameter name
}, to:"http://to_your_url_path")
{ (result) in
switch result {
case .success(let upload, _ , _):
upload.uploadProgress(closure: { (progress) in
print("uploding")
})
upload.responseJSON { response in
print("done")
}
case .failure(let encodingError):
print("failed")
print(encodingError)
}
}
答案 8 :(得分:0)
好吧,由于Multipart Form Data旨在用于二进制(和文本)数据传输,我认为将编码的数据发送到String上是不好的做法。
另一个缺点是不可能发送更复杂的参数,如JSON。
尽管如此,更好的选择是以二进制形式发送所有数据,即数据。
说我需要发送此数据
for group in tree.iterfind('.//group'):
for groupfilter in group.iterfind('.//groupfilter'):
groupname = group.get('name')
expression = groupfilter.get('expression', '') # default: empty string
print([groupname, expression])
...与用户的图片一起:
let name = "Arthur"
let userIDs = [1,2,3]
let usedAge = 20
为此,我将该文本数据转换为JSON,然后转换为二进制文件与图像:
let image = UIImage(named: "img")!
然后,最后通过Multipart Form Data请求发送它:
//Convert image to binary
let data = UIImagePNGRepresentation(image)!
//Convert text data to binary
let dict: Dictionary<String, Any> = ["name": name, "userIDs": userIDs, "usedAge": usedAge]
userData = try? JSONSerialization.data(withJSONObject: dict)
答案 9 :(得分:0)
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):
()
}
}
答案 10 :(得分:-1)
func funcationname()
{
var parameters = [String:String]()
let apiToken = "Bearer \(UserDefaults.standard.string(forKey: "vAuthToken")!)"
let headers = ["Vauthtoken":apiToken]
let mobile = "\(ApiUtillity.sharedInstance.getUserData(key: "mobile"))"
parameters = ["first_name":First_name,"last_name":last_name,"email":Email,"mobile_no":mobile]
print(parameters)
ApiUtillity.sharedInstance.showSVProgressHUD(text: "Loading...")
let URL1 = ApiUtillity.sharedInstance.API(Join: "user/update_profile")
let url = URL(string: URL1.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!)
var urlRequest = URLRequest(url: url!)
urlRequest.httpMethod = "POST"
urlRequest.allHTTPHeaderFields = headers
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(self.imageData_pf_pic, withName: "profile_image", fileName: "image.jpg", mimeType: "image/jpg")
for (key, value) in parameters {
multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
}, with: urlRequest) { (encodingResult) in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
if let JSON = response.result.value {
print("JSON: \(JSON)")
let status = (JSON as AnyObject).value(forKey: "status") as! Int
let sts = Int(status)
if sts == 200
{
ApiUtillity.sharedInstance.dismissSVProgressHUD()
let UserData = ((JSON as AnyObject).value(forKey: "data") as! NSDictionary)
ApiUtillity.sharedInstance.setUserData(data: UserData)
}
else
{
ApiUtillity.sharedInstance.dismissSVProgressHUD()
let ErrorDic:NSDictionary = (JSON as AnyObject).value(forKey: "message") as! NSDictionary
let Errormobile_no = ErrorDic.value(forKey: "mobile_no") as? String
let Erroremail = ErrorDic.value(forKey: "email") as? String
if Errormobile_no?.count == nil
{}
else
{
ApiUtillity.sharedInstance.dismissSVProgressHUDWithError(error: Errormobile_no!)
}
if Erroremail?.count == nil
{}
else
{
ApiUtillity.sharedInstance.dismissSVProgressHUDWithError(error: Erroremail!)
}
}
}
}
case .failure(let encodingError):
ApiUtillity.sharedInstance.dismissSVProgressHUD()
print(encodingError)
}
}
}