[英]Problem Uploading Images to S3 Bucket Using AlamoFire and Presigned URL
我為我的應用程序上傳到 S3 的方法是向我的 PHP 后端發送一個獲取請求,以生成一個預簽名的 URL。 我知道后端設置正確,因為運行以下命令成功地將圖像上傳到 S3 存儲桶:
curl -v -H "Content-Type: image/jpeg" -T./test.jpeg '<presignedURL>'
但是,嘗試在 Swift 中上傳圖像時遇到問題。 這是我當前的實現(請忽略垃圾,硬編碼,非錯誤檢查):
后端
<?php
require '../vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\Exception\AwsException;
$response = array();
$client = S3Client::factory(array(
'profile' => 'default',
'version' => 'latest',
'region' => 'us-east-2',
'signature' => 'v4'
));
$command = $client->getCommand('PutObject', array(
'Bucket' => 'test',
'Key' => 'test.jpeg',
'ContentType' => 'image/jpeg',
'Body' => ''
));
$signedUrl = $command->createPresignedUrl('+5 minutes');
$response['error'] = false;
$response['url'] = $signedUrl;
echo json_encode($response);
Swift代碼
import Foundation
import Alamofire
let getTokenURL = "http://192.168.1.59:8000/v1/upload.php"
func submitImage(image: UIImage, completion: @escaping (NSDictionary) -> Void) {
AF.request(getTokenURL, method: .get).responseJSON { response in
switch response.result {
case.success(let value):
let jsonData = value as! NSDictionary
let url = jsonData.value(forKey: "url") as! String
performUpload(image: image, postURL: url)
case.failure(_):
let error_msg: NSDictionary = [
"error" : true,
"message" : "Unknown error occurred. Please try again",
]
//completion(error_msg)
}
}
}
func performUpload(image: UIImage, postURL: String) {
let imageData = image.jpegData(compressionQuality: 0.50)!
AF.upload(imageData, to: postURL, headers: ["Content-Type":"image/jpeg"]) //likely the culprit line
}
目前 URL 從 submitImage() 中的 get 請求返回,並調用 performUpload(),這使得罪魁禍首(可能)成為我的 Swift 代碼段的最后一個問題。 我在閱讀文檔時無法弄清楚我應該做什么,並且大多數關於這個主題的指南都過時了,因為 AlamoFire 已經改變了它們的語法。 任何幫助將不勝感激。 謝謝!
編輯:我已經調整了 performUpload() function。 它現在將數據上傳到 s3 存儲桶,但是無法打開圖像。 我懷疑這是因為請求中的 header 不正確。 通過調試,我可以告訴 Content-Type header 無論如何都是“multipart/form-data”,所以我不確定這種方法是否可行:
struct HTTPBinResponse: Decodable { let url: String }
func performUpload(image: UIImage, postURL: String) {
let imageData = image.jpegData(compressionQuality: 0.50)!
AF.upload(multipartFormData: { multipartFormData in
multipartFormData.append(imageData, withName: "file", mimeType: "image/jpeg")
}, to: postURL, method: .put, headers: ["Content-Type":"image/jpeg"]).responseDecodable(of: HTTPBinResponse.self) { response in
debugPrint(response)
}
}
對於未來的讀者,這里的關鍵是添加method: .put
。 這個問題的其他一切都很好。
我還發現您必須使用空的內容類型標頭。 S3很奇怪。
AF.upload(imageData, to: postURL, method: .put, headers: ["Content-Type": ""])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.