Pergunta

Eu tenho um serviço na Web em execução no Windows Azure, que retorna o JSON que eu consumo no meu aplicativo para iPhone.

Infelizmente, o Windows Azure não parece suportar a compactação de respostas dinâmicas ainda (longa história), então decidi contorná -lo retornando um pacote JSON não compactado, que contém uma string compactada (usando GZIP).

por exemplo

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

... onde o valor é a sequência compactada de um objeto complexo representado no JSON.

Isso foi realmente fácil de implementar no servidor, mas, para a vida minha, não consigo descobrir como descomprimir um NSString de uma NSString não compactado, todos os exemplos que posso encontrar para o ZLIB etc. estão lidando com arquivos etc.

Alguém pode me dar alguma pista sobre como fazer isso? (Eu também ficaria feliz por uma solução que usava esvaziar, pois eu poderia alterar a implementação do servidor para usar também o deflate).

Obrigado!!

Steven

Editar 1: Aaah, vejo que asihttprequest estão usando a seguinte função no código -fonte:

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

... E eu sei que posso converter o NSString em nsdata, então vou ver se isso me leva a qualquer lugar!

Editar 2: Infelizmente, o método descrito na edição 1 não me levou a lugar algum.

Editar 3: Seguindo os conselhos abaixo sobre a codificação/decodificação Base64, criei o código a seguir. O CodedGzippedString é como você pode adivinhar, uma string "Olá, meu nome é Steven Elliott", que é gzipped e depois convertido em uma string base64. Infelizmente, o resultado que impressa usando o NSLog está em branco.

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);  
Foi útil?

Solução

Depois de todo esse tempo, finalmente encontrei uma solução para esse problema!

Nenhuma das respostas acima me ajudou, por mais promissor que todos pareçam. No final, pude comprimir a string no servidor com GZIP usando a estrutura Chilkat para .NET ... e depois descompacte -o no iPhone usando a estrutura Chilkat para iOS (ainda não foi lançada, mas disponível se você enviar um e -mail para cara diretamente).

A estrutura do Chilkat tornou isso super fácil de fazer tão grandes polegares até o desenvolvedor!

Outras dicas

Sua string "compactada" não são dados brutos do Gzip'd, está em algumas codificação que permite que esses bytes sejam armazenados em uma string-parece com base-64 ou algo parecido. Para tirar um nsdata disso, você precisará decodificá -lo no NSDATA.

Se for realmente base-64, consulte esta postagem no blog um código que o acompanha:http://cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.htmlo que fará o que você quiser.

Depois de ter um objeto nsdata, o método asihttprequest provavelmente fará o que quiser.

Isso funcionou para mim: a partir de uma string gzipeed, depois base64 codificada para a string não chutada (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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top