Сжать / распаковать NSString в target-c (iphone), используя GZIP или выкачать - PullRequest
8 голосов
/ 10 июня 2010

У меня есть веб-служба, работающая в Windows Azure, которая возвращает JSON, который я использую в своем приложении для iPhone.

К сожалению, Windows Azure, похоже, пока не поддерживает сжатие динамических ответов (длинная история)поэтому я решил обойти это, возвращая несжатый пакет JSON, который содержит сжатую (используя GZIP) строку.

например,

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

... где value - сжатая строка сложного объекта, представленного в JSON.

Это было действительно легко реализовать на сервере, ноя не могу понять, как распаковать сжатый NSString в несжатый NSString, все примеры, которые я могу найти для zlib и т. д., имеют дело с файлами и т. д.

Может кто-нибудь дать мне какие-нибудь подсказкикак это сделать?(Я также был бы рад за решение, использующее deflate, поскольку я мог бы изменить реализацию на стороне сервера, чтобы использовать также deflate).

Спасибо !!

Стивен

Редактировать 1: Ааа, я вижу, что ASIHTTPRequest использует следующую функцию в своем исходном коде:

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

... и я знаю, что могу преобразовать NSString в NSData,так что я посмотрю, приведет ли это меня куда-либо!

Edit 2: К сожалению, метод, описанный в Edit 1, никуда меня не привел.

Изменить 3: Следуя приведенным ниже советам относительно кодирования / декодирования base64, я придумал следующий код.Как вы можете догадаться, encodedGzippedString - это строка «Здравствуйте, меня зовут Стивен Эллиотт», которая распаковывается и затем преобразуется в строку base64.К сожалению, результат печати с использованием NSLog просто пуст.

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);  

Ответы [ 3 ]

4 голосов
/ 08 апреля 2011

После всего этого времени я наконец-то нашел решение этой проблемы!

Ни один из приведенных выше ответов не помог мне, столь же многообещающе, как они все выглядели. В конце я смог сжать строку на сервере с помощью gzip, используя среду chilkat для .net ..., а затем распаковать ее на iphone, используя среду chilkat для iOS (еще не выпущена, но доступна, если вы отправите электронное письмо парень прямо).

Фреймворк chilkat сделал этот супер простой способ сделать большой палец на усмотрение разработчика!

1 голос
/ 15 июня 2010

Ваша "сжатая" строка не является необработанными данными GZIP, она находится в некоторой кодировке, которая позволяет хранить эти байты в строке - выглядит как base-64 или что-то в этом роде.Чтобы получить NSData из этого, вам нужно будет декодировать его в NSData.

Если это действительно base-64, проверьте этот пост в блоге сопровождающим кодом: http://cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html, который будет делатьчто вы хотите.

Если у вас есть объект NSData, метод ASIHTTPRequest, вероятно, будет работать так, как вам нравится.

0 голосов
/ 01 октября 2010

Это сработало для меня: из строки gzipeed, затем base64 в кодировке в несжатую строку (все 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
...