8
votes

Compresser / décompresser Nstring dans l'objectif-C (iPhone) en utilisant gzip ou dégonfler

J'ai un service Web exécuté sur Windows Azure qui retourne JSON que je consomme dans mon application iPhone.

Malheureusement, Windows Azure ne semble pas supporter la compression des réponses dynamiques (longue histoire) alors j'ai donc décidé Pour le contourner en renvoyant un package JSON non compressé, qui contient une chaîne compressée (GZIP).

par exemple xxx

... où la valeur est la chaîne compressée d'un objet complexe représenté dans JSON.

Ceci était vraiment Facile à mettre en œuvre sur le serveur, mais pour la vie de moi, je ne peux pas comprendre comment décompresser une nstring gzippé dans une nstring non compressée, tous les exemples que je peux trouver pour zlib, etc. traitent des fichiers, etc. < P> Quelqu'un peut-il me donner des indices sur la façon de faire cela? (Je serais également heureux pour une solution utilisée de déflate, car je pourrais modifier la mise en œuvre du côté serveur pour utiliser également déflate).

merci !!

Steven

EDIT 1: AAAH, je vois que ASIHTTPRequest utilise la fonction suivante dans son code source: xxx ... et je ' J'ai conscient que je peux convertir Nstring en Nsdata, donc je verrai si cela me conduit n'importe où!

Edit 2: Malheureusement, la méthode décrite dans Edition 1 n'a pas conduit Moi n'importe où.

Edit 3: Suivre le conseil ci-dessous concernant le codage / décodage de base64, j'ai proposé le code suivant. Le codedgzippedstring est que vous pouvez deviner, une chaîne "Bonjour, mon nom est Steven Elliott" qui est gzippé puis converti en une chaîne de base64. Malheureusement, le résultat qui imprime à l'aide de NSLog est juste vide. xxx


0 commentaires

4 Réponses :


1
votes

Votre chaîne "compressée" n'est pas des données brutes GZIP'D, c'est dans certains codages qui permettent à ces octets d'être stockés dans une chaîne-- ressemble à la base-64 ou quelque chose comme ça. Pour obtenir une nsdata en dehors de cela, vous aurez besoin de le décoder dans les Nsdata.

Si c'est vraiment base-64, consultez ce blog poster un code d'accompagnement: http://cocoawithlove.com/2009/06/ Base64-coding-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 comme vous le souhaitez.


2 commentaires

Bonjour Quixoto, merci pour votre réponse. Si vous cochez la modification 3 dans mon message d'origine, vous verrez ce qui s'est passé après avoir essayé d'autres en utilisant vos conseils. Merci encore


C'est un ensemble raisonnable d'étapes, donc ce qui n'est pas clair est: est la chaîne transmise définitivement base64? (probablement) Quel est le codage d'origine de la chaîne d'origine dans Windows Terre? Vous choisissez un codage ASCII sur le décodage, ce qui est peu susceptible d'être correct. Les données du tampon Nsdata en disent-elles du tout?



0
votes

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


0 commentaires

4
votes

Après tout ce temps, j'ai enfin trouvé une solution à ce problème!

Aucune des réponses ci-dessus m'a aidé, aussi prometteuse que toutes les yeux. En fin de compte, j'ai pu compresser la chaîne sur le serveur avec GZIP à l'aide de la framework de Chilkat pour .NET ... et décompressez-le sur l'iPhone à l'aide de la framework Chilkat pour iOS (pas encore publié, mais disponible si vous envoyez un courrier électronique au courrier électronique. gars directement).

Le framework de Chilkat a rendu ce super facile à faire si gros pouces jusqu'au développeur!


1 commentaires

Bonjour, pouvez-vous fournir un lien exact au cadre?



0
votes

J'ai besoin de compresser des données sur l'iPhone à l'aide de l'objectif-C et de décompresser sur PHP. Voici ce que j'ai utilisé dans Xcode 11.5 et iOS 12.4:

Test de décompression de compression de l'objectif iOS Inclure libcompression.tbd dans les phases de construction -> Link binaire avec la bibliothèque. Ensuite, incluez l'en-tête. P> xxx pré>

sur le côté PHP, j'ai utilisé la fonction suivante pour décompresser les données: p>

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;

}  


0 commentaires