Pregunta Convierta NSData codificado en UTF-8 a NSString


Tengo codificado UTF-8 NSData desde el servidor de Windows y quiero convertirlo a NSString para Iphone. Como los datos contienen caracteres (como un símbolo de grado) que tienen valores diferentes en ambas plataformas, ¿cómo convierto datos a cadena?


547
2018-03-18 06:17


origen


Respuestas:


Si los datos no tienen terminación nula, debe usar -initWithData:encoding:

NSString* newStr = [[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding];

Si los datos tienen terminación nula, en su lugar debe usar -stringWithUTF8String: para evitar el extra \0 al final.

NSString* newStr = [NSString stringWithUTF8String:[theData bytes]];

(Tenga en cuenta que si la entrada no está codificada en UTF-8 correctamente, obtendrá nil.)


Variante Swift:

let newStr = String(data: data, encoding: .utf8)
// note that `newStr` is a `String?`, not a `String`.

Si los datos son terminados en nulo, puedes ir por la ruta segura que es eliminar el carácter nulo, o la forma insegura similar a la versión anterior de Objective-C.

// safe way, provided data is \0-terminated
let newStr1 = String(data: data.subdata(in: 0 ..< data.count - 1), encoding: .utf8)
// unsafe way, provided data is \0-terminated
let newStr2 = data.withUnsafeBytes(String.init(utf8String:))

1120
2018-03-18 06:20



Puedes llamar a este método

+(id)stringWithUTF8String:(const char *)bytes.

28
2018-03-18 06:25



Humildemente presento una categoría para que esto sea menos molesto:

@interface NSData (EasyUTF8)

// Safely decode the bytes into a UTF8 string
- (NSString *)asUTF8String;

@end

y

@implementation NSData (EasyUTF8)

- (NSString *)asUTF8String {
    return [[NSString alloc] initWithData:self encoding:NSUTF8StringEncoding];    
}

@end

(Tenga en cuenta que si no está utilizando ARC necesitará una autorelease ahí.)

Ahora en lugar de lo terriblemente detallado:

NSData *data = ...
[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

Tu puedes hacer:

NSData *data = ...
[data asUTF8String];

19
2017-10-01 23:04



La versión de Swift de String a Data y de vuelta a String:

Xcode 9 • Swift 4

extension Data {
    var string: String {
        return String(data: self, encoding: .utf8) ?? ""
    }
}
extension String {
    var data: Data {
        return Data(utf8)
    }
    var base64Decoded: Data? {
        return Data(base64Encoded: self)
    }
}

Patio de recreo

let string = "Hello World"                                  // "Hello World"
let stringData = string.data                                // 11 bytes
let base64EncodedString = stringData.base64EncodedString()  // "SGVsbG8gV29ybGQ="
let stringFromData = stringData.string                      // "Hello World"

let base64String = "SGVsbG8gV29ybGQ="
if let data = base64String.base64Decoded {
    print(data)                                    //  11 bytes
    print(data.base64EncodedString())              // "SGVsbG8gV29ybGQ="
    print(data.string)                             // "Hello World"
}

let stringWithAccent = "Olá Mundo"                          // "Olá Mundo"
print(stringWithAccent.count)                               // "9"
let stringWithAccentData = stringWithAccent.data            // "10 bytes" note: an extra byte for the acute accent
let stringWithAccentFromData = stringWithAccentData.string  // "Olá Mundo\n"

15
2018-02-15 03:51



A veces, los métodos en las otras respuestas no funcionan. En mi caso, estoy generando una firma con mi clave privada RSA y el resultado es NSData. Descubrí que esto parece funcionar:

C objetivo

NSData *signature;
NSString *signatureString = [signature base64EncodedStringWithOptions:0];

Rápido

let signatureString = signature.base64EncodedStringWithOptions(nil)

14
2018-05-19 23:42



Solo para resumir, aquí hay una respuesta completa, que funcionó para mí.

Mi problema era que cuando usaba

[NSString stringWithUTF8String:(char *)data.bytes];

La cadena que obtuve fue impredecible: alrededor del 70% contenía el valor esperado, pero con demasiada frecuencia resultó con Null o incluso peor: con el bagaje al final de la cadena.

Después de cavar, cambié a

[[NSString alloc] initWithBytes:(char *)data.bytes length:data.length encoding:NSUTF8StringEncoding];

Y obtuve el resultado esperado todo el tiempo.


1
2017-11-29 18:52