ここで私のジレンマを再確認するには、NSFetchedResultsControllerを使用するようにコードをリファクタリングしています。行があるかどうかにかかわらず、いつも表示したい5つのセクションのセットです。私はそれらを表示することにいくらか成功していますが、残念ながら正しいセクションの下に表示される適切な行を得ることができません。 (注:カスタムヘッダーを使用して、ユーザーが特定のセクションにセルを追加するたびに行を追加するボタンを使用しています)。coreDataのモデル関係は、Dogモデルが多くのタスクを持つことができますが、一匹の犬。残念なことに、私は作成したすべてのユニークな "Dog"のすべてのタスクをフェッチしているように見えます。そのため、すべてが同じ情報を持っています。NSFetchedResultsControllerを使用する方法5セクションを表示して適切な行を取得するためにフィルタリングする方法はありますか
NSFetchedResultsControllerに5つのセクションを作成するために使用するタスクモデルと列挙型は次のとおりです。
import Foundation
import CoreData
enum Type: String {
case Meals = "Meals"
case Exercise = "Exercise"
case Health = "Health"
case Training = "Training"
case Misc = "Misc"
}
class Task: NSManagedObject {
static let kClassName = "Task"
convenience init?(title: String, type: Type, isComplete: Bool, context: NSManagedObjectContext = Stack.sharedStack.managedObjectContext) {
guard let entity = NSEntityDescription.entityForName(Task.kClassName, inManagedObjectContext: context) else { return nil }
self.init(entity: entity, insertIntoManagedObjectContext: context)
self.title = title
self.isChecked = isComplete
self.type = type.rawValue
}
}
ここに私のsectionNameKeyPathとしてEnum Typeを渡しているFetchedResultsControllerがあります。 numberOfRowsInSectionで
class TaskController {
static let sharedController = TaskController()
private let kTask = "Task"
var fetchedResultsController: NSFetchedResultsController
var dog: Dog?
init() {
let request = NSFetchRequest(entityName: kTask)
let sortDescriptor1 = NSSortDescriptor(key: "type", ascending: true)
request.sortDescriptors = [sortDescriptor1]
fetchedResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: Stack.sharedStack.managedObjectContext, sectionNameKeyPath: String(Type), cacheName: nil)
_ = try? fetchedResultsController.performFetch()
}
}
Iは、行が最初に作成されるまでfetchedResultsController部が実際には存在しないと仮定していたように、私は機能性部と等しくなるようにsections.countと一致しようとしていますか?正直言って、この時点では、適切なセクションに一致する正しい行をフェッチする方法がわからないので、私は失われています。コメントされたコードは、私がコードをリファクタリングしてNSFetchedResultsControllerの方法に更新する前に、最初に正しいセクションの正しい行を取得していた方法でした。
extension DogDetailViewController: UITableViewDataSource {
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let sections = TaskController.sharedController.fetchedResultsController.sections else { return 0 }
if sections.count > 0 && section < sections.count {
return sections[section].numberOfObjects
}
return 0
// }
// if let dog = self.dog {
// switch section {
// case 0:
// return dog.tasks.filter({$0.type == String(Type.Meals)}).count
// case 1:
// return dog.tasks.filter({$0.type == String(Type.Exercise)}).count
// case 2:
// return dog.tasks.filter({$0.type == String(Type.Health)}).count
// case 3:
// return dog.tasks.filter({$0.type == String(Type.Training)}).count
// case 4:
// return dog.tasks.filter({$0.type == String(Type.Misc)}).count
// default:
// return 0
// }
// } else {
// return 0
// }
}
ご協力ありがとうございます。
@Charles A.さん、ありがとうございます。 NSFetchedResultsControllerの変数割り当てをSections配列の各項目に与えたのは面白いことです。私は単純に私が必要としていた情報を単にフィルタリングするためのNSFetchedResultsControllerを1つだけ必要とすると仮定しました。 –
タスクが特定の型に対して存在しないときにセクション全体を省略したいのであれば、 'NSFetchedResultsController'を使用し、' NSPredicate'の 'type'の制約を省略し、' sectionNameKeyPath '。あなたは常にセクションを望むと考えると、これはより簡単なアプローチだと思う。理想的には、DBエンジンでのフィルタリングは、メモリではなく、そうするのが妥当であるときに述語で行いたいと思っています。 –