使用GZIP或deflate压缩/解压缩objective-c(iphone)中的NSString
我有一个在WindowsAzure上运行的web服务,它返回我在iPhone应用程序中使用的JSON 不幸的是,windowsazure似乎还不支持动态响应的压缩(说来话长),所以我决定通过返回一个未压缩的JSON包来绕过它,该包包含一个压缩(使用GZIP)字符串 e、 g 。。。其中value是JSON中表示的复杂对象的压缩字符串 这很容易在服务器上实现,但就我的一生而言,我不知道如何将压缩的NSString解压为未压缩的NSString,我能找到的所有zlib等示例都是处理文件等 有人能告诉我怎么做吗?(我也希望有一个使用deflate的解决方案,因为我可以将服务器端实现也更改为使用deflate) 谢谢 史蒂文 编辑1:aah,我看到ASIHTTPRequest在其源代码中使用了以下函数:使用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等示例都是处理文件等 有人能告诉
//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;
}