I'm trying to use AmazonS3Client to putObject. The strange thing is, it only seems to work when I run my putObject code on the iOS main thread.
The code is basically like this:
-(void)uploadVideoToS3
{
S3PutObjectRequest * videoPOR = [[S3PutObjectRequest alloc] initWithKey:video.onlineVideoID inBucket:video.onlineVideoBucketName];
videoPOR.contentType = @"video/quicktime";
videoPOR.data = [NSData dataWithContentsOfURL:video.convertedVideoLocalURL];
videoPOR.delegate = self;
// Put the thumbnail and video into the specified s3
AmazonS3Client * s3 = [AmazonClientManager s3];
[s3 putObject:videoPOR];
[videoPOR release];
}
The bucket exists, I have permissions, etc. If I simply call
[self uploadVideoToS3]
in my code (which is off the main thread), the whole video upload method runs (I have some NSLogs to prove this), but I never get any status callbacks, no exceptions are thrown, and the object is never put into its bucket on S3.
When I call the upload function on the main thread like so:
dispatch_async(dispatch_get_main_queue(), ^(void) {
[self uploadVideoToS3];
});
I get progress callbacks, everything works, and the object is successfully put into the S3 bucket.
Does anyone know if putObject only works on the iOS main thread? If so, that would be unfortunate since it's typically the UI thread.
Thanks, Kevin
P.S. I've tried dispatching the function call on a non-main thread with the same failed result.
I am thinking that your thread terminates once it finishes sending the request, therefore the callbacks have no thread to go to. Creating a thread doesn't automatically mean that it just lives forever. Once it finishes its task, it ends and is reclaimed for the thread pool. To do this on another thread, you are going to have to design a method which integrates with a run loop. There is a section on it in the Threading Programming Guide in the Apple docs.
The problem is actually that the S3PutObjectRequest runs asynchronously if you set the delegate. The delegate sends its callbacks on the current run loop, which works fine on the main thread, but not on a dispatch queue thread. You have to start your own run loop in order to process the delegates. I'm still trying to decide the best way to manage this.
Of course, I wish they would simply provide synchronous and asynchronous methods rather than magically switching, but this is explained in the AmazonServiceRequest.h header file on the delegate property.
AmazonS3Client's putObject method blocks the main thread. Even i was facing the problem. But i found a better solution in S3TransferManager.
Example Code:
AmazonS3Client * s3 = [AmazonClientManager s3];
S3PutObjectRequest * videoPOR = [[S3PutObjectRequest alloc] initWithKey:video.onlineVideoID inBucket:video.onlineVideoBucketName];
videoPOR.contentType = @"video/quicktime";
videoPOR.data = [NSData dataWithContentsOfURL:video.convertedVideoLocalURL];
S3TransferManager *manager = [S3TransferManager new];
manager.s3 = s3;
[manager upload:videoPOR];
S3TransferManager runs asynchronously. You can find more info on it here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With