CoreDataと関連するエンティティのセクションに問題があります。私の問題を示すために、私はできるだけ簡単なバージョンのアプリケーションを作った。これは、ファイルをダウンロードしたい場合、そのファイルへのリンクです。 https://www.dropbox.com/s/y7gcpu7qq2mnrye/Sample%20List%20App.zip?dl=0didChangeSectionを呼び出してセクションの更新を強制的に行う方法
これは単なるテーブルビューで、プラスボタンを押すと、数量が1、名前が1、セクションが1の新しい項目が追加されます。次に、セルをクリックするとすべてが増えます。名前と数量の両方がうまく更新されていますが、セクションは決して更新されません。これは、frcがセクションテーブルの変更を追跡していないが、カタログまたは項目テーブルに問題がないためと思われる。私は、アプリケーションを終了し、再び起動すると、セクションが正しく読み込まれます。ここに私の現在のエンティティと(シンプルなアプリの)関係
は以下tableviewcontrollerからのコードです。この小さなで遊んでたら、sectionNameKeyPath
にという名前の最初の関係が直接すなわち(変更された場合。この場合には、あなたが正しいセクションにリンクされている新しいCatalog
を作成する場合didChangeSection
のみが発射される
import UIKit
import CoreData
class TableViewController: UITableViewController, NSFetchedResultsControllerDelegate {
// MARK: - Constants and Variables
let moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
var frc: NSFetchedResultsController = NSFetchedResultsController()
// MARK: - App loading Functions
override func viewDidLoad() {
super.viewDidLoad()
frc = getFCR()
frc.delegate = self
do {
try frc.performFetch()
} catch {
print("Failed to perform inital fetch")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Outlets and Actions
@IBAction func addItemPress(sender: UIBarButtonItem) {
var entityDesc = NSEntityDescription.entityForName("Items", inManagedObjectContext: self.moc)
let item = Items(entity: entityDesc!, insertIntoManagedObjectContext: self.moc)
item.qty = 1
entityDesc = NSEntityDescription.entityForName("Catalog", inManagedObjectContext: self.moc)
let catalog = Catalog(entity: entityDesc!, insertIntoManagedObjectContext: self.moc)
catalog.name = 1
var section: Sections?
if (checkSectionName(0, moc: self.moc) == false) {
entityDesc = NSEntityDescription.entityForName("Sections", inManagedObjectContext: self.moc)
section = Sections(entity: entityDesc!, insertIntoManagedObjectContext: self.moc)
section!.section = 1
} else {
section = returnSection(0, moc: self.moc)
}
item.catalog = catalog
item.catalog!.sections = section
do {
try moc.save()
} catch {
fatalError("New item save failed")
}
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
if let sections = frc.sections {
return sections.count
}
return 0
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let sections = frc.sections {
let currentSection = sections[section]
return currentSection.numberOfObjects
}
return 0
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableViewCell
let item: Items = frc.objectAtIndexPath(indexPath) as! Items
cell.nameLbl.text = "Item #\(item.catalog!.name!)"
cell.qtyLbl.text = "Qty: \(item.qty!.stringValue)"
return cell
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if let sections = frc.sections {
let currentSection = sections[section]
return "Section \(currentSection.name)"
}
return nil
}
func controllerWillChangeContent(controller: NSFetchedResultsController) {
tableView.beginUpdates()
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
tableView.endUpdates()
}
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
switch type {
case NSFetchedResultsChangeType.Update:
self.tableView.reloadSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Automatic)
case NSFetchedResultsChangeType.Delete:
self.tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Automatic)
case NSFetchedResultsChangeType.Insert:
self.tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Automatic)
case NSFetchedResultsChangeType.Move:
self.tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Automatic)
self.tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case NSFetchedResultsChangeType.Update:
self.tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Automatic)
case NSFetchedResultsChangeType.Delete:
self.tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Automatic)
case NSFetchedResultsChangeType.Insert:
self.tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: UITableViewRowAnimation.Fade)
case NSFetchedResultsChangeType.Move:
self.tableView.moveRowAtIndexPath(indexPath!, toIndexPath: newIndexPath!)
}
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let item: Items = frc.objectAtIndexPath(indexPath) as! Items
var qty: Int = Int(item.qty!)
qty = qty + 1
item.qty = qty
var name: Int = Int(item.catalog!.name!)
name = name + 1
item.catalog!.name = name
var sec: Int = Int(item.catalog!.sections!.section!)
sec = sec + 1
var section: Sections?
if (checkSectionName(sec, moc: self.moc) == false) {
let entityDesc = NSEntityDescription.entityForName("Sections", inManagedObjectContext: self.moc)
section = Sections(entity: entityDesc!, insertIntoManagedObjectContext: self.moc)
section!.section = sec
} else {
section = returnSection(sec, moc: self.moc)
}
item.catalog!.sections = section
do {
try moc.save()
} catch {
fatalError("Edit item save failed")
}
}
func fetchRequest() -> NSFetchRequest {
let fetchRequest = NSFetchRequest(entityName: "Items")
let sortDesc1 = NSSortDescriptor(key: "catalog.sections.section", ascending: true)
let sortDesc2 = NSSortDescriptor(key: "catalog.name", ascending: true)
fetchRequest.sortDescriptors = [sortDesc1, sortDesc2]
return fetchRequest
}
func getFCR() -> NSFetchedResultsController {
frc = NSFetchedResultsController(fetchRequest: fetchRequest(), managedObjectContext: moc, sectionNameKeyPath: "catalog.sections.section" , cacheName: nil)
return frc
}
func checkSectionName(sectionName: NSNumber, moc: NSManagedObjectContext) -> Bool {
var exists: Bool = false
let fetchReq = NSFetchRequest(entityName: "Sections")
let pred = NSPredicate(format: "section == %@", sectionName)
fetchReq.predicate = pred
do {
let check = try moc.executeFetchRequest(fetchReq)
for rec in check {
if let name = rec.valueForKey("section") {
if (name as! NSNumber == sectionName) {
exists = true
}
}
}
} catch {
fatalError("Failed fetching records when checking if List name already exists")
}
return exists
}
func returnSection(sectionName: NSNumber, moc: NSManagedObjectContext) -> Sections {
let fetchReq = NSFetchRequest(entityName: "Sections")
let pred = NSPredicate(format: "section == %@", sectionName)
fetchReq.predicate = pred
do {
let check = try moc.executeFetchRequest(fetchReq)
return check.first! as! Sections
} catch {
fatalError("Failed fetching records to return section")
}
}
}
あなたの質問に引用されている例からあなたの現実世界の問題にうまく翻訳できないかもしれない、醜い解決策です。私はそれが助けて欲しい – pbasdf
これは本当に良いアイデアです!私は今夜家に帰るときにそれを撃つつもりです。ありがとう –
爆笑、あなたもこの1つに投稿する必要があります、それは賞金がある場所です。 http://stackoverflow.com/questions/37328774/section-update-event-not-being-called-from-related-entity-in-swift –