Reputation: 2773
func startUploadingImage() {
var localFileName:String?
// Issue #1: This here causes a segmentation fault 11 - Worked completely fine in swift 2.3
if let imageToUploadUrl = selectedImageUrl {
let phResult = PHAsset.fetchAssets(withALAssetURLs: [imageToUploadUrl], options: nil)
localFileName = phResult.firstObject?.fileManager
}
if localFileName == nil {
return
}
// Configure AWS Cognito Credentials
let myIdentityPoolId = ""
let credentialsProvider:AWSCognitoCredentialsProvider = AWSCognitoCredentialsProvider(regionType:AWSRegionType.euWest1, identityPoolId: myIdentityPoolId)
let configuration = AWSServiceConfiguration(region:AWSRegionType.euWest1, credentialsProvider:credentialsProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
// Set up AWS Transfer Manager Request
let S3BucketName = ""
let remoteName = localFileName!
print(remoteName)
let uploadRequest = AWSS3TransferManagerUploadRequest()
uploadRequest?.body = generateImageUrl(remoteName)
uploadRequest?.key = remoteName
uploadRequest?.bucket = S3BucketName
uploadRequest?.contentType = "image/jpeg"
let transferManager = AWSS3TransferManager.default()
// Perform file upload
// #issue 2: Here I recieve an error of ambiguous reference to member 'continue'
transferManager.upload(uploadRequest).continue {
task -> AnyObject! in
if let error = task.error {
print("Upload failed with error: (\(error.localizedDescription))")
}
if let exception = task.exception {
print("Upload failed with exception (\(exception))")
}
if task.result != nil {
let s3URL = URL(string: "https://s3.amazonaws.com/\(S3BucketName)/\(uploadRequest.key!)")!
print("Uploaded to:\n\(s3URL)")
// Remove locally stored file
self.remoteImageWithUrl(uploadRequest.key!)
DispatchQueue.main.async {
self.submitImageToDatabase("https://s3-eu-west-1.amazonaws.com/\(S3BucketName)/\(uploadRequest.key!)")
}
}
else {
print("Unexpected empty result.")
}
return nil
}
}
Had a look at the AWS docs but can't seem to find nothing that's been updated since swift 3 (at least not that I can find). Most of it is written in Obj-c anyway which doesn't help.
I also seem to have the issues No such Module 'AWSS3'
and No such Module 'AWSCore'
even though they run fine when the project is built and i can cmd click to see the files.
Upvotes: 2
Views: 1829
Reputation: 2332
We should use AWSS3TransferUtility now because AWSS3TransferManagerUploadRequest is deprecated, here is the jpeg upload function in Swift 4.2 but it can be easily changed for any data type:
func uploadS3(image: UIImage,
name: String,
progressHandler: @escaping (Progress) -> Void,
completionHandler: @escaping (Error?) -> Void) {
guard let data = UIImageJPEGRepresentation(image, Constants.uploadImageQuality) else {
DispatchQueue.main.async {
completionHandler(NetErrors.imageFormatError) // Replace your error
}
return
}
let credentialsProvider = AWSStaticCredentialsProvider(accessKey: Constants.accessKeyS3, secretKey: Constants.secretKeyS3)
let configuration = AWSServiceConfiguration(region: Constants.regionS3, credentialsProvider: credentialsProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
let expression = AWSS3TransferUtilityUploadExpression()
expression.progressBlock = { task, progress in
DispatchQueue.main.async {
progressHandler(progress)
}
}
AWSS3TransferUtility.default().uploadData(
data,
bucket: Constants.bucketS3,
key: name,
contentType: "image/jpg",
expression: expression) { task, error in
DispatchQueue.main.async {
completionHandler(error)
}
print("Success")
}.continueWith { task -> AnyObject? in
if let error = task.error {
DispatchQueue.main.async {
completionHandler(error)
}
}
return nil
}
}
Do not forget to define or change Constants in the code. If you don't want to give public access, you should also define a user in IAM, and put this code in your bucket policy:
{
"Version": "2012-10-17",
"Id": "S3AccessPolicy",
"Statement": [
{
"Sid": "GiveAppPutAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:user/YOUR_USER"
},
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::YOUR_BUCKET/*"
}
]
}
Upvotes: 0
Reputation: 2505
func uploadButtonPressed(_ sender: AnyObject) {
if documentImageView.image == nil {
// Do something to wake up user :)
} else {
let image = documentImageView.image!
let fileManager = FileManager.default
let path = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent("\(imageName!).jpeg")
let imageData = UIImageJPEGRepresentation(image, 0.99)
fileManager.createFile(atPath: path as String, contents: imageData, attributes: nil)
let fileUrl = NSURL(fileURLWithPath: path)
var uploadRequest = AWSS3TransferManagerUploadRequest()
uploadRequest?.bucket = "BucketName"
uploadRequest?.key = "key.jpeg"
uploadRequest?.contentType = "image/jpeg"
uploadRequest?.body = fileUrl as URL!
uploadRequest?.serverSideEncryption = AWSS3ServerSideEncryption.awsKms
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
})
}
let transferManager = AWSS3TransferManager.default()
transferManager?.upload(uploadRequest).continue(with: AWSExecutor.mainThread(), withSuccessBlock: { (taskk: AWSTask) -> Any? in
if taskk.error != nil {
// Error.
} else {
// Do something with your result.
}
return nil
})
}
}
This is the complete code to upload an image to Amazon S3 written in swift 3 . TO configure your cognate identity pool add following code in app delegate.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
customiseAppearance()
let credentialsProvider =AWSCognitoCredentialsProvider(regionType:"YOUR REGION",identityPoolId:"YOUR POOL ID")
let configuration = AWSServiceConfiguration(region:"YOUR REGION", credentialsProvider:credentialsProvider)
AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration
return true
}
Let me answer to this error No such Module 'AWSS3' and No such Module 'AWSCore' , Check whether you added the AWSS3 framework and AWSCore framework in bridging header file like
#import <AWSCore/AWSCore.h>
Thanks!!
Upvotes: 5
Reputation: 5821
Update cocoapods to 1.0.0 version
gem list | grep cocoa
cocoapods (1.0.0)
Upvotes: 0