我在Windows Azure上运行了一个Web服务,它返回我在iPhone应用程序中使用的JSON。
不幸的是,Windows Azure似乎还不支持动态响应的压缩(长篇故事)所以我决定通过返回一个未压缩的JSON包来解决它,它包含一个压缩的(使用GZIP)字符串。
e.g
{"Error":null,"IsCompressed":true,"Success":true,"Value":"vWsAAB+LCAAAAAAAB..etc.."}
...其中value是以JSON表示的复杂对象的压缩字符串。
这在服务器上很容易实现,但是对于我的生活,我无法弄清楚如何将压缩的NSString解压缩为未压缩的NSString,我可以为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);
答案 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;
}