Support ASIHTTPRequest - buy Space Harvest - my new real-time strategy game for iPod Touch & iPhone!

All-Seeing Interactive Logo

ASIHTTPRequest documentation

Last updated: 2nd March 2010


Introduction

New in v1.0 is experimental Amazon S3 support, using the S3 REST API. This is new code, it will contain bugs, it will be missing features, and I expect the API will change over the next few weeks. Use at your own risk!

Most of these examples use synchronous requests for brevity, you should normally use a queue or [request startAsynchronous] to perform these operations asynchronously (more info..).


The classes

S3 support is built around 3 classes:

  • ASIS3Request
    An ASIHTTPRequest subclass that makes talking to S3 easy. It generates the HTTP headers S3 requires for you.
  • ASIS3ListRequest
    An ASIS3Request subclass that can can perform list requests, and parse the resulting XML.
  • ASIS3BucketObject
    A simple class that stores information about objects stored in a bucket on S3. An ASIListRequest creates these when you perform a list request, and you can use these to create a request that will GET, PUT or DELETE the objects they represent in the bucket.

GET an object

In this example, we'll get the object from S3 that is stored at http://my-bucket.s3.amazonaws.com/path/to/the/object.

NSString *secretAccessKey = @"my-secret-access-key";
NSString *accessKey = @"my-access-key";
NSString *bucket = @"my-bucket";
NSString *path = @"/path/to/the/object";
 
ASIS3Request *request = [ASIS3Request requestWithBucket:bucket path:path];
[request setSecretAccessKey:secretAccessKey];
[request setAccessKey:accessKey];
[request startSynchronous];
if (![request error]) {
	NSData *data = [request responseData];
} else {
	NSLog(@"%@",[[request error] localizedDescription]);
}

PUT an object

It can be a pain to have to set your access key and secret access key to every request, so we'll set the sharedAccessKey and sharedSecretAccessKey. The next time we perform a request without setting these, it will use these values.

[ASIS3Request setSharedSecretAccessKey:@"my-secret-access-key"];
[ASIS3Request setSharedAccessKey:@"my-access-key"];
 
NSString *filePath = @"/somewhere/on/disk.txt";
 
ASIS3Request *request = 
 [ASIS3Request PUTRequestForFile:filePath withBucket:@"my-bucket" path:@"/path/to/the/object"];
[request startSynchronous];
if ([request error]) {
   NSLog(@"%@",[[request error] localizedDescription]);
}

DELETE an object

We won't set the access keys this time, because we've already set the shared ones.

ASIS3Request *request = [ASIS3Request requestWithBucket:@"my-bucket" path:@"/path/to/the/object"];
[request setRequestMethod:@"DELETE"];
[request startSynchronous];
if ([request error]) {
   NSLog(@"%@",[[request error] localizedDescription]);
}

COPY an object

ASIS3Request *request = 
   [ASIS3Request COPYRequestFromBucket:@"my-bucket" path:@"/path/to/the/object" 
   toBucket:@"my-bucket" path:@"/new/path/to/the/object"];
[request startSynchronous];
if ([request error]) {
   NSLog(@"%@",[[request error] localizedDescription]);
}

Fetch a list of objects

A list query is basically a GET request on a bucket. S3 returns a list of information objects that matched the query in XML format. This example will fetch information about no more than 50 objects in http://my-bucket.s3.amazonaws.com/images/jpegs. [listRequest bucketObjects] is an array of ASIS3BucketObjects.

ASIS3ListRequest *listRequest = [ASIS3ListRequest listRequestWithBucket:@"my-bucket"];
[listRequest setPrefix:@"images/jpegs"];
[listRequest setMaxResultCount:50]; // Max number of results we want
[listRequest startSynchronous];
if (![listRequest error]) {
   NSLog(@"%@",[listRequest bucketObjects]);
}

Downloading objects from the list

This time, we'll do something with the result of the list query.

- (void)download25ImagesToDisk
{
   // First grab a list of 25 images
   ASIS3ListRequest *listRequest = [ASIS3ListRequest listRequestWithBucket:@"my-bucket"];
   [listRequest setPrefix:@"images/jpegs"];
   [listRequest setMaxResultCount:25];
   [listRequest startSynchronous];
   if ([listRequest error]) {
      NSLog(@"%@",[[listRequest error] localizedDescription]);
      return;
   }
 
   // We'll use a queue to perform the operations in the background
   [self setQueue:[ASINetworkQueue queue]];
   [[self queue] setRequestDidFinishSelector:@selector(requestDone:)];
   [[self queue] setRequestDidFailSelector:@selector(requestFailed:)];
   [[self queue] setDelegate:self];
 
   // Loop through all the objects returned by the query
   // and create a request to download them to disk
   int i=0;
   for (ASIS3BucketObject *object in [listRequest bucketObjects]) {
      ASIS3Request *request = [object GETRequest];
      NSString *downloadPath = [NSString stringWithFormat:@"/Users/ben/Desktop/images/%hi.jpg",i];
      [request setDownloadDestinationPath:downloadPath];
      [[self queue] addOperation:request];
      i++;
   }
 
   // Start the queue
   [[self queue] go];
}
 
- (void)requestDone:(ASIS3Request *)request
{
   NSLog(@"Finished downloading an image");
}
 
- (void)requestFailed:(ASIS3Request *)request
{
   NSLog(@"Dammit, something went wrong: %@",[[request error] localizedDescription]);
}

You can also create requests to PUT new files to replace objects in the list using [object PUTRequestWithFile:path], or to DELETE objects in the list using [object DELETERequest].

GZIP data

New in ASIHTTPRequest 1.0.3 is the ability to gzip request bodies (More here). This may be especially useful for applications that store data on S3, because:

  • Data is stored compressed, so it uses less space and costs you less money
  • Data is uploaded and downloaded compressed, so it saves money and makes requests faster in both directions
ASIS3Request *request = 
 [ASIS3Request PUTRequestForFile:filePath withBucket:@"my-bucket" path:@"/path/to/the/object"];
[request setShouldCompressRequestBody:YES];

Compressed data stored on S3 can be downloaded and automatically decompressed by any HTTP client that supports gzipped downloads (eg a web browser, NSURLConnection etc). However, S3 will not deliver uncompressed content to those that do not. HTTP clients that do not send a Accept-Encoding: gzip header will still get gzipped content.