We have an S3 bucket in both in EUCentral1 and SAEast1 and can use download/upload tasks on ios client. (9.2 and 10.2.1)
However, one particular test device (ios 9.2) is being denied 100% of her trials to upload a file to either of the storages. The file upload task reports progress from 0% to 100% and as the last action expected to give the success message, instead here is the error message we get. (Other 5 real devices work ok, either 9.2 or 10.2.1, simulator 9.2 works ok)
Error: com.amazonaws.AWSS3TransferUtilityErrorDomain Error
Domain=com.amazonaws.AWSS3TransferUtilityErrorDomain
Code=2
"(null)"
UserInfo={Server=AmazonS3,
Transfer-Encoding=Identity,
Connection=close,
Content-Type=application/xml,
Date=Sun, 26 Mar 2017 00:53:24 GMT,
x-amz-request-id=88220F9EB635AC88,
x-amz-id-2=sNk62wUmnw0/xtURPcMEKtN4vMWghv8pveYWDhGOy7UM+uuXDSxP9dGkql5a+kOaDBgDyuFkED0=}
I have confirmed we can get keys from the developer custom authenticator and successfully pass to the ios AWS.
Info file has EUCentral1 configurations and AppDelegate has the below config:
swift
let devAuth = CustomProvider(regionType: .EUCentral1, identityPoolId: POOLID, useEnhancedFlow: true, identityProviderManager:nil);
let credentialsProvider = AWSCognitoCredentialsProvider(regionType: .EUCentral1, identityProvider:devAuth)
let configuration = AWSServiceConfiguration(region: .EUCentral1, credentialsProvider:credentialsProvider)
credentialsProvider.getIdentityId();
AWSServiceManager.default().defaultServiceConfiguration = configuration
````swift
PREFIX = "https://s3.eu-central-1.amazonaws.com/(BUCKET)/"
// also, PREFIX = "https://s3-ap-southeast-1.amazonaws.com/(BUCKET)/"
let fileURL = URL(fileURLWithPath: localPath);
let transferUtility = AWSS3TransferUtility.default()
transferUtility.configuration.timeoutIntervalForRequest = 120
transferUtility.configuration.timeoutIntervalForResource = 7200
let expression = AWSS3TransferUtilityUploadExpression()
for metaKey in meta.keys {
expression.setValue(meta[metaKey], forRequestParameter: metaKey);
}
expression.progressBlock = { (task:AWSS3TransferUtilityTask, progress:Progress) in
print("upload progress: (progress.fractionCompleted)");
}
}
remoteURL = URL(string: remotePath, relativeTo: PREFIX);
transferUtility.uploadFile(fileURL,
bucket: BUCKET,
key: remotePath,
contentType: "audio/mp4",
expression: expression,
completionHandler: self.completionHandler)
.continueWith(block: startHandler);
````
Just in case,
````swift
final class CustomProvider: AWSCognitoCredentialsProviderHelper {
override func token() -> AWSTask<NSString> {
...sth.sth...
self.identityId = keyId
return AWSTask(result: NSString(string: keyToken));
}
````
Library ver:
pod frameworks:
Using AWSCore (2.5.2)
Using AWSS3 (2.5.2)
I have contacted AWS Support. They have given feedback about the issue.
This is the clock sync issue. Your timezone should match your mobile device's time.
Otherwise S3 (and also other AWS services) will deny the request.
I am having the same issue . Please help , even the timezone is correct in the mobile device , the progress goes till 1 , but in the end the request goes in error block.
All devices and simulator are having this error . ios 10+.
AWSS3TransferUtilityUploadExpression *expression = [AWSS3TransferUtilityUploadExpression new];
expression.progressBlock = ^(AWSS3TransferUtilityTask *task, NSProgress *progress) {
dispatch_async(dispatch_get_main_queue(), ^{
// Do something e.g. Update a progress bar.
NSLog(@"Here 1 %@",progress);
});
};
AWSS3TransferUtilityUploadCompletionHandlerBlock completionHandler = ^(AWSS3TransferUtilityUploadTask *task, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
// Do something e.g. Alert a user for transfer completion.
// On failed uploads, `error` contains the error object.
NSLog(@"Here 0 %@",error); -> always coming here......
});
};
@try {
AWSS3TransferUtility *transferUtility = [AWSS3TransferUtility defaultS3TransferUtility];
[[transferUtility uploadData:data
bucket:BucketName
key:@"IOSUpload"
contentType:@"video/quicktime" expression:expression completionHandler:completionHandler] continueWithBlock:^id(AWSTask *task){
NSLog(@"here - 2 %@",task.result);
if (task.error) {
NSLog(@"Error: %@", task.error);
}
if (task.result) {
AWSS3TransferUtilityUploadTask *uploadTask = task.result;
NSLog(@"Here - 1");
// Do something with uploadTask.
}
return nil;
}];
} @catch (NSException *exception) {
}
Did you try to create temporary URL? That may work. In our case, we could not have created temporary URL due to large file uploadings (temp URLs have 60 minutes of life time)
After download the sample App . I found out the error .
I needed to add some keys in info.plist file which is not mentioned in their documentation. (ignore "." in code)
<.key.>AWS<./key.>
<.dict.>
<.key.>CredentialsProvider<./key.>
<.dict.>
<.key.>CognitoIdentity<./key.>
<.dict.>
<.key.>Default<./key.>
<.dict.>
<.key.>PoolId<./key.>
<.string.>yourPoolID<./string.>
<.key.>Region<./key.>
<.string.>AWSYourregion<./string.>
<./dict.>
<./dict.>
<./dict.>
<.key.>S3TransferUtility<./key.>
<.dict.>
<.key.>Default<./key.>
<.dict.>
<.key.>Region<./key.>
<.string.>AWSYourregion<./string.>
<./dict.>
<./dict.>
<./dict.>
As i added these. It started working. Hope this helps someone.
I know this is an old question, however it's better to write my situation and solution.
In my iOS (Swift) project, I was trying to upload a picture after login (using Cognito) and I got this error:
Error Domain=com.amazonaws.AWSS3TransferUtilityErrorDomain Code=2 "(null)"
Everything seemed well on code below:
transferUtility.uploadData(
data,
key: "my-picture.png",
contentType: "image/png",
expression: expression,
completionHandler: completionHandler).continueWith { (task) -> AnyObject? in
if let error = task.error {
print("Error: \(error.localizedDescription)")
DispatchQueue.main.async {
print("Error on upload: \(error.localizedDescription)")
}
}
if let _ = task.result {
DispatchQueue.main.async {
print("Upload Starting!")
}
}
return nil;
}
The solution is on AWS Amplify Storage documentation. As stated there, I should have written the key value like
key: "private/{user_identity_id}/my-picture.png"
Maybe, it will help anybody in the future.
@ilkayaktas Thanks for your suggestion. I read the documentation before coming here but it was not clear from it :)
I am facing the same issue but the strange thing is that I am able to download and use the file and some time it gives me this error.
I know this is an old question, however it's better to write my situation and solution.
In my iOS (Swift) project, I was trying to upload a picture after login (using Cognito) and I got this error:Error Domain=com.amazonaws.AWSS3TransferUtilityErrorDomain Code=2 "(null)"Everything seemed well on code below:
transferUtility.uploadData( data, key: "my-picture.png", contentType: "image/png", expression: expression, completionHandler: completionHandler).continueWith { (task) -> AnyObject? in if let error = task.error { print("Error: \(error.localizedDescription)") DispatchQueue.main.async { print("Error on upload: \(error.localizedDescription)") } } if let _ = task.result { DispatchQueue.main.async { print("Upload Starting!") } } return nil; }The solution is on AWS Amplify Storage documentation. As stated there, I should have written the key value like
key: "private/{user_identity_id}/my-picture.png"Maybe, it will help anybody in the future.
Can you please explain?
Most helpful comment
I know this is an old question, however it's better to write my situation and solution.
In my iOS (Swift) project, I was trying to upload a picture after login (using Cognito) and I got this error:
Everything seemed well on code below:
The solution is on AWS Amplify Storage documentation. As stated there, I should have written the key value like
key: "private/{user_identity_id}/my-picture.png"Maybe, it will help anybody in the future.