I'm using Alamofire 4.0 to create a request to upload file directly to S3 Amazon.
I'm using the service from GetCloudApp . After my request Router.shared.prepareForUploadItem
from an api "https://my.cl.ly/v3/items
I retrieve the json like this
{
"slug": "1h132K0z2n3G",
"name": "Image.png",
"url": "http://f.cl.ly",
"uploads_remaining": 1,
"max_upload_size": 26214400,
"s3": {
"AWSAccessKeyId": "AKIAJP2C6U543KJIE2GA",
"key": "items/353u2B053p0H0D1O3w1b/${filename}",
"policy": "eyJleHBpcmF0aW9uIjoiMjAxNS0xMS0xMlQxMjo0MTozOFoiLCJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJjbG91ZGFwcC5jb3BwZXIuaW8ifSxbInN0YXJ0cy13aXRoIiwiJGtleSIsIml0ZW1zLzM1M3UyQjA1M3AwSDBEMU8zdzFiLyJdLHsic3VjY2Vzc19hY3Rpb25fcmVkaXJlY3QiOiJodHRwOi8vbXkuY2wuZGV2L3YzL2l0ZW1zLzFoMTMySzB6Mm4zRy9zMyJ9LHsiYWNsIjoicHVibGljLXJlYWQifSxbImNvbnRlbnQtbGVuZ3RoLXJhbmdlIiwwLDI2MjE0NDAwXV19",
"signature": "wqSVl9+fvkvtIzGfakNF+drqN0s=",
"success_action_redirect": "http://api.cl.ly/v3/items/1h132K0z2n3G/s3",
"acl": "public-read"
}
}
I take these key
and value
as my parameter :
"AWSAccessKeyId": "AKIAJP2C6U543KJIE2GA",
"key": "items/353u2B053p0H0D1O3w1b/${filename}",
"policy": "eyJleHBpcmF0aW9uIjoiMjAxNS0xMS0xMlQxMjo0MTozOFoiLCJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJjbG91ZGFwcC5jb3BwZXIuaW8ifSxbInN0YXJ0cy13aXRoIiwiJGtleSIsIml0ZW1zLzM1M3UyQjA1M3AwSDBEMU8zdzFiLyJdLHsic3VjY2Vzc19hY3Rpb25fcmVkaXJlY3QiOiJodHRwOi8vbXkuY2wuZGV2L3YzL2l0ZW1zLzFoMTMySzB6Mm4zRy9zMyJ9LHsiYWNsIjoicHVibGljLXJlYWQifSxbImNvbnRlbnQtbGVuZ3RoLXJhbmdlIiwwLDI2MjE0NDAwXV19",
"signature": "wqSVl9+fvkvtIzGfakNF+drqN0s=",
"success_action_redirect": "http://api.cl.ly/v3/items/1h132K0z2n3G/s3",
"acl": "public-read"
Then I create the request to upload my file using s3
dictionary like below :
Alamofire.upload(multipartFormData: { (multipartForm) in
for (key, value) in parameter {
let valueData = value.data(using: .utf8, allowLossyConversion: false)
guard let newData = valueData else{
return
}
multipartForm.append(newData, withName: key)
print("\(key) - \(value)")
}
multipartForm.append(data, withName: "file")
}, to: s3.url, method : .post) { (encodingResult) in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
debugPrint(response)
}
case .failure(let encodingError):
print(encodingError)
}
}
Finally I retrieve the response from server like this, I know it all about authentication but I really don't know what's the right way to do that.
status code: 401, headers {
"Cache-Control" = "no-cache";
Connection = "keep-alive";
"Content-Length" = 28;
"Content-Type" = "text/plain; charset=utf-8";
Date = "Sun, 08 Jan 2017 17:37:17 GMT";
Server = "nginx/1.4.6 (Ubuntu)";
Status = "401 Unauthorized";
"Www-Authenticate" = "Digest realm=\"Application\", qop=\"auth\", algorithm=MD5, nonce=\"MTQ4Mzg5NzAzNzpiYmEwN2MzZDljM2RjNDMyMGE1NzI2ODQ5MjhjMWVkNQ==\", opaque=\"9eb56ccb2e8b017ae42bdb4739690863\"";
"X-Request-Id" = 7bd77581bf677aee1b1abba21b3ad097;
"X-Runtime" = "0.004697";
"X-UA-Compatible" = "IE=Edge,chrome=1";
I try many ways but still no luck and can't make it work. I really need help. Thank in advance.
I figured out why this problem is occurred because I need to authenticate my upload request to S3 using CloudApp
's Digest authenticate after my request to CloudApp
to upload new file.
I will posted my completed code below:
func uploadFileToS3(_ s3: S3, data : Data, fileName : String, mimeType : String) {
let params = s3.s3Parameter
Alamofire.upload(multipartFormData: { (multipartForm) in
for (key, value) in params{
multipartForm.append(value.data(using: .utf8)!, withName: key)
}
multipartForm.append(data, withName: "file", fileName: fileName, mimeType: mimeType)
}, to: s3.url, method : .post, headers:["Accept":"application/json"]) { (encodingResult) in
guard let userInfor = UserDefaults.standard.dictionary(forKey: "UserInformation") else {
return
}
switch encodingResult {
case .success(let upload, _, _):
upload.authenticate(user: userInfor["email"]! as! String, password: userInfor["password"]! as! String)
self.progressbar.isHidden = false
upload.uploadProgress(closure: { (progress) in
self.progressbar.progress = Float(progress.fractionCompleted)
})
upload.responseJSON{ response in
self.progressbar.isHidden = true
let result = JSON(response.result.value!)
let file = CloudFile(fileInformation: result)
self.files.append(file)
let indexPath = IndexPath(row: 0, section: 0)
DispatchQueue.main.async {
self.filesTableView.insertRows(at: [indexPath], with: .automatic)
}
}
case .failure(let encodingError):
print(encodingError)
}
}
}
Noticed upload.authenticate(user: userInfor["email"]! as! String, password: userInfor["password"]! as! String)
in encodingResult
result completion handle, this is where you need authenticate your upload request. Alamofire will do the rest.
Hope this will help. Thanks
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.