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

使用GZIP或deflate压缩/解压缩objective-c(iphone)中的NSString,iphone,objective-c,gzip,deflate,http-compression,Iphone,Objective C,Gzip,Deflate,Http Compression,我有一个在WindowsAzure上运行的web服务,它返回我在iPhone应用程序中使用的JSON 不幸的是,windowsazure似乎还不支持动态响应的压缩(说来话长),所以我决定通过返回一个未压缩的JSON包来绕过它,该包包含一个压缩(使用GZIP)字符串 e、 g 。。。其中value是JSON中表示的复杂对象的压缩字符串 这很容易在服务器上实现,但就我的一生而言,我不知道如何将压缩的NSString解压为未压缩的NSString,我能找到的所有zlib等示例都是处理文件等 有人能告诉

我有一个在WindowsAzure上运行的web服务,它返回我在iPhone应用程序中使用的JSON

不幸的是,windowsazure似乎还不支持动态响应的压缩(说来话长),所以我决定通过返回一个未压缩的JSON包来绕过它,该包包含一个压缩(使用GZIP)字符串

e、 g

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

这很容易在服务器上实现,但就我的一生而言,我不知道如何将压缩的NSString解压为未压缩的NSString,我能找到的所有zlib等示例都是处理文件等

有人能告诉我怎么做吗?(我也希望有一个使用deflate的解决方案,因为我可以将服务器端实现也更改为使用deflate)

谢谢

史蒂文

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

//uncompress gzipped data with zlib
+ (NSData *)uncompressZippedData:(NSData*)compressedData;
。。。我知道我可以将NSString转换为NSData,所以我会看看这是否会让我有所收获

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

编辑3:根据下面关于base64编码/解码的建议,我提出了以下代码。encodedGzippedString正如您所猜测的,是一个字符串“您好,我的名字是Steven Elliott”,它被压缩,然后转换为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);  
您的“压缩”字符串不是原始的GZIP数据,它是以某种编码形式存在的,允许将这些字节存储在字符串中——看起来像base-64或类似的东西。要从中获取NSData,需要将其解码为NSData

如果它真的是base-64,请查看此博客文章并附上代码: 你想怎么做就怎么做

一旦有了NSData对象,ASIHTTPRequest方法可能会按照您的喜好进行操作。

这对我很有用: 从一个字符串gziped,然后base64编码 取消压缩字符串(所有utf8)


经过这么长时间,我终于找到了解决这个问题的办法

上面的答案没有一个对我有帮助,尽管它们看起来都很有希望。最后,我能够使用.net的chilkat框架在服务器上用gzip压缩字符串。。。然后使用iOS版的chilkat框架在iphone上解压(尚未发布,但如果你直接给他发电子邮件就可以使用)


chilkat框架使这项工作变得非常容易,因此开发人员对它竖起了大拇指

我需要使用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;

}  

嗨,吉诃多,谢谢你的回复。如果你在我原来的帖子中选中编辑3,你会看到在我尝试使用你的建议后发生了什么。再次感谢这是一组合理的步骤,所以不清楚的是:传输的字符串是否确实是Base64?(可能)Windows land中原始字符串的原始编码是什么?您在解码时选择了ASCII编码,这不太可能是正确的。NSData缓冲区中的数据能说明一切吗?嗨,你能提供任何到框架的精确链接吗?
#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);
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;

}