亚马逊S3 iPhone SDK下载图片

3

我实在想不出如何在我的iOS项目中实现亚马逊的SDK,也似乎没有找到我所需的大量文档。

我只是想简单地从我的Amazon S3账户下载文件并本地存储在iPhone上。我可以通过访问图片的HTTP地址来完成这一操作,但这不能像我希望的那样保护图片。

根据我所了解的,我应该做以下事情:

AmazonS3Client *s3Client = [[AmazonS3Client alloc] initWithAccessKey:@"mykey" withSecretKey:@"mysecretkey"];
        
        S3GetObjectRequest *requestedObject = [[S3GetObjectRequest alloc] initWithKey:bucketPath withBucket:@"mybucket"];
 
        NSLog(@"requestedobject:%@", requestedObject - I get the log here);
        
        S3GetObjectResponse *getObjectResponse = [s3Client getObject:requestedObject];
        
        NSLog(@"requestedobject2:%@", getObjectResponse - it crashes before this happens);
        NSData *myData2;
        myData2 = getObjectResponse.body;
        [myData2 writeToFile:bucketPath atomically:YES];

我在使用getObjectResponse、getObject代码时出错了,但我无法弄清正确的语法……任何帮助都将不胜感激!下面是日志信息: 2012-08-02 17:12:33.856 Collection Master Edition[13176:4e07] requestedobject:<S3GetObjectRequest: 0x96ac380> 2012-08-02 17:12:34.044 Collection Master Edition[13176:4e07] *** Terminating app due to uncaught exception 'AmazonServiceException', reason: '(null)' 值得一提的是,我可以用以下代码获取bucket列表内容。
 S3ListObjectsRequest *listObjectRequest = [[S3ListObjectsRequest alloc] initWithName:@"my bucket"];
        
        S3ListObjectsResponse *listObjectResponse = [s3Client listObjects:listObjectRequest];
        
        S3ListObjectsResult *listObjectsResults = listObjectResponse.listObjectsResult;
        
        for (S3ObjectSummary *objectSummary in listObjectsResults.objectSummaries) {
            NSLog(@"Bucket Contents:%@" ,[objectSummary key]); // This returns the contents of the bucket
        }

你可能需要重新考虑这个问题,而是在你的iOS应用和S3之间添加一个Web服务层。否则,你将需要将AWS凭证放入应用程序本身中。因此,如果有人黑客攻击你的应用程序,他们就可以完全访问你的S3存储(以及该密钥可用的任何其他Amazon服务)。 - Mike Brant
我已经考虑过这个问题,并设置了TVM Web服务层...但我无法通过第一步开始测试TVM步骤...我想如果我能让上面的代码工作,我就可以继续前进(并提出更多问题!)以使TVM正常工作-您有什么想法吗?除非您对整个事情有建议! - Zachary Fisher
嗨,你解决了这个问题吗?我也在这里遇到了同样的问题。 - codingrhythm
对于任何遇到相同问题的人,这篇帖子对我很有帮助:http://stackoverflow.com/questions/18318487/aws-s3-sdk-for-ios-putobjectregquest-to-new-region-not-working - codingrhythm
3个回答

1

从我在这里看到的情况,您可能有两个问题中的一个。当我开始使用AWS时,我也遇到了类似的问题。首先确保您的存储桶名称全部为小写字母。您应该通过将其放入@try-@catch块并记录错误来检查发生这种情况的原因,这可以在解决问题时提供很好的细节。

    -(UIImage *)getImageFromS3{      


    @try{
    AmazonS3Client *_s3Client = [[AmazonS3Client alloc]initWithAccessKey:ACCESS_KEY withSecretKey:SECRET_KEY];      

    S3GetObjectRequest *getObjectRequest = [[S3GetObjectRequest alloc]initWithKey:imageKey withBucket:pictureBucket];

  S3GetObjectResponse *response = [_s3Client getObject:getObjectRequest];

    if (response.error == nil)
    {
        if (response.body != nil)
        {
        UIImage *someImage = [UIImage imageWithData:reponse.body];
    return someImage;
        }
        else{
            NSLog(@"There was no value in the response body");
            return nil;
             }
    }
    else if (response.error != nil)
    {
        NSLog(@"There was an error in the response while getting image: %@",response.error.description);
    }
}

    @catch (NSException *exception) {
    NSLog(@"There was an exception when connecting to s3: %@",exception.description);
}

} 

