AWS: DeveloperAuthenticatedIdentityProvider not firing IOS Swift - ios

I am trying to integrate S3 upload to upload a video file and tried Developer authenticated Identity method. Everything is configured as per the aws docs says.
DeveloperAuthenticatedIdentityProvider Class :
class DeveloperAuthenticatedIdentityProvider : AWSCognitoCredentialsProviderHelper {
override func token() -> AWSTask<NSString> {
//return AWSTask //with token and will set identityId
}
and then
let devAuth = DeveloperAuthenticatedIdentityProvider(regionType: COGNITO_REGION, identityPoolId: COGNITO_POOL_ID, useEnhancedFlow: true, identityProviderManager:nil)
let credentialsProvider =
AWSCognitoCredentialsProvider(regionType: COGNITO_REGION, identityProvider:devAuth)
let configuration =
AWSServiceConfiguration(region: S3_REGION, credentialsProvider:credentialsProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
after configuring these things tried to upload using AWSS3TransferManager
let transferManager = AWSS3TransferManager.default()
let uploadingFileURL = URL(fileURLWithPath: "your/file/path/myTestFile.txt")
let uploadRequest = AWSS3TransferManagerUploadRequest()
uploadRequest.bucket = "myBucket"
uploadRequest.key = "myTestFile.txt"
uploadRequest.body = uploadingFileURL
transferManager.upload(uploadRequest).continueWith(executor: AWSExecutor.mainThread(), block: { (task:AWSTask<AnyObject>) -> Any? in
if let error = task.error as? NSError {
if error.domain == AWSS3TransferManagerErrorDomain, let code = AWSS3TransferManagerErrorType(rawValue: error.code) {
switch code {
case .cancelled, .paused:
break
default:
print("Error uploading: \(uploadRequest.key) Error: \(error)")
}
} else {
print("Error uploading: \(uploadRequest.key) Error: \(error)")
}
return nil
}
let uploadOutput = task.result
print("Upload complete for: \(uploadRequest.key)")
return nil
})
Whenever I call Upload method it shows
[Error Domain=com.amazonaws.AWSCognitoIdentityErrorDomain Code=8
"(null)" UserInfo={__type=NotAuthorizedException,
message=Unauthenticated access is not supported for this identity
pool.}]
also DeveloperAuthenticatedIdentityProvider not getting fired
kindly please help.

When you using Developer authenticated identity for cognito identity provider you need not use
AWSS3TransferManager.default()
You need to register the AWSServiceConfiguration to the AWSS3TransferManager with a key.
AWSS3TransferManager.register(with: configuration!, forKey:
"KEY")
Try this way:
let devAuth = DeveloperAuthenticatedIdentityProvider(regionType: COGNITO_REGION, identityPoolId: COGNITO_POOL_ID, useEnhancedFlow: true, identityProviderManager:nil)
let credentialsProvider = AWSCognitoCredentialsProvider(regionType: COGNITO_REGION, identityProvider:devAuth)
let configuration = AWSServiceConfiguration(region: S3_REGION, credentialsProvider:credentialsProvider)
AWSS3TransferManager.register(with: configuration!, forKey: "YOUR_KEY")
//Start Upload
let uploadRequest = AWSS3TransferManagerUploadRequest()
//Set all properties to uploadRequest
AWSS3TransferManager.s3TransferManager(forKey: "YOUR_KEY").upload(uploadRequest!).continueWith(executor: AWSExecutor.mainThread(), block: { (task:AWSTask<AnyObject>) -> Any? in
// Do something with the response
if task.isCancelled {
print("Cancelled Upload")
}
else if (task.error != nil) {
print("Upload error --> \(task.error)")
}else{
print("Upload success!!! Be happy :)")
}
return task
})
Just try, I think it may work.

Related

AWS Transfer Utility uploads are slow and inconsistent in iOS

I have implemented the basic AWS transfer utility upload video (file) code in my app and this had been working for me flawlessly until recently the uploads got extremely slow and even stuck.
I tried changing many things in the AWS code like shifting from TransferUtilityUpload to TrasferUtility UploadUsing MultiPart, changing the AWSServiceConfiguration from AWSCognitoCredentialsProvider(using poolId & region) to AWSStaticCredentialsProvider (using Accesskey, secret key and region), enabling acceleration etc but nothing has helped to increase the upload speed. Apart from this, the uploads are very inconsistent. For example sometimes a 30sec video (size 180MB) gets uploaded in under 2 mins and then again same video takes more than 5 minutes/gets stuck in the same network (speed 150MBps or more)
Can someone please help me understand the issue and fix it?
Code snippets below.
Service Configuration
let credentialsProvider = AWSStaticCredentialsProvider(accessKey: "******", secretKey: "*****")
let configuration = AWSServiceConfiguration.init(region: AWSRegionType.USEast1, credentialsProvider: credentialsProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
AWS Upload function
private func uploadfile(fileSize: Int, fileUrl: URL, fileName: String, contenType: String, progress: progressBlock?, completion: completionBlock?) {
// Upload progress block
var previousUploadedBytes: Double = 0.0
let expression = AWSS3TransferUtilityMultiPartUploadExpression()
expression.progressBlock = {(task, awsProgress) in
if task.status == AWSS3TransferUtilityTransferStatusType.waiting {
task.cancel()
}
guard let uploadProgress = progress else { return }
DispatchQueue.main.async {
uploadProgress(awsProgress.fractionCompleted)
//CODE FOR UI UPDATES
//DO SOMETHING WITH THE PROGRESS
}
}
// Completion block
var completionHandler: AWSS3TransferUtilityMultiPartUploadCompletionHandlerBlock?
completionHandler = { (task, error) -> Void in
DispatchQueue.main.async(execute: {
if error == nil {
let url = AWSS3.default().configuration.endpoint.url
let publicURL : URL = (url?.appendingPathComponent(self.bucketName).appendingPathComponent(fileName))!
if let completionBlock = completion {
completionBlock(publicURL.absoluteString, nil)
}
} else {
if let completionBlock = completion {
completionBlock(nil, error)
}
}
})
}
//acceleration mode enabled
let serviceConfiguration = AWSServiceConfiguration(
region: .USEast1,
credentialsProvider: AWSServiceManager.default().defaultServiceConfiguration.credentialsProvider
)
let transferUtilityConfiguration = AWSS3TransferUtilityConfiguration()
transferUtilityConfiguration.isAccelerateModeEnabled = true
AWSS3TransferUtility.register(
with: serviceConfiguration!,
transferUtilityConfiguration: transferUtilityConfiguration,
forKey: "transfer-acceleration"
)
// Start uploading using AWSS3TransferUtility
let awsTransferUtility = AWSS3TransferUtility.default()
awsTransferUtility.uploadUsingMultiPart(fileURL: fileUrl, bucket: bucketName, key: fileName, contentType: contenType, expression: expression, completionHandler: completionHandler).continueWith { (task) -> Any? in
if let error = task.error {
UploadHelper.sharedInstance.showSSLError = false
if (error as NSError).code == -1001 {
DispatchQueue.main.async {
UploadHelper.sharedInstance.noOfRetries = 0
UploadHelper.sharedInstance.changeToRetryUpload() // internal code to call for retry
}
} else if (error as NSError).code == -1009 {
DispatchQueue.main.async {
UploadHelper.sharedInstance.noOfRetries = 0
UploadHelper.sharedInstance.changeToRetryUpload() // internal code to call for retry
}
} else if (error as NSError).code == -1003 {
DispatchQueue.main.async {
UploadHelper.sharedInstance.noOfRetries = 0
UploadHelper.sharedInstance.changeToRetryUpload() // internal code to call for retry
}
} else if (error as NSError).code == -1200 {
DispatchQueue.main.async {
UploadHelper.sharedInstance.noOfRetries = 0
UploadHelper.sharedInstance.changeToRetryUpload() // internal code to call for retry
UploadHelper.sharedInstance.showSSLError = true
}
}
}
if let _ = task.result {
// your uploadTask
}
return nil
}
}

Upload image to S3 with Amazon Educate Starter Account

I just want to upload an image to S3, but I am using AWS Educate Account and I'm trying since 4 hours to get this done and have ZERO ideas what isn't working correctly.
So I've set up everything on the AWS console and the bucket is public to EVERYONE + Region US West N.Virginia like it should be with AWS Educate Accounts.
So here is my code:
let accessKey = "accessKey"
let secretKey = "secretKey"
let credentialsProvider = AWSStaticCredentialsProvider(accessKey: accessKey, secretKey: secretKey)
let configuration = AWSServiceConfiguration(region: AWSRegionType.USEast1, credentialsProvider: credentialsProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
let transferUtility = AWSS3TransferUtility.default()
let bucketname = "bucketname"
let expression = AWSS3TransferUtilityUploadExpression()
transferUtility.uploadData(jpegData, bucket: bucketname, key: "myTransferUtilityUpload.jpg", contentType: "image/jpg", expression: expression) { (task, error) in
if let error = error {
print(error.localizedDescription)
}
if let response = task.response {
print(response)
}
}
Can anyone tell me what I do wrong?
I get this error message:
The operation couldn’t be completed.
(com.amazonaws.AWSS3TransferUtilityErrorDomain error 2.)
accessKey + secretKey I got from Account Details + AWS CLI on the 'Welcome to AWS Educate Starter Account' Dashboard and obviously the bucket name is the same name like in my console
EDIT:
if let jpegData = image.jpegData(compressionQuality: 0.7) {
let fileManager = FileManager.default
if let documentDirectory = fileManager.urls(for: .documentDirectory,
in: .userDomainMask).first {
var sourceFolderURL = documentDirectory.appendingPathComponent("image.jpg")
do {
try jpegData.write(to: sourceFolderURL)
} catch {
print(error.localizedDescription)
completionHandler(nil)
return
}
let accessKey = "-"
let secretKey = "-"
let bucketname = "-"
let credentialsProvider = AWSStaticCredentialsProvider(accessKey: accessKey, secretKey: secretKey)
let configuration = AWSServiceConfiguration(region: AWSRegionType.USEast1, credentialsProvider: credentialsProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
let uploadRequest = AWSS3TransferManagerUploadRequest()!
uploadRequest.body = sourceFolderURL
uploadRequest.key = "image.jpg"
uploadRequest.bucket = bucketname
uploadRequest.contentType = "image/jpeg"
uploadRequest.acl = .publicReadWrite
let transferManager = AWSS3TransferManager.default()
transferManager.upload(uploadRequest).continueWith { [weak self] (task) -> Any? in
if let error = task.error {
print("Upload failed with error: (\(error.localizedDescription))")
completionHandler(nil)
return nil
}
if task.result != nil {
let url = AWSS3.default().configuration.endpoint.url
let publicURL = url?.appendingPathComponent(uploadRequest.bucket!).appendingPathComponent(uploadRequest.key!)
if let absoluteString = publicURL?.absoluteString {
print("Uploaded to:\(absoluteString)")
completionHandler(nil)
}
}
completionHandler(nil)
return nil
}
}
}
I have uploaded an image to S3 bucket with the following code:
First, save the image to a temporary directory.
func uploadImageToS3(imageName:String, completion:#escaping (Bool) -> Void) {
let accessKey = "accessKey"
let secretKey = "secretKey"
let credentialsProvider = AWSStaticCredentialsProvider(accessKey: accessKey, secretKey: secretKey)
let configuration = AWSServiceConfiguration(region:AWSRegionType.APSoutheast2, credentialsProvider:credentialsProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
let S3BucketName = "bucketname"
let uploadRequest = AWSS3TransferManagerUploadRequest()!
uploadRequest.body = self.getImageURLWithName(imageName:imageName)
uploadRequest.key = "\(imageName)"
uploadRequest.bucket = S3BucketName
uploadRequest.contentType = "image/jpeg"
//You can specify private or public here
uploadRequest.acl = .private
let transferManager = AWSS3TransferManager.default()
transferManager.upload(uploadRequest).continueWith { [weak self] (task) -> Any? in
ProgressIndicatorHelper.hideGlobalHUD()
if let error = task.error {
print("Upload failed with error: (\(error.localizedDescription))")
completion(false)
}
if task.result != nil {
let url = AWSS3.default().configuration.endpoint.url
let publicURL = url?.appendingPathComponent(uploadRequest.bucket!).appendingPathComponent(uploadRequest.key!)
if let absoluteString = publicURL?.absoluteString {
print("Uploaded to:\(absoluteString)")
completion(true)
}
}
return nil
}
}
For getting image from Path following code I have used:
func getImageURLWithName(imageName:String) -> URL {
var sourceImageURL: URL!
let fileManager = FileManager.default
if let documentDirectory = fileManager.urls(for: .documentDirectory,
in: .userDomainMask).first {
var sourceFolderURL:URL!
sourceFolderURL = documentDirectory.appendingPathComponent("YourTempFolder")
sourceImageURL = sourceFolderURL.appendingPathComponent(imageName)
}
return sourceImageURL
}
Hope this helps.
Moreover: Right now I don't think you can directly upload image from memory.
I searched for it. Following are links for same:
https://github.com/aws-amplify/aws-sdk-ios/issues/42
How to upload a UIImage to S3 with AWS iOS SDK v2
Let me know if you find any error.
Maybe it's a policy issue?
Try attaching this policy to your bucket (bucket policies)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::mybucketname/*"
]
}
]
}

Error uploading file to Amazon S3

I want t upload a csv file from my iOS App (written in Swift) to my amazon S3 bucket. To do this I'm using following code:
//Create
let fileName = "Export.csv"
let path = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(fileName)
csvText = CreateCSVAccount()
do {
try csvText.write(to: path!, atomically: true, encoding: String.Encoding.utf32BigEndian)
//Prepare Upload
let uploadingFileURL = path
let uploadRequest = AWSS3TransferManagerUploadRequest()
let Bucketname = "mybucket/CSV"
uploadRequest?.bucket = Bucketname
uploadRequest?.key = "mycsvfile.csv"
uploadRequest?.body = uploadingFileURL!
//Upload File
transferManager.upload(uploadRequest!).continueWith(executor: AWSExecutor.mainThread(), block: { (task:AWSTask<AnyObject>) -> Any? in
if let error = task.error as NSError? {
if error.domain == AWSS3TransferManagerErrorDomain, let code = AWSS3TransferManagerErrorType(rawValue: error.code) {
switch code {
case .cancelled, .paused:
break
default:
print("Error Contact uploading: \(String(describing: uploadRequest?.key)) Error: \(error)")
}
} else {
print("Error Contact uploading: \(String(describing: uploadRequest?.key)) Error: \(error)")
}
return nil
}
let uploadOutput = task.result
print("Upload complete for: \(String(describing: uploadRequest?.key))")
print("uploadOutput: \(String(describing: uploadOutput))")
return nil
})
} catch {
print("Failed to create file")
print("\(error)")
}
The problem is sometimes it works and sometimes I'm receiving the following error:
Message=You did not provide the number of bytes specified by the Content-Length HTTP header, NumberBytesExpected=412, Code=IncompleteBody, RequestId=075D1F5B0A377E89
Can somebody please help me?
Thank you very much in advance!
Add the contentLength header to your request.
That is:
uploadRequest?.contentLength = 1234
where 1234 is an NSNumber representing the number of bytes in body

Returning ENOTCONN Error

Im trying to upload image to Aws S3 bucket. I tried to follow a tutorial and I'm getting a error saying "Returning ENOTCONN because protocol has not yet been set up." I'm new to swift and I'm not able to understand why the error is occurring also.My code for S3 upload is as follows:
let uploadRequest = AWSS3TransferManagerUploadRequest()
uploadRequest?.body = url!
uploadRequest?.key = remoteFileName
uploadRequest?.bucket = S3BucketName
uploadRequest?.contentType = "image/" + ext
let transferManager = AWSS3TransferManager.default()
// Perform Upload
transferManager.upload(uploadRequest!).continueWith(block: { (task:AWSTask<AnyObject>) -> AnyObject! in
if let error = task.error{
print("error \(error.localizedDescription)")
}
if task.result != nil {
let url = AWSS3.default().configuration.endpoint.url
let publicURL = url?.appendingPathComponent((uploadRequest?.bucket!)!).appendingPathComponent((uploadRequest?.key!)!)
print("Uploaded to:\(publicURL)")
}
return nil
})
My S3 is in ap-south-1 and cognito pool id in us-west-2. I guess thats creating the problem.Is there a way to fix the issue without creating another bucket in us-west-2.
I get the following error:
You want the bucket policy to be somewhat like this if the cognito pool is not set up for authentication: Notice Principal and Action values
Also, is there any particular reason you're using AWSS3TransferManagerUploadRequest? If the policy doesn't resolve your issue, you can use the following code for AWSS3TransferUtilityUploadExpression which sends your data in chunks asynchronously.
let expression = AWSS3TransferUtilityUploadExpression()
expression.progressBlock = progressBlock
transferUtility.uploadData(UIImagePNGRepresentation(imageNew!)!,
bucket: "bucket-name",
key: (imgName.removeWhitespace()),
contentType: "image/png",
expression: expression,
completionHandler: completionHandler).continueWith { (task) -> AnyObject! in
if let error = task.error {
print("Error: \(error.localizedDescription)")
}
if let _ = task.result {
print("Upload Starting!")
// Do something with uploadTask.
}
return nil;
}

Swift upload to s3 bucket does not end

I'm trying to upload an image to a bucket. The connection is made, the upload apparently starts but does not progress. The permissions on the server I consider to be correct, because an android app is able to upload.
In my appdelegate I have this:
let credentialsProvider = AWSCognitoCredentialsProvider(regionType: AWSRegionType.USEast1, identityPoolId: "us-east-1:XXXXXX-XXXX-XXXX-XXXX-XXXX”, unauthRoleArn: "arn:aws:iam::XXXXX:role/Cognito_mybucketUnauth_Role", authRoleArn: "arn:aws:iam::XXXXX:role/Cognito_mybucketAuth_Role", identityProviderManager: nil)
let configuration = AWSServiceConfiguration(region: AWSRegionType.USEast1, credentialsProvider: credentialsProvider)
AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration
And this to get the image and upload
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]){
//getting details of image
let uploadFileURL = info[UIImagePickerControllerReferenceURL] as! NSURL
let imageName = uploadFileURL.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first! as String
// getting local path
let localPath = (documentDirectory as NSString).stringByAppendingPathComponent(imageName!)
//getting actual image
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
let data = UIImagePNGRepresentation(image)
data!.writeToFile(localPath, atomically: true)
let imageData = NSData(contentsOfFile: localPath)!
imageURL = NSURL(fileURLWithPath: localPath)
CampoImagem.image = image
picker.dismissViewControllerAnimated(true, completion: nil)
uploadImage()
}
func uploadImage(){
//defining bucket and upload file name
let S3BucketName: String = “mybucket"
let S3UploadKeyName: String = "profile/testImage.jpg"
let expression = AWSS3TransferUtilityUploadExpression()
/*expression.uploadProgress = {(task: AWSS3TransferUtilityTask, bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) in
dispatch_async(dispatch_get_main_queue(), {
let progress = Float(totalBytesSent) / Float(totalBytesExpectedToSend)
print("Progress is: \(progress)")
})
}*/
self.uploadCompletionHandler = { (task, error) -> Void in
dispatch_async(dispatch_get_main_queue(), {
if ((error) != nil){
print("Failed with error")
print("Error: \(error!)");
}
else{
print("Sucess")
}
})
}
let transferUtility = AWSS3TransferUtility.defaultS3TransferUtility()
transferUtility.uploadFile(imageURL, bucket: S3BucketName, key: S3UploadKeyName, contentType: "image/jpeg", expression: expression, completionHander: uploadCompletionHandler).continueWithBlock { (task) -> AnyObject! in
if let error = task.error {
print("Error: \(error.localizedDescription)")
}
if let exception = task.exception {
print("Exception: \(exception.description)")
}
if let _ = task.result {
print("Upload Starting!")
}
return nil;
}
}
Print: Upload Starting!
I suspect it's something when ID and permission to complete the upload with aws, but I think if it was the upload would not start, correct?
How can I solve this?
Please check this code you can also check by adding credentials in this demo project
https://github.com/awslabs/aws-sdk-ios-samples/blob/master/S3TransferUtility-Sample/Swift/S3BackgroundTransferSampleSwift/FirstViewController.swift

Resources