存储 NSAttributedString 核心数据

发布于 2024-10-04 08:09:04 字数 925 浏览 0 评论 0原文

我正在尝试将 NSAttributedString 存储到核心数据 SQL 存储中。

我将属性设置为“可转换”,它是可选的,它不是瞬态的或索引的,并且值转换器名称设置为默认的“NSKeyedUnarchiveFromData”。在 .xcdatamodel 中并生成托管对象类,该类在 .h: 中具有此属性

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

,在 .m: 中具有此属性:

@dynamic Text;

我查看并将 NSManagedObject 的“.text”属性设置为属性字符串,然后完成后我执行

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

以下 操作: through 导致输出中出现此错误:

[NSCFTypeencodeWithCoder:]: 无法识别的选择器发送到实例 0xc04edb0 由于以下原因终止应用程序 未捕获的异常 'NSInvalidArgumentException',原因: '* -[NSCFTypeencodeWithCoder:]: 无法识别的选择器发送到实例 0xc04edb0'

我已经检查了我要存储到属性中的内容的类,它是 NSAttributedString 我还检查了 responsesToSelector @selector(:) 并且这返回 true 所以非常困惑这与错误消息相反?

请指教。

谢谢 詹姆斯

I am trying to store an NSAttributedString to a Core Data SQL store.

I have the property set as a "transformable", it is optional and it is NOT transient or indexed and the value transformer name is set to default "NSKeyedUnarchiveFromData". In the .xcdatamodel and generated the managed object class which has this in the .h:

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

and this in the .m:

@dynamic Text;

I look through and set the ".text" property of my NSManagedObject to the attributed string then when completed I do:

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

This through is causing this error in the output:

[NSCFType encodeWithCoder:]:
unrecognized selector sent to instance
0xc04edb0 Terminating app due to
uncaught exception
'NSInvalidArgumentException', reason:
'* -[NSCFType encodeWithCoder:]:
unrecognized selector sent to instance
0xc04edb0'

I have checked the class of what I am storing to the property and it is NSAttributedString also I check responsesToSelector @selector(:) and this returns true so very confused as this is contrary to the error message?

Please advise.

Thanks
James

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

凉宸 2024-10-11 08:09:04

对于遇到此问题的任何人,我找到了最简单的解决方案:

在 Core Data 中添加一个属性,我们将其称为 attributedText。然后将其类型定义为Transformable。创建 .h 文件后,将 attributedText 的数据类型从 NSDictionary 更改为 NSAttributedString

现在您可以将 NSAttributedString 保存在 Core Data 中,无需任何修改。

回忆起来就像走一样简单:

myObject.attributedText

这将返回您的 NSAttributedString

希望这对某人有帮助。

For anyone experiencing this problem I found the easiest solution:

In Core Data add an attribute, let's call it attributedText. Then define its type as Transformable. After you create the .h file, change the data type of attributedText from NSDictionary to NSAttributedString.

Now you can save the NSAttributedString in Core Data with no modification needed.

Recalling it is as easy as going:

myObject.attributedText

which will return your NSAttributedString!

Hope this helps someone.

秋千易 2024-10-11 08:09:04

我在检查Apple开发者论坛并发现了一个与这个问题几乎完全相同的帖子,一个人已经做到了这一点,但不幸的是没有分享代码。他们所说的只是以下内容:

“在 Core Data 中,我在数据库中有一个可转换对象,并且我使用自己的 NSVauleTransformer。这是 NSValueTransformer 的子类,并从数据对象创建一个属性字符串并返回。

因此,我创建了一个名为 PersistableAttributedString 的类,它符合 NSCoding 规范,该类具有一个字符串和一个属性数组,并构建了属性字符串。符合 NSCoding 的文本属性 字符串和属性都符合 NSCoding

NSAttributedString 也是 NSCoding 。 code> 兼容,但属性不兼容,这就是问题所在。”

希望这可能有所帮助。

I was checking the Apple Developer Forums and found a thread almost exactly the same as this question, one person had done this but unfortunately did not share the code. All they said was the following:

"In Core Data i have an transformable in the database and i us my own NSVauleTransformer. This is a subclass of NSValueTransformer and creates an attributed string from the data object and back.

Therefore i created a class called PersistableAttributedString which is NSCoding compliant. This class has a string and an array of attributes and builds the attributed string. I also created a class for the possible text attributes which is NSCoding compliant. Together the string and the attributes are all NSCoding compliant.

The class NSAttributedString is also NSCoding compliant, but the attributes are not, that's the problem."

Hope that might help.

或十年 2024-10-11 08:09:04

