NSFetchedResultsController not sorting on encrypted attributes

北慕城南 提交于 2020-01-04 03:52:26

问题


I am trying to encrypt the attributes in my Core Data model using the transformable type but am experiencing a lot of issues trying to fetch back results once data has been persisted to the sqlite db. My main application for Core Data is to store some user related data and fetch it back again sorted by first name, last name etc and then display it in a table view using the first letter of first/last name as the section header. It seems that the encryption is interfering with the results because i get nothing back when i try to do fetch request with NSFetchedResultsController using the lastName as a sort descriptor. I get the following error:

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

Ive spent a lot of time investigating this issue to no avail. Does anybody know what the issue might be and how to get around it? Is there perhaps a way to do the sort on the db after the transformer decrypts the data? Or is there a way to maybe get back the raw data and then sort it after i have the data in an instance of the NSFetchedResultsController?

I used this source to encrypt the core data attribute:


回答1:


There is some relevant information in the "Core Data Programming Guide".

  • Fetching Managed Objects:

You cannot fetch using a predicate based on transient properties (although you can use transient properties to filter in memory yourself). ... To summarize, though, if you execute a fetch directly, you should typically not add Objective-C-based predicates or sort descriptors to the fetch request. Instead you should apply these to the results of the fetch.

  • Fetch Predicates and Sort Descriptors:

There are some interactions between fetching and the type of store. ... The SQL store, on the other hand, compiles the predicate and sort descriptors to SQL and evaluates the result in the database itself. This is done primarily for performance, but it means that evaluation happens in a non-Cocoa environment, and so sort descriptors (or predicates) that rely on Cocoa cannot work.

Since the transformer is applied to the data after fetching it from the SQLite store, using a transformed attribute as sort key will not produce the desired result.

Your Core Data error is probably caused by the fact that the sections are sorted using the encrypted data, but the sectionNameKeyPath of the FRC (which can be a transient attribute) gives the unencrypted data, which of course is inconsistent.

The only solution I can imagine is to store an additional unencrypted attribute that has enough information to be used as sort key (e.g. the person's initial letter).




回答2:


To the best of my knowledge, NSFetchRequest (when you use sqlite via CoreData) generates sql, use it on sqlite and returns result. So, while sqlite know nothing about your decrypting made by CoreData, it is impossible to sort result with NSFetchRequest using decrypted data.

Possible solution is to copy the result of NSFetchRequest into NSArray and do the sort over your encrypted fields manually. Another solution is to sort your data on every insert or modification and write the order to specific integer field and then while fetching sort over this field (it will save your performance if you do inserts and modification less frequent than fetching).




回答3:


The error you describe happens because sorting happens on the encrypted data in the database, but the NSFetchedResultsController later works on unencrypted data, and complains because the data is not sorted correctly for the section name.

To sort inside the db you would have to provide enough unencrypted info to sort, and to keep that info up-to-date.

For example, for sorting by first name, you could store an unencrypted attribute firstNameSection which contains the first letter of the firstName, and an attribute firstNameSortInfo which contains the position of that name for each index (for example "Aaron"=0, "Abby"=1, etc.

Then you could use firstNameSection and firstNameSortInfo for sorting, and firstNameSection as sectionNameKeyPath. This approach has (at least) two drawbacks:

  1. You would have to keep the firstNameSortInfo up-to-date, and this would need more writes than you may like, and the firstNameSortInfo sorting would have to be done in-memory (as it is done on unencrypted data).
  2. Some info about the encrypted data may be known to a potential attacker, which may weaken the encryption.


来源:https://stackoverflow.com/questions/12845831/nsfetchedresultscontroller-not-sorting-on-encrypted-attributes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!