0

也许这不是必需的,但可能会帮助某些人。这是用于上传图像到亚马逊S3的代码。

constant.h
#import <Foundation/Foundation.h>
#define SECRET_KEY             @"your secret kry"
#define ACCESS_KEY_ID          @"your access id"

#define PICTURE_BUCKET @"桶名称" #define PICTURE_NAME @"任何文字" #define CREDENTIALS_ERROR_TITLE @"缺少凭据" #define CREDENTIALS_ERROR_MESSAGE @"AWS 凭据未正确配置。请查看 README 文件。"

@interface Constant : NSObject

+(NSString *)pictureBucket;

@end

In constant.m

#import "Constant.h"

@implementation Constant +(NSString *)pictureBucket { return [[NSString stringWithFormat:@"%@-%@", PICTURE_BUCKET, ACCESS_KEY_ID] lowercaseString]; }

@end

在 UploadViewController.h 中

  typedef enum {
  GrandCentralDispatch,
  Delegate,
  BackgroundThread
  } UploadType;

  @interface UploadPhotoViewController :  UIViewController<UIImagePickerControllerDelegate,UINavigationControllerDelegate,UINavigationControllerDelegate, AmazonServiceRequestDelegate>
 {
UploadType _uploadType;
 }

 @property (strong, nonatomic) IBOutlet UIButton *buttonSelectPhoto;
  @property (nonatomic, retain) AmazonS3Client *s3;

在UploadViewController.m文件中

      #import "UploadPhotoViewController.h"
       #import <AWSRuntime/AWSRuntime.h>
      #import "Constant.h"

       @interface UploadPhotoViewController ()

        @end

         @implementation UploadPhotoViewController

     - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
        {
     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
    // Custom initialization
      }
       return self;
     }

       - (void)viewDidLoad
      {
     [super viewDidLoad];
// Do any additional setup after loading the view from its nib.

     #ifdef DEBUG
     [AmazonLogger verboseLogging];
   #else
      [AmazonLogger turnLoggingOff];
   #endif

     [AmazonErrorHandler shouldNotThrowExceptions];

      if(![ACCESS_KEY_ID isEqualToString:@"CHANGE ME"]
          && self.s3 == nil)
       {
    // Initial the S3 Client.
    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    // This sample App is for demonstration purposes only.
    // It is not secure to embed your credentials into source code.
    // DO NOT EMBED YOUR CREDENTIALS IN PRODUCTION APPS.
    // We offer two solutions for getting credentials to your mobile App.
    // Please read the following article to learn about Token Vending Machine:
    // * http://aws.amazon.com/articles/Mobile/4611615499399490
    // Or consider using web identity federation:
    // * http://aws.amazon.com/articles/Mobile/4617974389850313
    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    self.s3 = [[AmazonS3Client alloc] initWithAccessKey:ACCESS_KEY_ID withSecretKey:SECRET_KEY] ;
    self.s3.endpoint = [AmazonEndpoints s3Endpoint:US_WEST_2];

    // Create the picture bucket.
    S3CreateBucketRequest *createBucketRequest = [[S3CreateBucketRequest alloc] initWithName:[Constant pictureBucket] andRegion:[S3Region USWest2]];
    S3CreateBucketResponse *createBucketResponse = [self.s3 createBucket:createBucketRequest];
    if(createBucketResponse.error != nil)
    {
        NSLog(@"Error: %@", createBucketResponse.error);
    }
}

  }
   -(void)viewDidAppear:(BOOL)animated
 {
[super viewDidAppear:animated];

if ([ACCESS_KEY_ID isEqualToString:@"CHANGE ME"])
{
    [self showAlertMessage:CREDENTIALS_ERROR_MESSAGE withTitle:CREDENTIALS_ERROR_TITLE];
}

} - (void)showAlertMessage:(NSString *)message withTitle:(NSString *)title { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil]; alertView.delegate=self; [alertView show]; } - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{

    // Set the content type so that the browser will treat the URL as an image.
    S3ResponseHeaderOverrides *override = [[S3ResponseHeaderOverrides alloc] init];
    override.contentType = @"image/jpeg";

    // Request a pre-signed URL to picture that has been uplaoded.
    S3GetPreSignedURLRequest *gpsur = [[S3GetPreSignedURLRequest alloc] init];
    gpsur.key                     = PICTURE_NAME;
    gpsur.bucket                  = [Constant pictureBucket];
    gpsur.expires                 = [NSDate dateWithTimeIntervalSinceNow:(NSTimeInterval) 3600]; // Added an hour's worth of seconds to the current time.
    gpsur.responseHeaderOverrides = override;

    // Get the URL
    NSError *error = nil;
    NSURL *url = [self.s3 getPreSignedURL:gpsur error:&error];

    if(url == nil)
    {
        if(error != nil)
        {
            dispatch_async(dispatch_get_main_queue(), ^{

                NSLog(@"Error: %@", error);
                [self showAlertMessage:[error.userInfo objectForKey:@"message"] withTitle:@"Browser Error"];
            });
        }
    }
    else
    {
        /*dispatch_async(dispatch_get_main_queue(), ^{
            // Display the URL in Safari
            [[UIApplication sharedApplication] openURL:url];

        });*/
    }NSLog(@"url is %@",url);

});

 }

   - (void)didReceiveMemoryWarning
   {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
  }

   - (IBAction)buttonTakePhoto:(id)sender
   {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];

