2009-06-28 5 views
5

Ich ziehe meine Haare auf diesem ... Ich verwende die ASIHTTPRequest (http://allseeing-i.com/ASIHTTPRequest/) Wrapper-Bibliothek für den Zugriff auf Amazon S3-Speicher. Ich bin in der Lage, gut zu verbinden und eine Liste von Eimern ohne Probleme zu greifen. Mein Frust ist, wenn ich versuche, ein neues Objekt (ein Foto) in einen bestehenden Bucket zu laden (PUT und/oder POST). Ich folge Amazons Dokumentation (zumindest glaube ich, dass ich es bin), aber nichts scheint zu funktionieren.Uploading auf Amazon S3-Dienste von iPhone App

Bitte helfen Sie mir, bevor ich aus dem Fenster spring. Ich will nicht sterben. :-(

Vielen Dank im Voraus für jede Hilfe, die ich bekommen kann.

L.

+0

Hmmmm - ziemlich schwer zu helfen, ohne irgendwelche Details über "es funktioniert nicht". Was speziell? Fällt auf welche Art und Weise? Code? Was hast du probiert? – Hunter

Antwort

12

Hier ist ein einfaches Beispiel ist PUT verwenden. Offensichtlich sollten Sie eine Warteschlange verwenden anstatt eine synchrone Anforderung in den realen Welt.

Wenn Sie die amz-Header zu ändern, vergessen Sie nicht, ‚canonicalizedAmzHeaders‘ zu aktualisieren, da pro Amazon Anweisungen.

#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

Sie Rock pokeb. Ich schätze die Hilfe sehr. Mein kanonisierter AmzHeader war total verrückt. Ich habe jedoch ein anderes Problem ... Ich habe versucht, die Anfrage zu einer Warteschlange hinzuzufügen und von dort aus zu starten, aber ohne Erfolg. Hier ist mein Code: [networkQueue cancelAllOperations]; [Anfrage ..... Definitionen gehen hier]; [networkQueue addOperation: Anfrage]; [networkQueue go]; Auf welche Dinge sollte ich beim Hinzufügen einer Anfrage zu einer Warteschlange achten? danke nochmal für die Hilfe! L. –

+0

Haben Sie zuerst die Warteschlange erstellt? (zB: [self setNetworkQueue: [ASINetworkQueue queue]]) – pokeb

+0

Sie hatten wieder Recht. Meine networkQueue-Instanzvariable wurde nie initialisiert. Du bist der Mann. Ich schätze die Hilfe sehr. –

1

Es gibt auch die Connection Kit Cocoa-Framework, das Daten zu verschiedenen Diensten, einschließlich Amazon S3, hochladen kann. Ich bin mir ziemlich sicher, dass es einige Ausgangspunkte für Sie in seiner Quelle hat.

11

Bei hilfreich ist es für alle, diese Frage zu finden - Grund S3 Unterstützung jetzt ist eingebaut, um ASIHTTPRequest:

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

ich für S3-Unterstützung über das Hinzufügen von Alter zu denken hatte, aber Ihre Frage stupste es an die Spitze der Warteschlange :)

+0

SCHÖN! Ich liebe den Wrapper. Ich bin dein größter Fan geworden. Mach weiter so! –

+0

danke für die schöne Bibliothek! :) –