2010-06-10 123 views
8

我有一個在Windows Azure上運行的Web服務,它返回我在iPhone應用程序中使用的JSON。不幸的是,Windows Azure似乎不支持壓縮動態響應(長篇故事),所以我決定通過返回一個包含壓縮(使用GZIP)字符串的未壓縮JSON包來繞過它。在使用GZIP或deflate的objective-c(iphone)中壓縮/解壓縮NSString

e.g

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

...其中值是在JSON表示的複合物的壓縮字符串。

這真的很容易在服務器上實現,但對於我的生活,我無法弄清楚如何將壓縮後的NSString解壓縮爲未壓縮的NSS​​tring,我可以找到zlib等的所有示例都處理文件等

任何人都可以給我任何線索如何做到這一點? (我也很樂意使用deflate的解決方案,因爲我可以將服務器端實現改爲使用deflate)。

謝謝!

史蒂芬

編輯1:啊哈,我看到ASIHTTPRequest在它使用下面的函數的源代碼:

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

...和我知道,我可以轉換的NSString NSData,所以我會看看這是否導致我的任何地方!

編輯2:不幸的是,編輯1中描述的方法並沒有引導我到任何地方。

編輯3:根據以下關於base64編碼/解碼的建議,我想出了以下代碼。 encodedGzippedString就像你猜測的那樣,是一個字符串「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); 

回答

3

畢竟這段時間,我終於找到了解決這個問題的辦法!

上面的答案都沒有幫助我,因爲他們都看起來很有希望。最後,我可以使用chilkat framework for .net ...在服務器上壓縮字符串,然後使用iOS的chilkat框架在iphone上解壓縮它(尚未發佈,但如果通過電子郵件發送直接)。

奇爾卡特框架使得這非常容易做到這樣大開發商的大拇指!

+0

嗨,你能提供任何確切的鏈接到框架? – 2013-10-04 15:24:22

+0

http://www.chilkatsoft.com/downloads_ios.asp – dirkoneill 2013-11-27 00:35:40

+0

如何使用chilkat框架? – 2014-11-05 06:29:44

1

你「壓縮」字符串不是原始數據gzip壓縮,它在一些編碼,使這些字節存儲在一個string--看起來像基地-64或類似的東西。爲了得到一個NSData,你需要將它解碼成NSData。

如果它真的是base-64,請查看此博客文章隨附的代碼: http://cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html 這將做你想做的。

一旦你有一個NSData對象,ASIHTTPRequest方法可能會隨你喜歡。

+0

Hi Quixoto, 感謝您的回覆。如果您在原始文章中查看編輯3,您會看到發生了什麼後,我嘗試了更多使用您的建議。 再次感謝 – 2010-06-15 23:09:13

+0

這是一組合理的步驟,所以不清楚的是:傳輸的字符串是否是Base64? (可能)Windows域中原始字符串的原始編碼是什麼?您正在解碼上選擇ASCII編碼,這不太可能是正確的。 NSData緩衝區中的數據是否可以說明? – 2010-06-16 01:08:32

0

這工作對我來說: 從字符串gzipeed,然後base64編碼 到un-gzipped字符串(所有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