Last active
May 26, 2023 08:28
-
-
Save StarWars/ba0ced0f27b4bf6761bf776a63be1a4b to your computer and use it in GitHub Desktop.
HTTP upload to S3 using Swift and Alamofire 4+
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class S3UploadCredentials: NSObject { | |
var bucketUrl: String | |
var key: String | |
var acl: String | |
var credential: String | |
var date: String | |
var algorithm: String | |
var policy: String | |
var signature: String | |
var fileUrl: String | |
init(bucketUrl: String, key: String, acl: String, credential: String, algorithm: String, date: String, policy: String, signature: String, fileUrl: String) { | |
self.bucketUrl = bucketUrl | |
self.key = key | |
self.acl = acl | |
self.credential = credential | |
self.algorithm = algorithm | |
self.date = date | |
self.policy = policy | |
self.signature = signature | |
self.fileUrl = fileUrl | |
} | |
} | |
// MARK: - S3 | |
private func uploadImageToS3(image: UIImage, uploadCredentials s3: S3UploadCredentials, completion: @escaping ((Error?) -> ())) { | |
let parameter = ["policy": s3.policy, | |
"x-amz-algorithm": s3.algorithm, | |
"x-amz-credential": s3.credential, | |
"x-amz-date": s3.date, | |
"x-amz-signature": s3.signature, | |
"key": s3.key, | |
"acl": s3.acl] | |
guard let data = UIImageJPEGRepresentation(image, 1.0) else { | |
let err = NSError(domain: "pl.appbeat", code: 9_999, userInfo: ["Data error": "Was not able to prepare image from data."]) | |
completion(err) // Provide a meaningful error for your app here | |
return | |
} | |
Alamofire.upload(multipartFormData: { (multipartForm) in | |
for (key, value) in parameter { | |
multipartForm.append(value.data(using: .utf8)!, withName: key) | |
} | |
multipartForm.append(data, withName: "file")//, fileName: "file", mimeType: "image/jpeg") | |
}, to: s3.bucketUrl, method : .put, headers: nil) { (encodingResult) in | |
completion(nil) | |
switch encodingResult { | |
case .success(let upload, _, _): | |
upload.responseData { response in | |
switch response.result { | |
case .success: | |
print(response.response!.statusCode) | |
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) { | |
print("Server Response: \(utf8Text)") // original server data as UTF8 string | |
} | |
break | |
case .failure(let error): | |
print(response.response!.statusCode) | |
debugPrint(error) | |
break | |
} | |
} | |
case .failure(let encodingError): | |
print(encodingError) | |
} | |
} | |
} |
Also, is the bucketUrl one with all the Query Params like this one showcased in the AWS Docs?
https://s3.amazonaws.com/examplebucket/test.txt
?X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20130524%2Fus-east-1%2Fs3%2Faws4_request
&X-Amz-Date=20130524T000000Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host
&X-Amz-Signature=<signature-value>
Thanks!
It's much simpler if you have a presigned-url. I couldn't get multi-part form to work as it was corrupting the file/image contents.
//data = UIImage.jpegData(...)
//url = presigned url
//method = needs to be same as what was used to generate presigned url
Alamofire
.upload(data, to: url, method: .put)
.responseString() { response in
switch response.result {
case .success:
//success
case .failure(let error):
//failure
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello there,
I'm desperately trying to get this to work for me. Could you please Help Me?
Out of the following Headers:
Could you please tell me where can I get: policy, key and acl?
Thank you very Much in advance!