2010-06-10 9 views
8

Tengo un servicio web que se ejecuta en Windows Azure que devuelve JSON que consumo en mi aplicación de iPhone.Comprimir/Descomprimir NSString en objetivo-c (iphone) usando GZIP o desinflar

Desafortunadamente, Windows Azure no parece ser compatible con la compresión de respuestas dinámicas (larga historia), así que decidí evitarlo al devolver un paquete JSON descomprimido, que contiene una cadena comprimida (usando GZIP).

por ejemplo

{"Error":null,"IsCompressed":true,"Success":true,"Value":"vWsAAB+LCAAAAAAAB..etc.."} 

... donde valor es la cadena comprimida de un objeto complejo representado en JSON.

Esto fue realmente fácil de implementar en el servidor, pero por mi vida no puedo encontrar la manera de descomprimir un NSString comprimido en un NSString descomprimido, todos los ejemplos que puedo encontrar para zlib, etc. tratan con archivos etc.

¿Alguien me puede dar alguna pista sobre cómo hacer esto? (También me gustaría una solución que utiliza desinflado ya que podría cambiar la implementación del lado del servidor para usar desinflar también).

Gracias!

Steven

Edición 1: Aaah, veo que ASIHTTPRequest está usando la siguiente función en su código fuente:

//uncompress gzipped data with zlib 
+ (NSData *)uncompressZippedData:(NSData*)compressedData; 

... y estoy consciente de que puedo convertir NSString a NSData, así que veré si esto me lleva a cualquier parte.

Editar 2: Desafortunadamente, el método descrito en Editar 1 no me llevó a ninguna parte.

Editar 3: Siguiendo los consejos a continuación sobre la codificación/decodificación base64, se me ocurrió el siguiente código. El codificadoGzippedString es como usted puede adivinar, una cadena "Hola, mi nombre es Steven Elliott" que se gzipped y luego se convierte en una cadena de base64. Desafortunadamente, el resultado que imprime con NSLog es simplemente blanco.

NSString *encodedGzippedString = @"GgAAAB+LCAAAAAAABADtvQdgHEmWJSYvbcp7f0r1StfgdKEIgGATJNiQQBDswYjN5pLsHWlHIymrKoHKZVZlXWYWQMztnbz33nvvvffee++997o7nU4n99//P1xmZAFs9s5K2smeIYCqyB8/fnwfPyK+uE6X2SJPiyZ93eaX+TI9Lcuiatvx/wOwYc0HGgAAAA=="; 
NSData *decodedGzippedData = [NSData dataFromBase64String:encodedGzippedString]; 
NSData* unGzippedJsonData = [ASIHTTPRequest uncompressZippedData:decodedGzippedData]; 
NSString* unGzippedJsonString = [[NSString alloc] initWithData:unGzippedJsonData encoding:NSASCIIStringEncoding];  
NSLog(@"Result: %@", unGzippedJsonString); 

Respuesta

3

¡Después de todo este tiempo, finalmente encontré una solución a este problema!

Ninguna de las respuestas anteriores me ha ayudado, por más prometedoras que todas.Al final, pude comprimir la cadena en el servidor con gzip usando chilkat framework para .net ... y luego descomprimirlo en el iphone usando chilkat framework para iOS (aún no publicado, pero disponible si envía un correo electrónico al chico directamente).

¡El marco de trabajo de chilkat hizo que esto fuera muy fácil de hacer, por lo que le agradezco al desarrollador!

+0

Hola, ¿Puedes proporcionar algún enlace exacto al marco? –

+0

http://www.chilkatsoft.com/downloads_ios.asp – dirkoneill

+0

cómo usar el marco chilkat? –

1

Su cadena "comprimido" no es GZIP de datos en bruto, es de alguna codificación que permite a los bytes que se almacenan en una base de string-- parece-64 o algo parecido. Para obtener un NSData de esto, deberá decodificarlo en NSData.

Si es realmente base-64, revisa esta publicación en el blog con un código adjunto: http://cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html que hará lo que quieras.

Una vez que tiene un objeto NSData, el método ASIHTTPRequest probablemente hará lo que quiera.

+0

Hola Quixoto, Gracias por su respuesta. Si marcas edit 3 en mi publicación original, verás qué sucedió después de que probé un poco más usando tus consejos. Gracias de nuevo –

+0

Es un conjunto razonable de pasos, entonces lo que no está claro es: ¿la cadena transmitida es definitivamente Base64? (probablemente) ¿Cuál es la codificación original de la cadena original en Windows land? Está eligiendo una codificación ASCII en la decodificación, que es poco probable que sea correcta. ¿Los datos en el búfer NSData dicen nada? –

0

Esto funcionó para mí: de una cadena gzipeed, luego base64 codificó para una cadena sin glosar (todos utf8).

#import "base64.h" 
#import "NSData+Compression.h" 

... 

+(NSString *)gunzipBase64StrToStr:(NSString *)stringValue { 
    //now we decode from Base64 
    Byte inputData[[stringValue lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];//prepare a Byte[] 
    [[stringValue dataUsingEncoding:NSUTF8StringEncoding] getBytes:inputData];//get the pointer of the data 
    size_t inputDataSize = (size_t)[stringValue length]; 
    size_t outputDataSize = EstimateBas64DecodedDataSize(inputDataSize);//calculate the decoded data size 
    Byte outputData[outputDataSize];//prepare a Byte[] for the decoded data 
    Base64DecodeData(inputData, inputDataSize, outputData, &outputDataSize);//decode the data 
    NSData *theData = [[NSData alloc] initWithBytes:outputData length:outputDataSize];//create a NSData object from the decoded data 
                         //NSLog(@"DATA: %@ \n",[theData description]); 

    //And now we gunzip: 
    theData=[theData gzipInflate];//make bigger==gunzip 
    return [[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding]; 
} 

@end 
Cuestiones relacionadas