初めてAlamofireを使用しています。最新バージョンのAlamofire 1.3.1を使用しています。 1つのAPI呼び出しで1つの画像、1つのビデオ、およびいくつかのPOSTパラメーターを送信したい。マルチパートフォームデータを使用しています。 mutipartモジュールは機能しています。余分なPOST parametersparams
を送信する問題に直面しています。以下は私のコードです。 「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):
}
}
)
私は解決策を見つけました:)最後に。
リクエストにデータを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文字列を解析して元の配列を取得します
Alamofire 4では、ボディデータを追加することが重要ですbeforeファイルデータを追加します!
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,
[...]
)
これは私が私の問題を解決する方法です
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)
}
}
Swift 3/Alamofire 4.0( 受け入れられた回答 )への補遺
Swift 3/Alamofire 4.0のmultipartFormData
に追加するには、次の MultipartFormData
のメソッドを使用します。
public func append(_ data: Data, withName name: String) { /* ... */ }
また、String
をData
に変換するには、String
のdata(using:)
メソッドを使用します。例えば。、
multipartFormData.append("comment".data(using: .utf8)!, withName: "comment")
パラメーター付きのアップロード画像の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)
For 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のreadme にあるすべての例を見ることができます。
まあ、マルチパートフォームデータはバイナリ(およびテキスト)データ送信に使用することを目的としているため、エンコードされたデータをStringに送信することは悪い習慣だと思います。
もう1つの欠点は、JSONのようなより複雑なパラメーターを送信できないことです。
ただし、すべてのデータをバイナリ形式で、つまりデータとして送信することをお勧めします。
このデータを送信する必要があるとします
let name = "Arthur"
let userIDs = [1,2,3]
let usedAge = 20
...ユーザーの写真と一緒に:
let image = UIImage(named: "img")!
そのために、そのテキストデータをJSONに変換し、次にイメージと一緒にバイナリに変換します。
//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)
そして最後に、Multipart Form Dataリクエストで送信します:
Alamofire.upload(multipartFormData: { (multiFoormData) in
multiFoormData.append(userData, withName: "user")
multiFoormData.append(data, withName: "picture", mimeType: "image/png")
}, to: url) { (encodingResult) in
...
}
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)
}
}