2016-10-20 52 views
-1

我试图返回具有不同值的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) 
    } 

谢谢你们!

回答

1

如果是我,我会用allTagsRequest填充本地数组,并且有NSFetchedResultsController提要。然后我会让该本地数组提供tableview。

这样,当你需要唯一的列表时,你可以做一些小技巧,将数组转换成NSSet,然后返回数组(这将删除重复项)。当你准备好再次获得整个列表时,你可以从原始文件中重新读取并重新加载tableview。

+0

一些铸造后它像一个魅力工作 - 谢谢! –

0

只是想大声,但如果你设置与resultType到

request.resultType = .dictionaryResultType 

将这个真的管用吗?

let tagDataSource = SortableDataSource<Tag>(fetchRequest: Tag.uniqueTagsRequest,...) 

var results: [SortType] { 
    return fetchedResultsController.fetchedObjects as! [SortType] 
} 

不需额外的fetchedObjects[String:Any]

+0

你说得对 - 这是我的问题的一部分。如果我不制作resultType .dictionaryResultType,那么returnDistinctResults将不起作用。如果我使用.dictionaryResultType,那么我无法填充表格。 –

+0

我想我想知道如何返回不同的结果没有字典结果类型 –