2009-06-28 12 views
5

私はこの1つで私の髪を引っ張っています... Amazon S3ストレージにアクセスするためのASIHTTPRequest(http://allseeing-i.com/ASIHTTPRequest/)ラッパーライブラリを使用しています。私はうまく接続して問題のないバケットのリストを取得することができます。私の不満は、新しいオブジェクト(写真)を既存のバケットにアップロード(PUTおよび/またはPOST)しようとすることです。私は手紙にAmazonの文書を守っています(少なくとも私は私だと思いますが)何も動かないようです。iPhone AppからAmazon S3サービスにアップロード

私が窓から飛び降りる前に誰か助けてください。私は死にたくない。 :-(私が得ることができる任意のヘルプを事前に

感謝。

L.

+0

Hmmmm - 「動作しません」以外の詳細がなくても大変助かります。具体的には何ですか?どのように失敗するのですか?コード?何を試しましたか? – Hunter

答えて

12

ここでは、PUTを使用して、基本的な例である。明らかに、キューではなく、リアルタイムで同期要求を使用する必要があります世界。あなたはAMZヘッダを変更した場合

、Amazonの指示に従って「canonicalizedAmzHeaders」を更新することを忘れないでください。

#import "ASIHTTPRequest.h" 
#import <CommonCrypto/CommonHMAC.h> 

... 

- (void)testS3 
{ 
    NSString *filePath = @"/path/to/file"; 
    NSString *contentType = @"text/plain"; 
    NSString *bucket = @"mybucket"; 
    NSString *path = @"test"; 
    NSString *secretAccessKey = @"my-secret-access-key"; 
    NSString *accessKey = @"my-access-key"; 

    NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease]; 
    [dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss zzzz"]; 
    NSString *date = [dateFormatter stringFromDate:[NSDate date]]; 

    ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@.s3.amazonaws.com/%@",bucket,path]]] autorelease]; 
    [request setPostBodyFilePath:filePath]; 
    [request setShouldStreamPostDataFromDisk:YES]; 
    [request setRequestMethod:@"PUT"]; 

    [request addRequestHeader:@"x-amz-acl" value:@"private"]; 
    [request addRequestHeader:@"Content-Type" value:contentType]; 
    [request addRequestHeader:@"Date" value:date]; 

    NSString *canonicalizedAmzHeaders = @"x-amz-acl:private"; 
    NSString *canonicalizedResource = [NSString stringWithFormat:@"/%@/%@",bucket,path]; 
    NSString *stringToSign = [NSString stringWithFormat:@"PUT\n\n%@\n%@\n%@\n%@",contentType,date,canonicalizedAmzHeaders,canonicalizedResource]; 

    NSString *signature = [self base64forData:[self HMACSHA1withKey:secretAccessKey forString:stringToSign]]; 
    NSString *auth = [NSString stringWithFormat:@"AWS %@:%@",accessKey,signature]; 
    [request addRequestHeader:@"Authorization" value:auth]; 


    [request start]; 
    NSLog(@"%@",[request responseString]); 

} 


// Source: http://stackoverflow.com/questions/476455/is-there-a-library-for-iphone-to-work-with-hmac-sha-1-encoding 

- (NSData *)HMACSHA1withKey:(NSString *)key forString:(NSString *)string 
{ 
    NSData *clearTextData = [string dataUsingEncoding:NSUTF8StringEncoding]; 
    NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding]; 

    uint8_t digest[CC_SHA1_DIGEST_LENGTH] = {0}; 

    CCHmacContext hmacContext; 
    CCHmacInit(&hmacContext, kCCHmacAlgSHA1, keyData.bytes, keyData.length); 
    CCHmacUpdate(&hmacContext, clearTextData.bytes, clearTextData.length); 
    CCHmacFinal(&hmacContext, digest); 

    return [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH]; 
} 

//Source http://www.cocoadev.com/index.pl?BaseSixtyFour 

- (NSString *)base64forData:(NSData *)data 
{ 
    static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/"; 

    if ([data length] == 0) 
     return @""; 

    char *characters = malloc((([data length] + 2)/3) * 4); 
    if (characters == NULL) 
     return nil; 
    NSUInteger length = 0; 

    NSUInteger i = 0; 
    while (i < [data length]) 
    { 
     char buffer[3] = {0,0,0}; 
     short bufferLength = 0; 
     while (bufferLength < 3 && i < [data length]) 
      buffer[bufferLength++] = ((char *)[data bytes])[i++]; 

     // Encode the bytes in the buffer to four characters, including padding "=" characters if necessary. 
     characters[length++] = encodingTable[(buffer[0] & 0xFC) >> 2]; 
     characters[length++] = encodingTable[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)]; 
     if (bufferLength > 1) 
      characters[length++] = encodingTable[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)]; 
     else characters[length++] = '='; 
     if (bufferLength > 2) 
      characters[length++] = encodingTable[buffer[2] & 0x3F]; 
     else characters[length++] = '=';  
    } 

    return [[[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES] autorelease]; 
} 
+0

あなたはロックpokeb。本当に助けに感謝します。私のcanonicalizedAmzHeaderはすべて狂っていました。私はもう一つの問題を抱えています...キューにリクエストを「追加」してそこから起動しようとしましたが、無駄にしました。ここに私のコードです: [networkQueue cancelAllOperations]; [要求.....定義はここに]; [networkQueue addOperation:request]; [networkQueue go]; キューにリクエストを追加する際には、どのようなことが必要ですか? もう一度お世話になりました! L. –

+0

最初にキューを作成しましたか? (例:[self setNetworkQueue:[ASINetworkQueue queue]]) – pokeb

+0

あなたはもう一度元気でした。私のnetworkQueueインスタンス変数が決して初期化されませんでした。あなたは男です。本当に助けに感謝します。 –

1

もありますConnection Kit Amazon S3を含む異なるサービスにデータをアップロードできるCocoaフレームワーク。私はそれがソースのあなたのためのいくつかの出発点を持っていることをかなり確信しています。

11

それがこの質問を見つける人のための便利だ場合 - 基本S3のサポートは今ASIHTTPRequestにして構築されています。

http://allseeing-i.com/ASIHTTPRequest/S3

私は年齢のためのS3のサポートを追加することを考えてのだが、あなたの質問には、それをつついキューの前面に表示されます。

+0

NICE!私はラッパーが大好きです。私はあなたの最大のファンになった。これからもいい結果を出し続けてください! –

+0

素敵な図書館に感謝します! :) –

関連する問題