2016-10-20 51 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

我想我想知道如何返回不同的結果沒有字典結果類型 –