2009-06-28 7 views
5

Estoy tirando de mi cabello en este ... Estoy usando la biblioteca contenedora ASIHTTPRequest (http://allseeing-i.com/ASIHTTPRequest/) para acceder al almacenamiento de Amazon S3. Puedo conectarme perfectamente y tomar una lista de cubos sin ningún problema. Mi frustración es tratar de CARGAR (PONER y/o PUBLICAR) un nuevo objeto (una foto) en un depósito existente. Estoy siguiendo la documentación de Amazon al pie de la letra (al menos creo que lo estoy) pero nada parece funcionar.Subiendo a los servicios de Amazon S3 desde la aplicación iPhone

Por favor, alguien me ayude antes de saltar por la ventana. No quiero morir :-(

Gracias de antemano por cualquier ayuda que pueda conseguir.

L.

+0

Hmmmm: bastante difícil de ayudar sin más detalles que "no funciona". ¿Qué específicamente? ¿Falla de qué manera? ¿Código? ¿Qué has intentado? – Hunter

Respuesta

12

Esto es un ejemplo básico utilizando PUT. Obviamente, usted debe utilizar una cola en lugar de una solicitud síncrona en lo real mundo.

Si cambia las cabeceras AMZ, no se olvide de actualizar '' canonicalizedAmzHeaders según las instrucciones del Amazonas.

#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

You Rock pokeb. Realmente aprecio la ayuda. Mi canonicalizedAmzHeader fue todo un desastre. Sin embargo, tengo otro problema ... Intenté "agregar" la solicitud a una cola e iniciarla desde allí, pero fue en vano. Aquí está mi código: [networkQueue cancelAllOperations]; [solicitud ..... definiciones aquí]; [networkQueue addOperation: request]; [networkQueue go]; ¿Qué cosas debería estar pendiente al agregar una solicitud a una cola? ¡gracias de nuevo por la ayuda! L. –

+0

¿Creó primero la cola? (por ejemplo: [self setNetworkQueue: [ASINetworkQueue queue]]) – pokeb

+0

Usted tenía razón otra vez. Mi variable de instancia de networkQueue nunca se inicializó. Tu eres el hombre. Realmente aprecio la ayuda. –

1

también existe la Connection Kit Cocoa framework, que puede cargar datos a diferentes servicios, incluido Amazon S3. Estoy bastante seguro de que tiene algunos puntos de partida para usted en su fuente.

11

En caso de que sea útil para cualquier persona encontrar esta pregunta - Soporte básico S3 está ahora integrado en ASIHTTPRequest:

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

que había estado pensando en añadir soporte S3 para las edades, pero su pregunta empujó al frente de la cola :)

+0

NIZA! Me encanta el envoltorio. Me he convertido en tu mayor fan. ¡Mantener el buen trabajo! –

+0

¡gracias por la hermosa biblioteca! :) –