AWS iOS SDK v2 Files Upload to S3 issue - ios

I am trying to upload images to the S3, and for files that are less than 2 mb, it is ok, but for more than 2 mb, server return Code=-1001 "The request timed out.". Could someone explain how it is possible to handle this problem?
Code example below:
AWSS3 *s3 = [[AWSS3 alloc] initWithConfiguration:configuration];
AWSS3PutObjectRequest *logFile = [AWSS3PutObjectRequest new];
logFile.bucket = bucket;
logFile.key = path;
logFile.contentType = [self contentTypeForImageData:self.userPicture];
logFile.body = self.userPicture;
logFile.contentLength = [NSNumber numberWithInteger:[self.userPicture length]];
[[s3 putObject:logFile] continueWithBlock:^id(BFTask *task) {
NSLog(#"Amazon error : %#", [task error]);
return nil;
}];

When using initWithConfiguration:, you must manually retain a strong reference to an instance of AWSS3. One way to accomplish this is to make it a property. Using defaultS3 eliminates the need for this since the AWSS3 class retains the strong reference to the default service client for you.
Hope this helps,

Related

Upload files to s3 AWSCognitoCredentialsProvider ios

I try to upload file to s3 and I always got next error message
2015-08-05 14:35:53.931 BellyBuds[47981:2189296] Upload failed: [Error
Domain=com.amazonaws.AWSS3ErrorDomain Code=0 "The operation couldn’t
be completed. (com.amazonaws.AWSS3ErrorDomain error 0.)"
UserInfo=0x7fd40a40d8f0
{HostId=wo/bHFvnQjGuiLic3IhL+jicVfeIcuR6M4HXz/nB9WRt/T09h16bbR77nkqKngzj,
Bucket=bbbname, Endpoint=bbstagemusic.s3.amazonaws.com,
Message=The bucket you are attempting to access must be addressed
using the specified endpoint. Please send all future requests to this
endpoint., Code=PermanentRedirect, RequestId=6D250A718C640210}]
AWSCognitoCredentialsProvider *credProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1
identityId:[params valueForKey:#"IdentityId"]
identityPoolId:[params valueForKey:#"IdentityPoolId"]
logins:#{#"cognito-identity.amazonaws.com": params[#"Token"]}];
//credProvider.logins = #{ #(AWSCognitoLoginProviderKeyLoginWithAmazon): params[#"Token"] };
AWSServiceConfiguration *serviceConfiguration = [[AWSServiceConfiguration alloc]initWithRegion:AWSRegionUSEast1 credentialsProvider:credProvider];
AWSS3TransferManagerUploadRequest *uploadRequest = [AWSS3TransferManagerUploadRequest new];
uploadRequest.body = [NSURL fileURLWithPath:[BBFileManager getRecordingList][0]];
uploadRequest.key = [[BBFileManager getRecordingList][0] lastPathComponent];
uploadRequest.bucket = #"bbbucket";
AWSServiceManager *serv = [AWSServiceManager defaultServiceManager];
serv.defaultServiceConfiguration = serviceConfiguration;
[AWSS3TransferManager registerS3TransferManagerWithConfiguration:serviceConfiguration forKey:#"transferKey"];
[[[AWSS3TransferManager S3TransferManagerForKey:#"transferKey"] upload:uploadRequest] continueWithBlock:^id (AWSTask *task) {
return nil;
}];
I use correct data and set right region. I try use other regions and make other stuff, but this not be helpful. I always got errors related to regions and endpoint. What I do wrong?
I've found the problem!
uploadRequest.key = [[BBFileManager getRecordingList][0] lastPathComponent];
property uploadRequest.key should contain future file path for example, if future file will be located at /bbucketname/music/IdentityId/file.mp3, value of the key should be music/IdentityId/file.mp3

S3TransferManager not able to save file/data on S3GetObjectRequest targetedFilePath in ios

I am an iOS developer using Amazon S3 to upload and download the data. I successfully uploaded many image files, but when I am trying to download those all files, I am not able to save data or file on targeted path of S3GetObjectRequest. I am requesting object through the S3TransferManager.
Below is my code
- (void)listObjects:(id)sender {
self.collection = [[NSMutableArray alloc] init];
s3Client = [[AmazonS3Client alloc] initWithAccessKey:ACCESS_KEY_ID withSecretKey:SECRET_KEY];
#try {
S3ListObjectsRequest *req = [[S3ListObjectsRequest alloc] initWithName:AMAZON_BUCKET_NAME];
req.prefix = #"arvinds/8/";
//req.prefix = [NSString stringWithFormat:#"%#", self.appUser.userEmail];
S3ListObjectsResponse *resp = [s3Client listObjects:req];
NSMutableArray* objectSummaries = resp.listObjectsResult.objectSummaries;
for (int x = 0; x < [objectSummaries count]; x++) {
NSLog(#"objectSummaries: %#",[objectSummaries objectAtIndex:x]);
S3ObjectSummary *s3Object = [objectSummaries objectAtIndex:x];
NSString *downloadingFilePath = [[NSTemporaryDirectory() stringByAppendingPathComponent:#"download"] stringByAppendingPathComponent:s3Object.key];
NSURL *downloadingFileURL = [NSURL fileURLWithPath:downloadingFilePath];
NSLog(#"downloadingFilePath--- %#",downloadingFilePath);
if ([[NSFileManager defaultManager] fileExistsAtPath:downloadingFilePath]) {
[self.collection addObject:downloadingFileURL];
} else {
[self.collection addObject:downloadingFileURL];
S3GetObjectRequest *getObj = [[S3GetObjectRequest new] initWithKey:s3Object.key withBucket:AMAZON_BUCKET_NAME];
getObj.targetFilePath = downloadingFilePath;
getObj.delegate = self;
[self download:getObj];// Start downloding image and write in default folder
}
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.GalleryCollectionView reloadData];
//[self downloadAllRequestObject];
});
}
#catch (NSException *exception) {
NSLog(#"Cannot list S3 %#",exception);
}
}
// Above code is for access all the objects stored on Amazon S3 server.
// Below code is for S3TransferManager request
- (void)download:(S3GetObjectRequest *)downloadRequest {
S3TransferManager *transferManager = [S3TransferManager new];
transferManager.s3 = s3Client;
transferManager.delegate = self;
[transferManager download:downloadRequest];
}
When executing this, it is not saving data on the target path.
- download: is an asynchronous method and returns immediately. Since you are not retaining a strong reference to an instance of S3TransferManager, it can be released before the download completes. You need to keep a strong reference to transferManager.
Please note that you are using a deprecated version of the AWS SDK. It may be worthwhile to migrate to the version 2 of the AWS Mobile SDK for iOS. With the latest version of the SDK, you do not need to worry about the memory retention issue you are encountering.

AWS iOS v2 Video uploading issue

After using AWS SDK for iOS v1 i was using [S3PutObjectRequest stream] property to upload video files to the s3 server.With new version of the AWS SDK for the IOS such property was removed. I found out that new version has few Classes that can handle it such as [AWSKinesis] am i right are this classes are suitable for uploading video to the S3 server?
If yes could someone provide some examples please.
You should use AWSS3TransferManager for uploading movies to your S3 bucket. This sample app demonstrates how to use the transfer manager.
self.s3 = [[AmazonS3Client alloc] initWithAccessKey:ACCESS_KEY_ID withSecretKey:SECRET_KEY];
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfFile:tempPath options:nil error:&error];
S3PutObjectRequest *por = [[S3PutObjectRequest alloc] initWithKey:#"Video Name"
inBucket:#"BucketName"];
//por.contentType = #"image/jpeg";
por.contentType = #"video/quicktime";
por.data = data;
por.delegate = self;
start = [NSDate date];
[self.s3 putObject:por];
Successfully uploaded then below method will call:
-(void)request:(AmazonServiceRequest *)request didCompleteWithResponse: (AmazonServiceResponse *)response
Failed to upload then below method will call:
-(void)request:(AmazonServiceRequest *)request didFailWithError:(NSError *)error
For people that what to use AWSKinesis lib is available nice tutorial.
http://docs.aws.amazon.com/mobile/sdkforios/developerguide/kinesis.html

Amazon S3 iOS SDK v2 Upload with AWSAccessKeyId:Signature

I'm trying to upload file on S3 bucket and device is getting access information from another server (AWSAccessKeyId and Signature). Is it possible to upload file with AWS iOS SDK v2? If not are there any chances to use another approach possible for iOS (eg. generate Pre-Signed URL and do the http post/put)?
Right now I'm using this approach, but it's for access_key/access_secret:
AWSStaticCredentialsProvider *credentialsProvider = [AWSStaticCredentialsProvider credentialsWithAccessKey:awsAccessKey secretKey:awsSecretKey];
AWSServiceConfiguration *configuration = [AWSServiceConfiguration configurationWithRegion:AWSRegionUSEast1 credentialsProvider:credentialsProvider];
[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
AWSS3 *transferManager = [[AWSS3 alloc] initWithConfiguration:configuration];
AWSS3PutObjectRequest *getLog = [[AWSS3PutObjectRequest alloc] init];
getLog.bucket = awsS3Bucket;
getLog.key = awsS3FileNameString;
getLog.contentType = #"text/plain";
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *fileName = [documentsDirectory stringByAppendingPathComponent:logFileName];
long long fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:fileName error:nil][NSFileSize] longLongValue];
getLog.body = [NSURL fileURLWithPath:fileName];
getLog.contentLength = [NSNumber numberWithUnsignedLongLong:fileSize];
[[transferManager putObject:getLog] continueWithBlock:^id(BFTask *task) {
if(task.error)
{
NSLog(#"Error: %#",task.error);
}
else
{
NSLog(#"Got here: %#", task.result);
}
return nil;
}];
I'll be grateful for any ideas.
I recommend the following approach:
Generate the access key, secret key, and session token on your server. You have many language options including Java, .NET, PHP, Ruby, Python, and Node.js.
Implement your own credentials provider by conforming to AWSCredentialsProvider. This credentials provider should:
Retrieve the access key, secret key, and session key from your server.
Persist them until they expire.
Return the credentials when requested.
If they are expired, re-retrieve them from your server.
Calling refresh also should initiate the credentials retrieval process.
Assign your credentials provider to defaultServiceConfiguration or pass it to initWithConfiguration:.
As a side note, when using initWithConfiguration:, you need to manually retain a strong reference to an instance of AWSS3. Using defaultS3 will eliminate the need for this.
Hope this helps,

ios upload file to amazon s3

I am working on an ios app that needs to be able to upload files to amazon s3 but I am having some issues. The function manages to create the correct key or path within the s3 bucket but the file itself does not upload into it. below is the code for 1 of the options i have tried
if (self.s3 == nil) {
self.s3 = [[AmazonS3Client alloc] initWithAccessKey:[Config getS3Key] withSecretKey:[Config getS3Secret]] ;
}
[self performSelectorInBackground:#selector(processBackgroundThreadUploadInBackground:)
withObject:params];
}
- (void)processBackgroundThreadUploadInBackground:(NSMutableDictionary *)params
{
S3PutObjectRequest *por = [[S3PutObjectRequest alloc] initWithKey:#"staging/videos/" inBucket:#"aaa.aaaaa.com"];
por.contentType = #"video/mp4";
por.data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[params valueForKey:#"takeurl"]]];
// por.contentType = #"image/png";
// por.data = [params valueForKey:#"takeimage"];
S3PutObjectResponse *putObjectResponse = [self.s3 putObject:por];
[self performSelectorOnMainThread:#selector(showCheckErrorMessage:)
withObject:putObjectResponse.error
waitUntilDone:NO];
}
this creates the key path staging/videos/ within the bucket on s3 but the file is not there. I tried this with an image file also. I have checked to make sure that the data that i am trying to push up is not nil.
The xml response i get from the server says that the content length is 0 though.
I have also tried the multi part approach from the s3 sdk with the same result.
Can anyone see what I am doing wrong ?
I'm obviously really late with this response, but just in case anyone else has this problem in the future, you were structuring your request wrong.
By doing:
S3PutObjectRequest *por = [[S3PutObjectRequest alloc] initWithKey:#"staging/videos/" inBucket:#"aaa.aaaaa.com"];
with a backslash at the end of your key, you were creating a folder, not a file. You need to end your key with the filename including a suffix, ex #"staging/videos/video.mp4".

Resources