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

ただ、大声で考えていますが、

request.resultType = .dictionaryResultType 

にresultTypeとを設定している場合、これは実際に動作しますか? fetchedObjects Won't

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

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

[String:Any]のこと?

+0

あなたは正しいです - それは私の問題の一部です。 resultType .dictionaryResultTypeを作成しないと、returnDistinctResultsは機能しません。 .dictionaryResultTypeを使用すると、テーブルに値を設定できません。 –

+0

私はdictionaryResultTypeなしで別個の結果を返す方法を考えていると思います。 –

関連する問題