3

我正在尝试使用可转换类型来加密我的核心数据模型中的属性,但是一旦数据被持久化到 sqlite db,尝试取回结果时遇到了很多问题。我的核心数据的主要应用程序是存储一些与用户相关的数据并按名字、姓氏等排序再次将其取回,然后使用名字/姓氏的第一个字母作为部分标题将其显示在表格视图中。似乎加密干扰了结果,因为当我尝试使用 NSFetchedResultsController 使用 lastName 作为排序描述符来获取请求时,我什么也没得到。我收到以下错误:

CoreData: error: (NSFetchedResultsController) The fetched object at index X has an out of order section name 'S. Objects must be sorted by section name'

我花了很多时间调查这个问题无济于事。有谁知道问题可能是什么以及如何解决它?变压器解密数据后,是否有办法对数据库进行排序?或者有没有办法可以取回原始数据,然后在我将数据放在 NSFetchedResultsController 的实例中之后对其进行排序?

我使用这个源来加密核心数据属性:

4

3 回答 3

1

《Core Data Programming Guide》中有一些相关信息。

您不能使用基于瞬态属性的谓词进行获取(尽管您可以使用瞬态属性自己在内存中进行过滤)。...总而言之,如果您直接执行 fetch,则通常不应将基于 Objective-C 的谓词或排序描述符添加到 fetch 请求中。相反,您应该将这些应用于获取的结果。

获取和存储类型之间存在一些交互。...另一方面,SQL 存储将谓词和排序描述符编译为 SQL,并在数据库本身中评估结果。这样做主要是为了性能,但这意味着评估发生在非 Cocoa 环境中,因此依赖 Cocoa 的排序描述符(或谓词)无法工作。

由于转换器是在从 SQLite 存储中获取数据后应用于数据的,因此使用转换后的属性作为排序键将不会产生所需的结果。

您的核心数据错误可能是由于这些部分是使用加密数据排序的,但是sectionNameKeyPathFRC 的(可以是临时属性)给出了未加密的数据,这当然是不一致的。

我能想象的唯一解决方案是存储一个额外的未加密属性,该属性有足够的信息用作排序键(例如人的首字母)。

于 2012-10-16T18:40:28.097 回答
1

您描述的错误发生是因为排序发生在数据库中的加密数据上,但NSFetchedResultsController后者适用于未加密的数据,并抱怨因为数据未针对部分名称正确排序。

要在数据库中排序,您必须提供足够的未加密信息进行排序,并保持该信息是最新的。

例如,对于按名字排序,您可以存储一个firstNameSection包含 的第一个字母的未加密属性firstName,以及一个firstNameSortInfo包含每个索引的名称位置的属性(例如“Aaron”=0,“Abby”=1 , ETC。

然后你可以使用firstNameSectionandfirstNameSortInfo进行排序,而firstNameSectionas sectionNameKeyPath。这种方法(至少)有两个缺点:

  1. 您必须保持firstNameSortInfo最新,这将需要比您想要的更多的写入,并且firstNameSortInfo必须在内存中进行排序(因为它是在未加密的数据上完成的)。
  2. 潜在攻击者可能知道有关加密数据的一些信息,这可能会削弱加密。
于 2012-10-19T22:06:23.170 回答
1

据我所知,NSFetchRequest(当您通过 CoreData 使用 sqlite 时)生成 sql,在 sqlite 上使用它并返回结果。因此,虽然 sqlite 对 CoreData 进行的解密一无所知,但不可能使用 NSFetchRequest 使用解密的数据对结果进行排序。

可能的解决方案是将 NSFetchRequest 的结果复制到 NSArray 并手动对加密字段进行排序。另一种解决方案是在每次插入或修改时对数据进行排序,并将顺序写入特定的整数字段,然后在对该字段进行排序时(如果您执行插入和修改的频率低于获取频率,它将节省您的性能)。

于 2012-10-20T19:20:35.860 回答