使用GZIP或deflate在objective-c(iphone)中压缩/解压缩NSString

时间:2010-06-10 15:34:48

标签: iphone objective-c gzip deflate http-compression

我在Windows Azure上运行了一个Web服务,它返回我在iPhone应用程序中使用的JSON。

不幸的是,Windows Azure似乎还不支持动态响应的压缩(长篇故事)所以我决定通过返回一个未压缩的JSON包来解决它,它包含一个压缩的(使用GZIP)字符串。

e.g

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

...其中value是以JSON表示的复杂对象的压缩字符串。

这在服务器上很容易实现,但是对于我的生活,我无法弄清楚如何将压缩的NSS​​tring解压缩为未压缩的NSS​​tring,我可以为zlib等找到的所有示例都处理文件等

任何人都可以给我任何关于如何做到这一点的线索吗? (我也很高兴使用deflate的解决方案,因为我可以更改服务器端实现以使用deflate)。

谢谢!

史蒂芬

编辑1: Aaah,我看到ASIHTTPRequest在它的源代码中使用了以下函数:

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

...而且我知道我可以将NSString转换为NSData,所以我会看看这是否会引导我到任何地方!

编辑2:不幸的是,编辑1中描述的方法并没有把我带到任何地方。

编辑3:按照以下关于base64编码/解码的建议,我想出了以下代码。您可以猜测编码的GzippedString是一个字符串“Hello,我的名字是Steven Elliott”,它被gzip压缩然后转换为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);  

4 个答案:

答案 0 :(得分:4)

经过这么久,我终于找到了解决这个问题的方法!

上面的答案都没有对我有所帮助,因为他们看起来都很有希望。最后,我能够使用chilkat框架为.net来压缩服务器上的字符串...然后使用chilkat框架在iOS上解压缩它(尚未发布,但如果您通过电子邮件发送,则可用直接)。

chilkat框架让这个非常容易对开发人员大加赞赏!

答案 1 :(得分:1)

你的“压缩”字符串不是原始GZIP数据,它在某种编码中允许这些字节存储在字符串中 - 看起来像base-64或类似的东西。要从中获取NSData,您需要将其解码为NSData。

如果它真的是base-64,请查看此博客文章附带的代码: http://cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html 这将做你想要的。

一旦你有了一个NSData对象,ASIHTTPRequest方法可能会按你的意愿做。

答案 2 :(得分:0)

这对我有用: 从字符串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

答案 3 :(得分:0)

我需要使用Objective-c在iPhone上压缩数据并在PHP上解压缩。这是我在XCode 11.5和iOS 12.4中使用的:

iOS Objective-c压缩解压缩测试 在构建阶段->使用库链接二进制文件中包括libcompression.tbd。然后添加标题。

#include "compression.h"


NSLog(@"START META DATA COMPRESSION");
NSString *testString = @"THIS IS A COMPRESSION TESTTHIS IS A COMPRESSION TESTTHIS IS A COMPRESSION TESTTHIS IS A COMPRESSION TESTTHIS IS A COMPRESSION TESTTHIS IS A COMPRESSION TEST";
NSData *theData = [testString dataUsingEncoding:NSUTF8StringEncoding];
size_t src_size = theData.length;
uint8_t *src_buffer = (uint8_t*)[theData bytes];
size_t dst_size = src_size+4096;
uint8_t *dst_buffer = (uint8_t*)malloc(dst_size);
dst_size = compression_encode_buffer(dst_buffer, dst_size, src_buffer, src_size, NULL, COMPRESSION_ZLIB);
NSLog(@"originalsize:%zu compressed:%zu", src_size, dst_size);
NSData *dataData = [NSData dataWithBytes:dst_buffer length:sizeof(dst_buffer)];
NSString *compressedDataBase64String = [dataData base64EncodedStringWithOptions:0];    

NSLog(@"Compressed Data %@", compressedDataBase64String);

NSLog(@"START META DATA DECOMPRESSION");
src_size = compression_decode_buffer(src_buffer, src_size, dst_buffer, dst_size, NULL, COMPRESSION_ZLIB);
NSData *decompressed = [[NSData alloc] initWithBytes:src_buffer length:src_size];
NSString *decTestString;
decTestString = [[NSString alloc] initWithData:decompressed encoding:NSASCIIStringEncoding];

NSLog(@"DECOMPRESSED DATA %@", decTestString);

free(dst_buffer);

在PHP端,我使用以下函数解压缩数据:

function decompressString($compressed_string) {

    //NEED RAW GZINFLATE FOR COMPATIBILITY WITH IOS COMPRESSION_ZLIB WITH IETF RFC 1951
    $full_string = gzinflate($compressed_string);
    return $full_string;

}