Pregunta

Estoy intentando almacenar una NSAttributedString a un almacén de datos básicos en SQL.

Tengo el conjunto de propiedades como "transformable", es opcional y no es transitoria o indexados y el nombre del transformador valor está configurado como predeterminado "NSKeyedUnarchiveFromData". En el .xcdatamodel y generado la clase de objeto gestionado que tiene esto en el .h:

@property (nonatomic, retain) id Text; (I have tried changing id to NSAttributedString *Text)

y esto en el .m:

@dynamic Text;

Miro a través de y establezca la propiedad ".text" de mi NSManagedObject a la cadena atribuido a continuación, una vez terminado hago:

NSError *error = nil;
[managedObjectContext save:&error];

Esta través de está causando este error en la salida:

  

[NSCFType encodeWithCoder:]:   Selector no reconocido enviado a la instancia   0xc04edb0 de terminación debido a la aplicación   excepción no detectada   'NSInvalidArgumentException', por:   ' * - [NSCFType encodeWithCoder:]:   Selector no reconocido enviado a la instancia   0xc04edb0'

He comprobado la clase de lo que estoy almacenando a la propiedad y es NSAttributedString también verifico responsesToSelector @selector(:) y esto devuelve cierto modo muy confuso ya que esto es contrario al mensaje de error?

Por favor avise.

Gracias James

¿Fue útil?

Solución

Estaba revisando los Foros de desarrolladores Apple y encontró un hilo casi exactamente el mismo que esta pregunta, una persona había hecho esto, pero por desgracia no compartir el código. Todo lo que dijo fue lo siguiente:

"Datos de materias básicas Tengo una transformable en la base de datos y yo nos NSVauleTransformer mi propia. Esta es una subclase de NSValueTransformer y crea una cadena con atributos del objeto de datos y la espalda.

Por lo tanto, he creado una clase llamada PersistableAttributedString que es compatible NSCoding. Esta clase tiene una cadena y un conjunto de atributos y construye la cadena con atributos. También creé una clase para los posibles atributos de texto que es compatible NSCoding. Junto la cadena y los atributos son compatibles NSCoding.

El NSAttributedString clase también NSCoding es compatible, pero los atributos no son, ese es el problema ".

La esperanza que podría ayudar.

Otros consejos

Para cualquier persona que experimenta este problema que encontré la solución más fácil:

En Datos Básicos de añadir un atributo, llamémoslo attributedText. A continuación, defina su tipo que Transformable. Después de crear el archivo .h, cambie el tipo de datos de attributedText de NSDictionary a NSAttributedString.

Ahora usted puede guardar el NSAttributedString en base de datos sin ninguna modificación necesaria.

Recordando que es tan fácil como ir:

myObject.attributedText

que devolverá su NSAttributedString!

Espero que esto ayude a alguien.

En Xcode 10 con generación automática de código que esto es mucho más simple que las otras sugerencias.

  1. Seleccione el nombre del atributo y abra el inspector modelo de datos ( Comando + opción + 3 )
  2. Conjunto Attribute Type a Transformable
  3. Conjunto Custom Class a NSAttributedString

Captura de Xcode inspector atributo

Y eso es todo, ahora sólo puede guardar los datos en su código Swift como era de esperar, por ejemplo:.

detailItem.content = textView.attributedText

Otra idea sería crear una clase personalizada de NSAttributedString y el uso en algún lugar enumerateAttributesInRange:options:usingBlock: para obtener todos los atributos de la cadena y luego guardar los NSDictionary con los atributos y los rangos para datos básicos aswell como la cadena con atributos despojado de sus atributos.

A continuación, cuando la cadena se carga de nuevo se podría aplicar los atributos que están en el diccionario de la cadena con atributos usando initWithString:attributes:.

Es la fuente que está dando que pena -. Un CTDictionary es gratuito puenteados a NSDictionary que implementa NSCoding por lo que debe codificar bien

Puede que tenga que hacer frente a la fuente usted mismo :( -. Aquí está una manera de hacerlo va a trompicones

1) En lugar de almacenar la NSAttributedString, descomponerlo y poner cada uno de sus componentes en una matriz.

2) Ir a través de la matriz - si usted ve la fuente ref debe almacenar sólo la información necesaria para volver a crear este tipo de letra - echar un vistazo a la función CTFontCopyFontDescriptor y la función CTFontDescriptorCopyAttribute debe dejar que se obtiene atributos de fuente como una cadena. Poner todo esto en un NSDictionary que debe almacenar in fine de datos básicos.

3) Almacenar esta matriz en datos básicos -. Esperemos que todos los elementos de la matriz será compatible NSCoding por lo que debe estar bien

...

Para volver a crear la cadena, cuando se carga desde coredata, si ves a un tipo de letra que representa NSDctionary atributos que debe ser capaz de recrear el fCTFontDescriptor y desde que la fuente.

Luego, se coloca la cadena de nuevo juntos.

He encontrado una manera de salvar texto atribuido en Swift 4 que no utiliza un archivo de cabecera. Mi almacén de datos básicos se compone de una entidad llamada "AttrNote" con atributos de "Título" y "notas". "Título" es de tipo "String" pero "notas" es de tipo "transformable". A continuación, en el controlador de vista donde la entrada nota / edición se realiza Tengo el siguiente para el botón Guardar:

@IBAction func saveBtn(_ sender: Any) {

var note: AttrNote!

//other code

if let title = titleTextField.text {
note.title = title
}
if let noteText = notesTextView.attributedText {
note.notes = noteText
}

Y la función que se llama para cargar los datos tiene el siguiente:

func loadNoteData() {
if let note = noteToEdit {
titleTextField.text = note.title
notesTextView.attributedText = note.notes as! NSAttributedString
}
}

Y tengo la siguiente en viewDidLoad que permite que el B / I / T opciones de formato para aparecer con la selección de texto:

notesTextView.allowsEditingTextAttributes=true

Soy capaz de guardar texto atribuido a continuación, ver / editar más tarde.

OK ... Una especie de ruptura a través aunque no es una buena ...

Si NSLog la cadena atribuido a continuación, podemos ver ahí Tiene NSFont y NSParagraphStyle. Aunque estos no son NSFont y NSParagraphStyle en el código son CTFontRef y CT Diccionarios de estilos de párrafo ... Estos no son objetos NS aunque NSLog en que la salida como estos y por lo tanto, supongo que es por eso que no podemos realizar el selector "encodeWithCoder" en el objeto.

Si en el código acabamos de hacer "NSFont;" el compilador dice "NSFont no declarada" por lo que lo podemos hacer ya que sólo tenemos las funciones TC?

Como dijo mi colega en los comentarios anteriores si establecemos la propiedad ".text" a sólo 'NSAttrinutedString * cadena = [NSAttributedString alloc] initWithString: @' prueba "] se ahorra bien y si quitamos todo el estilo de la uno que desea guardar también funciona!

Tiene que haber una manera de almacenar NSATTRIBUTED CADENA con un estilo en el núcleo DATOS NO ...?

Cualquier ideas muy apreciada.

-JM

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top