2011-01-29 15 views
5

Uso la classe NSXMLParser di Apple per caricare i dati. Ho un quadro separato per la serializzazione dei miei dati.Conversione da NSString a Base64 Data per serializzazione XML

Ne ho abbastanza del trattino lungo, le virgolette di Word, ecc. Che appaiono nel mio output XML e causano errori durante l'analisi, che spesso causano una perdita di dati dovuta alla scarsa gestione di quei caratteri da parte del parser.

Se ho un input dell'utente come oggetto NSString, voglio convertirlo in Base64 (che ho un metodo di utilità per), quindi scrivere quei byte nel file XML, al posto di NSString. Capisco che questo potrebbe richiedere più spazio, ma almeno non avrò più a che fare con i problemi di convalida.

La mia domanda è: come si fa a convertire i byte NSData (che assomigliano <8d72...> in una dichiarazione NSLog) a un NSString, senza utilizzando la codifica per ottenere il valore originale di nuovo. Voglio che quei byte effettivi, come appaiono nell'istruzione del registro, vengano convertiti in una NSString. E infine (durante il caricamento di questi dati serializzati), se si dispone di un NSString:

NSString *loadedData = @"8d72..."; 

Come si fa ad andare da questa forma al formato leggibile? L'intero processo di codifica è un po 'difficile da capire per me, ma penso che questo sia un modo davvero solido per garantire che l'input utente strano sia correttamente conservato nei miei file XML.

risposta

11

Capito. Sto utilizzando i metodi di codifica/decodifica da questa risposta per convertire i miei oggetti NSString agli oggetti NSData, e viceversa: Any base64 library on iphone-sdk?

E poi ho scritto questi metodi rapidi che fanno uso di metodi di cui sopra, e mi permetta di scrivere i dati della stringa Base64 in XML. Caricarlo funziona alla grande, è stato testato con caratteri cinesi, caratteri di Word, ecc. Puoi anche analizzarli se vuoi, ma almeno l'errore non è nel parser. (Che potrebbe facilmente tradursi in perdita di dati se non si gestisce correttamente gli errori.)

+ (NSString *)toBase64String:(NSString *)string { 
    NSData *data = [string dataUsingEncoding: NSUnicodeStringEncoding]; 

    NSString *ret = [NSStringUtil base64StringFromData:data length:[data length]]; 

    return ret; 
} 

+ (NSString *)fromBase64String:(NSString *)string { 
    NSData *base64Data = [NSStringUtil base64DataFromString:string]; 

    NSString* decryptedStr = [[NSString alloc] initWithData:base64Data encoding:NSUnicodeStringEncoding]; 

    return [decryptedStr autorelease]; 
} 

Edit: Come il link originale è giù, ho cacciato giù il mio codice da qualche tempo fa, qui sono i miei Metodi NSStringUtil menzionati sopra. Nota Non ho creato questo codice, ma ha funzionato bene per anni:

+ (NSData *)base64DataFromString: (NSString *)string { 
    unsigned long ixtext, lentext; 
    unsigned char ch, input[4], output[3]; 
    short i, ixinput; 
    Boolean flignore, flendtext = false; 
    const char *temporary; 
    NSMutableData *result; 

    if (!string) { 
     return [NSData data]; 
    } 

    ixtext = 0; 

    temporary = [string UTF8String]; 

    lentext = [string length]; 

    result = [NSMutableData dataWithCapacity: lentext]; 

    ixinput = 0; 

    while (true) { 
     if (ixtext >= lentext) { 
      break; 
     } 

     ch = temporary[ixtext++]; 

     flignore = false; 

     if ((ch >= 'A') && (ch <= 'Z')) { 
      ch = ch - 'A'; 
     } else if ((ch >= 'a') && (ch <= 'z')) { 
      ch = ch - 'a' + 26; 
     } else if ((ch >= '0') && (ch <= '9')) { 
      ch = ch - '0' + 52; 
     } else if (ch == '+') { 
      ch = 62; 
     } else if (ch == '=') { 
      flendtext = true; 
     } else if (ch == '/') { 
      ch = 63; 
     } else { 
      flignore = true; 
     } 

     if (!flignore) { 
      short ctcharsinput = 3; 
      Boolean flbreak = false; 

      if (flendtext) { 
       if (ixinput == 0) { 
        break; 
       } 

       if ((ixinput == 1) || (ixinput == 2)) { 
        ctcharsinput = 1; 
       } else { 
        ctcharsinput = 2; 
       } 

       ixinput = 3; 

       flbreak = true; 
      } 

      input[ixinput++] = ch; 

      if (ixinput == 4) { 
       ixinput = 0; 

       unsigned char0 = input[0]; 
       unsigned char1 = input[1]; 
       unsigned char2 = input[2]; 
       unsigned char3 = input[3]; 

       output[0] = (char0 << 2) | ((char1 & 0x30) >> 4); 
       output[1] = ((char1 & 0x0F) << 4) | ((char2 & 0x3C) >> 2); 
       output[2] = ((char2 & 0x03) << 6) | (char3 & 0x3F); 

       for (i = 0; i < ctcharsinput; i++) { 
        [result appendBytes: &output[i] length: 1]; 
       } 
      } 

      if (flbreak) { 
       break; 
      } 
     } 
    } 

    return result; 
} 

+ (NSString *)base64StringFromData: (NSData *)data length: (NSUInteger)length { 
    unsigned long ixtext, lentext; 
    long ctremaining; 
    unsigned char input[3], output[4]; 
    short i, charsonline = 0, ctcopy; 
    const unsigned char *raw; 
    NSMutableString *result; 

    lentext = [data length]; 

    if (lentext < 1) { 
     return @""; 
    } 

    result = [NSMutableString stringWithCapacity: lentext]; 

    raw = [data bytes]; 

    ixtext = 0; 

    while (true) { 
     ctremaining = lentext - ixtext; 

     if (ctremaining <= 0) { 
      break; 
     } 

     for (i = 0; i < 3; i++) { 
      unsigned long ix = ixtext + i; 

      if (ix < lentext) { 
       input[i] = raw[ix]; 
      } else { 
       input[i] = 0; 
      } 
     } 

     output[0] = (input[0] & 0xFC) >> 2; 
     output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4); 
     output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6); 
     output[3] = input[2] & 0x3F; 

     ctcopy = 4; 

     switch (ctremaining) { 
      case 1: 
       ctcopy = 2; 
       break; 
      case 2: 
       ctcopy = 3; 
       break; 
     } 

     for (i = 0; i < ctcopy; i++) { 
      [result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]]; 
     } 

     for (i = ctcopy; i < 4; i++) { 
      [result appendString: @"="]; 
     } 

     ixtext += 3; 
     charsonline += 4; 

     if ((ixtext % 90) == 0) { 
      [result appendString: @"\n"]; 
     } 

     if (length > 0) { 
      if (charsonline >= length) { 
       charsonline = 0; 

       [result appendString: @"\n"]; 
      } 
     } 
    } 

    return result; 
} 
+1

Dobbiamo importare qualsiasi framework per utilizzare NSStringUtil ???? –

+0

'NSStringUtil' è una classe che ho scritto che contiene semplicemente i metodi' base64DataFromString: 'e' base64StringFromData: 'come descritto nel link nella mia risposta. –

+0

puoi per favore mostrarmi quella classe NSStringUtil .... voglio convertire la mia base64 in NSString .... ma sto ricevendo un errore per NSStringUtil. –