NSFetchRequest
を別の値で返そうとしています。 - でも、重複NSFetchRequestのユニークな結果を得る
class Tag: NSManagedObject {
static let entityName = "\(Tag.self)"
static var allTagsRequest: NSFetchRequest<NSFetchRequestResult> = {
let request = NSFetchRequest<NSFetchRequestResult>(entityName: Tag.entityName)
request.sortDescriptors = [NSSortDescriptor(key: "title", ascending: true)]
return request
}()
static var uniqueTagsRequest: NSFetchRequest<NSFetchRequestResult> = {
let request = NSFetchRequest<NSFetchRequestResult>(entityName: Tag.entityName)
request.sortDescriptors = [NSSortDescriptor(key: "title", ascending: true)]
request.resultType = .dictionaryResultType
request.returnsDistinctResults = true
return request
}()
}
allTagsRequest
戻って適切に、すなわち、それはCoreDataに保存されているすべてのタグを返します。これは私が持っているものです。私はuniqueTagsRequest
が一意のタグだけを返すようにしたいが、そうした場合、tableViewは設定されない。ここに私のtableViewコードは次のとおりです。
class SortableDataSource<SortType: CustomTitleConvertible>: NSObject, UITableViewDataSource where SortType: NSManagedObject {
let kReuseIdentifier = "sortableItemCell"
fileprivate let fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>
var results: [SortType] {
return fetchedResultsController.fetchedObjects as! [SortType]
}
init(fetchRequest: NSFetchRequest<NSFetchRequestResult>, managedObjectContext moc: NSManagedObjectContext) {
self.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)
super.init()
executeFetch()
}
func executeFetch() {
do {
try fetchedResultsController.performFetch()
} catch let error as NSError {
let alertController = UIAlertController(
title: "Error",
message: "\(error.debugDescription)",
preferredStyle: .alert)
let okAction = UIAlertAction(
title: "Ok",
style: .cancel,
handler: nil)
alertController.addAction(okAction)
UIApplication.topViewController()?.present(alertController, animated: true, completion: nil)
}
}
//MARK: - UITableViewDataSource
func numberOfSections(in tableView: UITableView) -> Int { return 2 }
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
case 0: return 1
case 1: return fetchedResultsController.fetchedObjects?.count ?? 0
default: return 0
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: kReuseIdentifier)
cell.selectionStyle = .none
switch (indexPath.section, indexPath.row) {
case (0, 0):
cell.textLabel?.text = "All \(SortType.self)s"
cell.accessoryType = .checkmark
case (1, _):
guard let sortItem = fetchedResultsController.fetchedObjects?[indexPath.row] as? SortType else { break}
cell.textLabel?.text = sortItem.title
default: break
}
return cell
}
}
とコントローラを並べ替える:
@objc fileprivate func presentSortController() {
let tagDataSource = SortableDataSource<Tag>(fetchRequest: Tag.uniqueTagsRequest, managedObjectContext: CoreDataController.sharedInstance.managedObjectContext)
let sortItemSelector = SortItemSelector(sortItems: tagDataSource.results)
let sortController = PhotoSortListController(dataSource: tagDataSource, sortItemSelector: sortItemSelector)
sortController.onSortSelection = { checkedItems in
if !checkedItems.isEmpty {
var predicates = [NSPredicate]()
for tag in checkedItems {
let predicate = NSPredicate(format: "%K CONTAINS %@", "tags.title", tag.title)
predicates.append(predicate)
}
let compoundPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: predicates)
self.dataSource.performFetch(withPredicte: compoundPredicate)
} else {
self.dataSource.performFetch(withPredicte: nil)
}
}
let navController = UINavigationController(rootViewController: sortController)
present(navController, animated: true, completion: nil)
}
みんなありがとう!
キャスト後、それは魅力のように機能しました - ありがとう! –