2010-06-10 16 views
8

J'ai un service web fonctionnant sous Windows Azure qui renvoie le JSON que je consomme dans mon application iPhone. Malheureusement, Windows Azure ne semble pas encore supporter la compression des réponses dynamiques (histoire longue), j'ai donc décidé de contourner ce problème en retournant un paquet JSON non compressé, qui contient une chaîne compressée (en utilisant GZIP).Compresser/décompresser NSString dans l'objectif-c (iphone) en utilisant GZIP ou dégonfler

par exemple

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

... où la valeur est la chaîne compressée d'un objet complexe représenté en JSON. Cela a été très facile à implémenter sur le serveur, mais pour la vie de moi je n'arrive pas à comprendre comment décompresser un NSString gzippé en un NSString non compressé, tous les exemples que je peux trouver pour zlib etc. traitent de fichiers etc.

Quelqu'un peut-il me donner des indices sur la façon de procéder? (Je serais également heureux pour une solution qui utilise deflate car je pourrais changer l'implémentation côté serveur pour utiliser aussi deflate).

Merci!

Steven

Edit 1: Aaah, je vois que ASIHTTPRequest utilise la fonction suivante dans son code source:

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

... et je suis conscient que je peux convertir NSString à NSData, je verrai si cela me mène n'importe où!

Édition 2: Malheureusement, la méthode décrite dans Edit 1 ne m'a conduit nulle part.

Éditer 3: Suivant les conseils ci-dessous concernant le codage/décodage base64, j'ai trouvé le code suivant. Le encodedGzippedString est comme vous pouvez le deviner, une chaîne "Bonjour, mon nom est Steven Elliott" qui est gzippé puis converti en une chaîne base64. Malheureusement, le résultat qui imprime en utilisant NSLog est simplement vide.

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

Répondre

3

Après tout ce temps, j'ai finalement trouvé une solution à ce problème! Aucune des réponses ci-dessus ne m'a aidé, aussi prometteur que tous les regards.Au final, j'ai pu compresser la chaîne sur le serveur avec gzip en utilisant le framework chilkat pour .net ... puis décompresser sur l'iphone en utilisant le framework chilkat pour iOS (pas encore disponible, mais disponible si vous envoyez le gars directement).

Le cadre chilkat a rendu ce super facile à faire si grand bravo au développeur!

+0

Salut, Pouvez-vous fournir un lien exact avec le framework? –

+0

http://www.chilkatsoft.com/downloads_ios.asp – dirkoneill

+0

comment utiliser chilkat framework? –

1

Votre chaîne « compressé » ne sont pas des données brutes gzip, il est dans un codage qui permet à ces octets à stocker dans un string-- ressemble base 64 ou quelque chose comme ça. Pour obtenir un NSData hors de cela, vous devrez le décoder dans le NSData. Si c'est vraiment base-64, consultez ce blog un code d'accompagnement: http://cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html qui fera ce que vous voulez.

Une fois que vous avez un objet NSData, la méthode ASIHTTPRequest fera probablement ce que vous voulez.

+0

Bonjour Quixoto, Merci pour votre réponse. Si vous vérifiez edit 3 dans mon post original, vous verrez ce qui s'est passé après que j'ai essayé plus en utilisant votre conseil. Merci encore –

+0

C'est un ensemble d'étapes raisonnable, donc ce qui n'est pas clair est: la chaîne transmise est-elle définitivement Base64? (probablement) Quel est le codage original de la chaîne originale dans Windows land? Vous choisissez un encodage ASCII sur le décodage, ce qui est peu probable. Est-ce que les données dans le tampon NSData disent du tout? –

0

Cela a fonctionné pour moi: à partir d'une chaîne gzipeed, puis codé base64 à la chaîne non-gzippé (tous 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