8

Windows Azureで実行されているWebサービスがあり、iPhoneアプリで使用するJSONを返します。

残念ながら、Windows Azureはまだ動的応答の圧縮をサポートしていないようです(長い話)ので、圧縮された(GZIPを使用した)文字列を含む非圧縮のJSONパッケージを返すことで回避することにしました。

例えば

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

...ここで、valueは、JSONで表される複雑なオブジェクトの圧縮された文字列です。

これはサーバーに実装するのは本当に簡単でしたが、私の人生では、gzipで圧縮されたNSStringを非圧縮のNSStringに解凍する方法を理解できません。zlibなどで見つけることができるすべての例は、ファイルなどを扱っています。

誰かが私にこれを行う方法についての手がかりを与えることができますか?(サーバー側の実装をdeflateを使用するように変更できるので、deflateを使用したソリューションにも満足しています)。

ありがとう!!

スティーブン

編集1:ああ、ASIHTTPRequestがソースコードで次の関数を使用していることがわかります。

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

...そしてNSStringをNSDataに変換できることを知っているので、これが私をどこにでも導くかどうかを確認します!

編集2:残念ながら、編集1で説明した方法では、どこにもつながりませんでした。

編集3: base64のエンコード/デコードに関する以下のアドバイスに従って、次のコードを思いつきました。encodeGzippedStringは、ご想像のとおり、gzipで圧縮されてbase64文字列に変換される文字列「こんにちは。私の名前はStevenElliottです」です。残念ながら、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

4 に答える 4

4

結局、私はついにこの問題の解決策を見つけました!

上記の答えはどれも私を助けませんでした、彼ら全員が見たのと同じくらい有望でした。結局、.net用のchilkatフレームワークを使用してgzipでサーバー上の文字列を圧縮し、iOS用のchilkatフレームワークを使用してiphoneで解凍することができました(まだリリースされていませんが、電子メールで送信すると利用可能になります男直接)。

チルカットフレームワークにより、開発者はこれを非常に簡単に行うことができます。

于 2011-04-07T21:44:22.477 に答える
1

「圧縮された」文字列は生のGZIPされたデータではなく、それらのバイトを文字列に格納できるようにするエンコードになっています。base-64などのように見えます。これからNSDataを取得するには、NSDataにデコードする必要があります。

それが本当にbase-64である場合は、このブログ投稿に付随するコードを確認してください:http: //cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html これはあなたが望むことをします。

NSDataオブジェクトを取得すると、ASIHTTPRequestメソッドはおそらくお好みで動作します。

于 2010-06-14T22:37:09.147 に答える
0

これは私にとってはうまくいきました:gzipで圧縮された文字列から、gzipで圧縮されていない文字列(すべてutf8)にbase64でエンコードされました。

#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
于 2010-10-01T13:40:35.020 に答える
0

Objective-cを使用してiPhoneでデータを圧縮し、PHPで解凍する必要がありました。XCode11.5とiOS12.4で使用したものは次のとおりです。

iOSObjective-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;

}  
于 2020-09-28T03:34:41.323 に答える