Almacenamiento de Datos Básicos NSAttributedString
-
27-09-2019 - |
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
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.
- Seleccione el nombre del atributo y abra el inspector modelo de datos ( Comando + opción + 3 )
- Conjunto
Attribute Type
aTransformable
- Conjunto
Custom Class
aNSAttributedString
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