Cómo inicializar una cadena desde NSData en Swift


He estado intentando inicializar una cadena desde NSData en Swift.

En la documentación de NSString Cocoa Apple dice que tienes que usar esto:

 init(data data: NSData!, encoding encoding: UInt)

Sin embargo, Apple no incluyó ningún ejemplo de uso o dónde poner el init.

Estoy tratando de convertir el siguiente código de Objective-C a Swift

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

He estado probando muchas sintaxis posibles, como las siguientes (por supuesto que no funcionó):

var string:NSString!
string = init(data: fooData,encoding: NSUTF8StringEncoding)
Author: Anh Pham, 2014-06-03

7 answers

Así es como debe inicializar el NSString:

Swift 2.X o mayor

let datastring = NSString(data: fooData, encoding: NSUTF8StringEncoding)

Swift 3 o más reciente:

let datastring = NSString(data: fooData, encoding: String.Encoding.utf8.rawValue)

Este documento explica la sintaxis.

 213
Author: 67cherries,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-18 19:43:37

Este es el código implementado necesario:

En Swift 3.0:

var dataString = String(data: fooData, encoding: String.Encoding.utf8)

O simplemente

var dataString = String(data: fooData, encoding: .utf8)

Versión anterior de swift:

En Swift 2.0:

import Foundation

var dataString = String(data: fooData, encoding: NSUTF8StringEncoding)

En Swift 1.0:

var dataString = NSString(data: fooData, encoding:NSUTF8StringEncoding)
 275
Author: Sunkas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-23 14:59:13

Swift 2.0

Parece que Swift 2.0 ha introducido el String(data:encoding:) como una extensión de cadena cuando se importa Foundation. No he encontrado ningún lugar donde esto esté documentado, por extraño que parezca.

(pre Swift 2.0) Extensión ligera

Aquí hay una pequeña extensión copy-pasteable sin usar NSString, cortemos el intermediario.

import Foundation

extension NSData
{
    var byteBuffer : UnsafeBufferPointer<UInt8> { get { return UnsafeBufferPointer<UInt8>(start: UnsafeMutablePointer<UInt8>(self.bytes), count: self.length) }}
}

extension String
{
    init?(data : NSData, encoding : NSStringEncoding)
    {
        self.init(bytes: data.byteBuffer, encoding: encoding)
    }
}

// Playground test
let original = "Nymphs blitz quick vex dwarf jog"
let encoding = NSASCIIStringEncoding

if let data = original.dataUsingEncoding(encoding)
{
    String(data: data, encoding: encoding)
}

Esto también le da acceso a data.byteBuffer que es un tipo de secuencia, por lo que todas esas operaciones geniales que puede hacer con secuencias también funcionan, como hacer un reduce { $0 &+ $1 } para una suma de comprobación.

Notas

En mi edición anterior, usé este método:

var buffer = Array<UInt8>(count: data.length, repeatedValue: 0x00)
data.getBytes(&buffer, length: data.length)
self.init(bytes: buffer, encoding: encoding)

El problema con este enfoque, es que estoy creando una copia de la información en una nueva matriz, por lo tanto, estoy duplicando la cantidad de bytes (específicamente: encoding size * data.length)

 14
Author: Can,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-30 18:41:48

Desde la tercera versión de Swift puedes hacer lo siguiente:

let desiredString = NSString(data: yourData, encoding: String.Encoding.utf8.rawValue)

Simialr a lo que Sunkas aconsejó.

 4
Author: Sergey Petrachkov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-09 03:17:38
import Foundation
var string = NSString(data: NSData?, encoding: UInt)
 3
Author: mlask,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-03 19:30:15

Otra respuesta basada en extensiones (chico extraño esto en Java):

extension NSData {
    func toUtf8() -> String? {
        return String(data: self, encoding: NSUTF8StringEncoding)
    }
}

Entonces puedes usarlo:

let data : NSData = getDataFromEpicServer()
let string : String? = data.toUtf8() 

Tenga en cuenta que la cadena es opcional, la inicial NSData puede no ser convertible a Utf8.

 2
Author: elcuco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-02 12:37:17

Objetivo-C

NSData *myStringData = [@"My String" dataUsingEncoding:NSUTF8StringEncoding]; 
NSString *myStringFromData = [[NSString alloc] initWithData:myStringData encoding:NSUTF8StringEncoding];
NSLog(@"My string value: %@",myStringFromData);

Swift

//This your data containing the string
   let myStringData = "My String".dataUsingEncoding(NSUTF8StringEncoding)

   //Use this method to convert the data into String
   let myStringFromData =  String(data:myStringData!, encoding: NSUTF8StringEncoding)

   print("My string value:" + myStringFromData!)

Http://objectivec2swift.blogspot.in/2016/03/coverting-nsdata-to-nsstring-or-convert.html

 0
Author: Tarun Seera,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-16 14:01:20