Reputation: 1413
Seems this should be relatively simple. I'm using the AWS SDK (v2) for iOS and I'm trying to download a .png file and display it to the screen in a UIImage. Everything actually works! Just very strangely...
Here is my code:
AWSStaticCredentialsProvider *credentialsProvider = [AWSStaticCredentialsProvider credentialsWithAccessKey:@"MY_ACCESS_KEY" secretKey:@"MY_SECRET_KEY"];
AWSServiceConfiguration *configuration = [AWSServiceConfiguration configurationWithRegion:AWSRegionUSWest1 credentialsProvider:credentialsProvider];
[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
AWSS3 *transferManager = [[AWSS3 alloc] initWithConfiguration:configuration];
AWSS3GetObjectRequest *getImageRequest = [AWSS3GetObjectRequest new];
getImageRequest.bucket = @"MY_BUCKET";
getImageRequest.key = @"MY_KEY";
[[transferManager getObject:getImageRequest] continueWithBlock:^id(BFTask *task) {
if(task.error)
{
NSLog(@"Error: %@",task.error);
}
else
{
NSLog(@"Got image");
NSData *data = [task.result body];
UIImage *image = [UIImage imageWithData:data];
myImageView.image = image;
}
return nil;
}];
When this code gets executed, the continueWithBlock gets executed, there is no task error, so Got image is logged. And this happens fairly quickly. However, it's not until about 10 seconds later that the UIImageView updates on the screen. I even ran through the debugger to see if any of the lines following the NSLog(@"Got image");
line were taking long and they weren't. They were all executing very quickly but then the UIImageView would not be updated on the UI.
Upvotes: 3
Views: 2623
Reputation: 3759
The issue is that you are updating UI component from a background thread. The continueWithBlock:
block is executed in the background thread, and it is causing the aforementioned behavior. You have two options:
Use Grand Central Dispatch in the block and run it on the main thread:
...
NSURL *fileURL = [task.result body];
NSData *data = // convert fileURL to data
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *image = [UIImage imageWithData:data];
myImageView.image = image;
});
...
Use mainThreadExecutor
to run the block on the main thread:
[[transferManager getObject:getImageRequest] continueWithExecutor:[BFExecutor mainThreadExecutor]
withBlock:^id(BFTask *task) {
...
Hope this helps,
Upvotes: 5