在具有自动代码生成功能的 Xcode 10 中,这比其他建议简单得多。

  1. 选择属性的名称并打开数据模型检查器(Command+Option+3
  2. 设置属性类型Transformable
  3. 设置为 自定义类NSAttributedString

Xcode 属性检查器的屏幕截图

就是这样,现在您可以将数据保存在 Swift 中代码如您所料,例如:

detailItem.content = textView.attributedText

In Xcode 10 with automatic code generation this is a lot simpler than the other suggestions.

  1. Select the name of the Attribute and open the Data Model inspector (Command+Option+3)
  2. Set Attribute Type to Transformable
  3. Set Custom Class to NSAttributedString

Screenshot of Xcode attribute inspector

And that's it, now you can just save your data in your Swift code as you'd expect, e.g.:

detailItem.content = textView.attributedText

把人绕傻吧 2024-10-11 08:09:04

另一个想法是创建一个 NSAttributedString 的自定义类,并在某个地方使用 enumerateAttributesInRange:options:usingBlock: 来获取字符串的所有属性,然后保存 NSDictionary 包含核心数据中的属性和范围以及删除其属性的属性字符串。

然后,当再次加载字符串时,您可以使用 initWithString:attributes: 将字典中的属性应用到属性字符串。

Another idea would be to create a Custom Class of NSAttributedString and somewhere use enumerateAttributesInRange:options:usingBlock: to get all the attributes of the string and then save the NSDictionary with the attributes and ranges in to Core Data aswell as the attributed string stripped of it's attributes.

Then when the string is loaded again you could apply the attributes that are in the dictionary to the attributed string using initWithString:attributes:.

冰之心 2024-10-11 08:09:04

正是这种字体让你感到悲伤——CTDictionary 是免费桥接到 NSDictionary 的,NSDictionary 实现了 NSCoding,所以应该可以很好地编码。

您可能必须自己处理字体:( - 这是一种糟糕的方法。1

) 不要存储 NSAttributedString,而是将其分解并将其每个组件放入一个数组中。

2) 遍历数组 - 如果您看到字体引用,则必须仅存储重新创建此字体所需的信息 - 查看 CTFontCopyFontDescriptor 函数,CTFontDescriptorCopyAttribute 函数应该让您以字符串形式获取字体属性。将所有这些放入 NSDictionary 中,该字典应该很好地存储在核心数据中。

3)将此数组存储在核心数据中 - 希望数组中的所有项目都符合 NSCoding 标准,所以应该没问题。

...

要重新创建字符串,当您从 coredata 加载时,如果您看到表示字体属性的 NSDctionary,您应该能够重新创建 fCTFontDescriptor 并从中重新创建字体。

然后,将绳子放回原处。

It's the font that's giving you grief - a CTDictionary is toll-free bridged to NSDictionary which implements NSCoding so should encode fine.

You might have to deal with the font yourself :( - here's a sucky way of doing it.

1) Instead of storing the NSAttributedString, break it down and put each of it's components into an array.

2) Go through the array - if you see font ref you must store just the information required to re-create this font - have a look at the CTFontCopyFontDescriptor function and the CTFontDescriptorCopyAttribute function should let you get font attributes as a string. Put all these into a NSDictionary which should store in core data fine.

3) Store this array in core data - hopefully all the items in the array will be NSCoding compliant so you should be fine.

...

To recreate your string, when you load from coredata, if you see an NSDctionary representing font attributes you should be able to re-create the fCTFontDescriptor and from that the font.

Then, put your string back together.

娇柔作态 2024-10-11 08:09:04

好吧...某种突破,虽然不是一个好的突破...

如果我们 NSLog 属性字符串,那么我们可以看到其中有 NSFont 和 NSParagraphStyle。虽然这些在代码中不是 NSFont 和 NSParagraphStyle,但它们是 CTFontRef 和段落样式的 CT 词典...这些不是 NS 对象,尽管在 NSLog 中它们输出为这些对象,因此猜测这就是为什么我们无法在对象上执行“encodeWithCoder”选择器的原因。

如果在代码中我们只执行“NSFont;”编译器说“NSFont 未声明”,那么我们只有 CT 函数,我们能做什么呢?

正如我的同事在上面的评论中所说,如果我们将“.text”属性设置为“NSAttrinulatedString *string = [NSAttributedString alloc] initWithString:@"test"],它会保存得很好,如果我们从我们想要的样式中删除所有样式保存它也有效!

必须有一种方法可以将 NSATTRIBUTED 字符串存储到核心数据中...不?

非常感谢

-JM 。

OK... Some kind of break through although not a good one...

If we NSLog the attributed string then we can see in there it has NSFont and NSParagraphStyle in. Although these are NOT NSFont and NSParagraphStyle in the code these are CTFontRef and CT Dictionaries of paragraph styles... These are not NS objects although in NSLog they output as these and therefore guess that is why we can not perform the "encodeWithCoder" selector on the object.

IF in the code we just do "NSFont;" the compiler says "NSFont undeclared" so what can we do as we only have the CT functions?

As my colleague said in the comments above if we set the ".text" property to just "NSAttrinutedString *string = [NSAttributedString alloc] initWithString:@"test"] it saves fine and if we remove all the styling from the one we WANT to save it also works!

THERE MUST BE A WAY OF STORING NSATTRIBUTED STRING WITH STYLING INTO CORE DATA... NO?

Any ideas greatly appreciated.

-JM

云之铃。 2024-10-11 08:09:04

我找到了一种在 Swift 4 中保存属性文本的方法,该方法不使用头文件。我的核心数据存储由一个名为“AttrNote”的实体组成,其属性为“标题”和“注释”。 “title”的类型为“String”,但“notes”的类型为“transformable”。然后在完成注释输入/编辑的视图控制器中,我有以下保存按钮:

@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
}

调用加载数据的函数有以下内容:

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

我在 ViewDidLoad 中有以下内容,可以启用 B/I/U选择文本时显示的格式选项:

notesTextView.allowsEditingTextAttributes=true

我可以保存属性文本,然后稍后查看/编辑它。

I found a way to save attributed text in Swift 4 that does not use a header file. My Core Data store consists of an entity called "AttrNote" with attributes of "title" and "notes". "title" is of type "String" but "notes" is of type "transformable". Then within the view controller where note entry/editing is done I have the following for the save button:

@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
}

And the function that is called to load the data has the following:

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

And I have the following in ViewDidLoad that enables the B/I/U formatting options to appear with the selection of text:

notesTextView.allowsEditingTextAttributes=true

I am able to save attributed text and then view/edit it later.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文