picker.delegate = self;

picker.allowsEditing = YES;

picker.sourceType = UIImagePickerControllerSourceTypeCamera;



[self presentViewController:picker animated:YES completion:NULL];
  }

   - (IBAction)buttonSelectPhoto:(id)sender
   {
 [self showImagePicker:Delegate];
 }

    - (void)showImagePicker:(UploadType)uploadType
{
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init] ;
imagePicker.delegate = self;

_uploadType = uploadType;

[self presentViewController:imagePicker animated:YES completion:NULL];
   }


  - (void)processDelegateUpload:(NSData *)imageData
 {
// Upload image data.  Remember to set the content type.
S3PutObjectRequest *por = [[S3PutObjectRequest alloc] initWithKey:PICTURE_NAME
                                                          inBucket:[Constant pictureBucket]];
por.contentType = @"image/jpeg";
por.data = imageData;
por.delegate = self;

// Put the image data into the specified s3 bucket and object.
[self.s3 putObject:por];
 }

     -(void)request:(AmazonServiceRequest *)request didCompleteWithResponse:(AmazonServiceResponse *)response
  {
[self showAlertMessage:@"The image was successfully uploaded." withTitle:@"Upload Completed"];

[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
  }

 -(void)request:(AmazonServiceRequest *)request didFailWithError:(NSError *)error
  {
NSLog(@"Error: %@", error);
[self showAlertMessage:error.description withTitle:@"Upload Error"];

[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
  }

   #pragma mark - UIImagePickerControllerDelegate methods

       -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
    {
// Get the selected image.
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];

// Convert the image to JPEG data.
NSData *imageData = UIImageJPEGRepresentation(image, 1.0);


if(_uploadType == Delegate)
{
    [self processDelegateUpload:imageData];
}

[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

[picker dismissViewControllerAnimated:YES completion:NULL];
   }

   -(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
  {
[picker dismissViewControllerAnimated:YES completion:NULL];
   }

     - (IBAction)buttonBack:(id)sender
     {
[self.navigationController popViewControllerAnimated:YES];
   }

   @end

0

可能的问题是与您的密钥对关联的权限有关。 我建议您前往管理控制台上的IAM,创建一个具有所需S3权限的新组,本例中除了一些不需要的管理事项(因此主要只是POST,GET权限)之外,几乎都需要。然后在该组中创建用户,并使用该密钥对进行测试。这可能会清理事情,因为我认为这就是为我工作的过程。 似乎列表权限相当低级,但POST和GET需要不同的权限。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接