2011-01-29 20 views
5

Używam klasy NSXMLParser firmy Apple do ładowania danych. Mam osobne ramy do serializacji moich danych.Konwersja NSString na dane Base64 dla XML Serializacja

Mam już dość długiego kreska, cytaty Word itp. Pojawiające się w moim wyjściu XML i powodujące błędy podczas analizowania, co często skutkuje utratą danych z powodu słabej obsługi tych znaków przez parser.

Jeśli mam dane wejściowe użytkownika jako obiekt NSString, chcę przekonwertować go do Base64 (do którego mam metodę narzędzia), a następnie zapisać te bajty do pliku XML, zamiast NSString. Rozumiem, że może to zająć więcej miejsca, ale przynajmniej nie będę już musiał zajmować się problemami związanymi z weryfikacją.

Moje pytanie brzmi, w jaki sposób można przejść o przekształcenie bajtów NSData (które wyglądają jak <8d72...> w instrukcji NSLog) do NSString, bez użyciu kodowania, aby uzyskać oryginalne wartości powrotem. Chcę, aby te faktyczne bajty, jak pojawiają się w logu, zostały przekonwertowane na NSString. I wreszcie (podczas ładowania to odcinkach danych), jeśli masz NSString:

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

Jak można przejść z tej formy na format czytelny dla człowieka? Cały proces kodowania jest dla mnie trochę trudny do zrozumienia, ale uważam, że jest to naprawdę solidny sposób, aby zapewnić, że dziwne dane wejściowe użytkownika są poprawnie przechowywane w moich plikach XML.

Odpowiedz

11

Rozumiem. Używam metody kodowania/dekodowania z tej odpowiedzi przekonwertować moje obiekty NSString obiektów NSData i vice versa: Any base64 library on iphone-sdk?

a potem napisał te szybkich metod, które sprawiają, że korzystanie z powyższych metod i pozwól mi napisz dane ciągu Base64 do XML. Ładowanie go działa świetnie, zostało przetestowane z chińskimi znakami, znakami Word itp. Możesz je także sparsować, jeśli chcesz, ale przynajmniej błąd nie znajduje się w parserze. (Co może łatwo doprowadzić do utraty danych, jeśli nie obsługuje błędów prawidłowo.)

+ (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: jak oryginalny link jest w dół, ścigani mój kod z jakiś czas temu, tutaj są moje NSStringUtil metody wymienione powyżej. Zauważ, że nie autor tego kodu, ale został on działa dobrze przez lata:

+ (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

Czy musimy importować żadnych ram do korzystania NSStringUtil ???? –

+0

'NSStringUtil' jest klasą, którą napisałem, która po prostu zawiera metody' base64DataFromString: 'i' base64StringFromData: 'opisane w linku w mojej odpowiedzi. –

+0

możesz mi pokazać, że klasa NSStringUtil .... chcę przekonwertować moje base64 na NSString .... ale otrzymuję błąd dla NSStringUtil. –