Amazon S3 Cognito - 从图像选择器上传图像 - Swift 3
Amazon S3 Cognito - Upload image from image picker - Swift 3
我已成功将静态图片上传到 AWS 服务器。当我将它与 imagepicker 结合使用时,我遇到了一个奇怪的问题,因为即使我以不同的方式选择和命名它们,但仍将相同的图像上传到 AWS。代码如下:
internal func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : Any])
{
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
var imageUrl = info[UIImagePickerControllerReferenceURL] as? NSURL
let imageName = imageUrl?.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let photoURL = NSURL(fileURLWithPath: documentDirectory)
let localPath = photoURL.appendingPathComponent(imageName!)
print("image name : \(imageName)")
if !FileManager.default.fileExists(atPath: localPath!.path) {
do {
try UIImageJPEGRepresentation(image, 1.0)?.write(to: localPath!)
print("file saved")
//let imageData = NSData(contentsOf: localPath!)
//let finalURL = localPath!
//this is in swift 2; above 2 lines are its equivalent in swift3. I think the problem lies here
//let imageData = NSData(contentsOfFile: localPath)!
//imageURL = NSURL(fileURLWithPath: localPath)
}catch {
print("error saving file")
}
}
else {
print("file already exists")
}
self.dismiss(animated: true, completion: nil)
let credentialProvider = AWSCognitoCredentialsProvider(regionType: .USEast1, identityPoolId: "identity pool id")
let configuration = AWSServiceConfiguration(region: .APSoutheast1, credentialsProvider: credentialProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
//these are the static values I used that worked perfectly fine with separate images
//let localFileName = "Alerts_bg"
//let ext = "png"
//let remoteName = localFileName + "." + ext
//let imageURL = Bundle.main.url(forResource: localFileName, withExtension: ext)!
let transferManager = AWSS3TransferManager.default()
let uploadRequest = AWSS3TransferManagerUploadRequest()!
uploadRequest.bucket = "bucket"
let imageAWSName = "ios_" + NSUUID().uuidString + ".jpg"
uploadRequest.key = imageAWSName
uploadRequest.body = localPath! as URL
uploadRequest.contentType = "image/jpg"
print("req123 : \(uploadRequest)")
uploadRequest.uploadProgress = { (bytesSent, totalBytesSent, totalBytesExpectedToSend) -> Void in
DispatchQueue.main.async(execute: {
//self.amountUploaded = totalBytesSent // To show the updating data status in label.
//self.fileSize = totalBytesExpectedToSend
print("progress : \(totalBytesSent)/\(totalBytesExpectedToSend)")
})
}
transferManager.upload(uploadRequest).continueWith(executor: AWSExecutor.mainThread(), block: { (task:AWSTask<AnyObject>) -> Any? in
if let error = task.error {
print("Upload failed with error: (\(error.localizedDescription))")
}
if task.result != nil {
let s3URL = URL(string: "https://s3-ap-southeast-1.amazonaws.com/bucket/\(imageAWSName)")!
print("Uploaded to:\(s3URL)")
}
return nil
})
dismiss(animated:true, completion: nil) //5
}
我看过很多博客,例如 this and this,但这些都是 swift 的早期版本,我无法将其转换为 Swift 3 并正确地将 imagepicker 与 AWS 结合使用.
有人请帮忙。
实际上,当你这样做的时候:
let photoURL = NSURL(fileURLWithPath: documentDirectory)
let localPath = photoURL.appendingPathComponent(imageName!)
您正在将 localPath 创建为 URL
。
所以当你在做的时候:
let imageURL = NSURL(fileURLWithPath: localPath)
它给出了错误,因为 localPath 是 URL
而不是 String
。
这里可以直接用as:
let imageURL = localPath!
我找到了解决问题的方法:
let imageAWSName = "ios_" + NSUUID().uuidString + ".jpg"
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let photoURL = NSURL(fileURLWithPath: documentDirectory)
let localPath = photoURL.appendingPathComponent(imageAWSName)
if !FileManager.default.fileExists(atPath: localPath!.path) {
do {
try UIImageJPEGRepresentation(image, 1.0)?.write(to: localPath!)
print("file saved")
}catch {
print("error saving file")
}
}
else {
print("file already exists")
}
let credentialProvider = AWSCognitoCredentialsProvider(regionType: .USEast1, identityPoolId: “your identity pool id”)
let configuration = AWSServiceConfiguration(region: .APSoutheast1, credentialsProvider: credentialProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
let transferManager = AWSS3TransferManager.default()
let uploadRequest = AWSS3TransferManagerUploadRequest()!
let yourBucketName = “your bucket name”
uploadRequest.bucket = yourBucketName
uploadRequest.key = imageAWSName
uploadRequest.body = localPath! as URL
uploadRequest.contentType = "image/jpg"
uploadRequest.uploadProgress = { (bytesSent, totalBytesSent, totalBytesExpectedToSend) -> Void in
DispatchQueue.main.async(execute: {
//self.amountUploaded = totalBytesSent // To show the updating data status in label.
//self.fileSize = totalBytesExpectedToSend
print("progress : \(totalBytesSent)/\(totalBytesExpectedToSend)")
})
}
transferManager.upload(uploadRequest).continueWith(executor: AWSExecutor.mainThread(), block: { (task:AWSTask<AnyObject>) -> Any? in
if let error = task.error {
print("Upload failed with error: (\(error.localizedDescription))")
}
if task.result != nil {
let s3URL = URL(string: "https://s3-ap-southeast-1.amazonaws.com/\(yourBucketName)/\(imageAWSName)")!
print("Uploaded to:\(s3URL)")
}
return nil
})
self.picker.dismiss(animated: true, completion: nil)
确保 localPath 中使用的 imageAWSName 始终与我所做的不同。这是最主要的事情,否则即使您从选择器中选择不同的图像,AWS 也会多次保存相同的图像。
希望对以后的人有所帮助!
我已成功将静态图片上传到 AWS 服务器。当我将它与 imagepicker 结合使用时,我遇到了一个奇怪的问题,因为即使我以不同的方式选择和命名它们,但仍将相同的图像上传到 AWS。代码如下:
internal func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [String : Any])
{
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
var imageUrl = info[UIImagePickerControllerReferenceURL] as? NSURL
let imageName = imageUrl?.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let photoURL = NSURL(fileURLWithPath: documentDirectory)
let localPath = photoURL.appendingPathComponent(imageName!)
print("image name : \(imageName)")
if !FileManager.default.fileExists(atPath: localPath!.path) {
do {
try UIImageJPEGRepresentation(image, 1.0)?.write(to: localPath!)
print("file saved")
//let imageData = NSData(contentsOf: localPath!)
//let finalURL = localPath!
//this is in swift 2; above 2 lines are its equivalent in swift3. I think the problem lies here
//let imageData = NSData(contentsOfFile: localPath)!
//imageURL = NSURL(fileURLWithPath: localPath)
}catch {
print("error saving file")
}
}
else {
print("file already exists")
}
self.dismiss(animated: true, completion: nil)
let credentialProvider = AWSCognitoCredentialsProvider(regionType: .USEast1, identityPoolId: "identity pool id")
let configuration = AWSServiceConfiguration(region: .APSoutheast1, credentialsProvider: credentialProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
//these are the static values I used that worked perfectly fine with separate images
//let localFileName = "Alerts_bg"
//let ext = "png"
//let remoteName = localFileName + "." + ext
//let imageURL = Bundle.main.url(forResource: localFileName, withExtension: ext)!
let transferManager = AWSS3TransferManager.default()
let uploadRequest = AWSS3TransferManagerUploadRequest()!
uploadRequest.bucket = "bucket"
let imageAWSName = "ios_" + NSUUID().uuidString + ".jpg"
uploadRequest.key = imageAWSName
uploadRequest.body = localPath! as URL
uploadRequest.contentType = "image/jpg"
print("req123 : \(uploadRequest)")
uploadRequest.uploadProgress = { (bytesSent, totalBytesSent, totalBytesExpectedToSend) -> Void in
DispatchQueue.main.async(execute: {
//self.amountUploaded = totalBytesSent // To show the updating data status in label.
//self.fileSize = totalBytesExpectedToSend
print("progress : \(totalBytesSent)/\(totalBytesExpectedToSend)")
})
}
transferManager.upload(uploadRequest).continueWith(executor: AWSExecutor.mainThread(), block: { (task:AWSTask<AnyObject>) -> Any? in
if let error = task.error {
print("Upload failed with error: (\(error.localizedDescription))")
}
if task.result != nil {
let s3URL = URL(string: "https://s3-ap-southeast-1.amazonaws.com/bucket/\(imageAWSName)")!
print("Uploaded to:\(s3URL)")
}
return nil
})
dismiss(animated:true, completion: nil) //5
}
我看过很多博客,例如 this and this,但这些都是 swift 的早期版本,我无法将其转换为 Swift 3 并正确地将 imagepicker 与 AWS 结合使用. 有人请帮忙。
实际上,当你这样做的时候:
let photoURL = NSURL(fileURLWithPath: documentDirectory)
let localPath = photoURL.appendingPathComponent(imageName!)
您正在将 localPath 创建为 URL
。
所以当你在做的时候:
let imageURL = NSURL(fileURLWithPath: localPath)
它给出了错误,因为 localPath 是 URL
而不是 String
。
这里可以直接用as:
let imageURL = localPath!
我找到了解决问题的方法:
let imageAWSName = "ios_" + NSUUID().uuidString + ".jpg"
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let photoURL = NSURL(fileURLWithPath: documentDirectory)
let localPath = photoURL.appendingPathComponent(imageAWSName)
if !FileManager.default.fileExists(atPath: localPath!.path) {
do {
try UIImageJPEGRepresentation(image, 1.0)?.write(to: localPath!)
print("file saved")
}catch {
print("error saving file")
}
}
else {
print("file already exists")
}
let credentialProvider = AWSCognitoCredentialsProvider(regionType: .USEast1, identityPoolId: “your identity pool id”)
let configuration = AWSServiceConfiguration(region: .APSoutheast1, credentialsProvider: credentialProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
let transferManager = AWSS3TransferManager.default()
let uploadRequest = AWSS3TransferManagerUploadRequest()!
let yourBucketName = “your bucket name”
uploadRequest.bucket = yourBucketName
uploadRequest.key = imageAWSName
uploadRequest.body = localPath! as URL
uploadRequest.contentType = "image/jpg"
uploadRequest.uploadProgress = { (bytesSent, totalBytesSent, totalBytesExpectedToSend) -> Void in
DispatchQueue.main.async(execute: {
//self.amountUploaded = totalBytesSent // To show the updating data status in label.
//self.fileSize = totalBytesExpectedToSend
print("progress : \(totalBytesSent)/\(totalBytesExpectedToSend)")
})
}
transferManager.upload(uploadRequest).continueWith(executor: AWSExecutor.mainThread(), block: { (task:AWSTask<AnyObject>) -> Any? in
if let error = task.error {
print("Upload failed with error: (\(error.localizedDescription))")
}
if task.result != nil {
let s3URL = URL(string: "https://s3-ap-southeast-1.amazonaws.com/\(yourBucketName)/\(imageAWSName)")!
print("Uploaded to:\(s3URL)")
}
return nil
})
self.picker.dismiss(animated: true, completion: nil)
确保 localPath 中使用的 imageAWSName 始终与我所做的不同。这是最主要的事情,否则即使您从选择器中选择不同的图像,AWS 也会多次保存相同的图像。
希望对以后的人有所帮助!