数据库中以段标题的一条记录填充数据库,它与多(UserInstruction)到一个(SectionHeading)关系,“ fetchedResultsController.sections”返回nil
致命错误:未正确配置FRC:文件/Users/tae/Documents/Assignments/BrickMatcherV5/BrickMatcherV5/Controllers/InformationViewController.swift,第101行
2019-12-18 18:18:18.406622 + 0000 BrickMatcherV5 [3924:121317]致命错误:未正确配置FRC:文件/Users/tae/Documents/Assignments/BrickMatcherV5/BrickMatcherV5/Controllers/InformationViewController.swift,第101行
import UIKit
import CoreData
class InformationViewController: UITableViewController {
let cellId = "sdlfjowieurewfn34898442249sd;ds;lfkds;f47824dslaksjfs;ad"
var model: UserInstructionsModel!
let defaults = UserDefaults.standard
var networkManager = NetworkManager.shared
var instructionURLComponents = URLComponents()
// Create a reference to the CoreData Stack
private let cdStack = CoreDataStack.shared
// The all mighty FetchedResultsController
fileprivate lazy var fetchedResultsController: NSFetchedResultsController <UserInstruction> = {
let fetchRequest:NSFetchRequest = UserInstruction.fetchRequest()
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "sectionHeading.name", ascending: true),
NSSortDescriptor(key: "rowOrder", ascending: true)]
//managedObjectContext is your instance of NSManagedObjectContext
let fetchedResultsContoller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: CoreDataStack.shared.mainContext, sectionNameKeyPath: "sectionHeading.name", cacheName: nil)
fetchedResultsContoller.delegate = self
return fetchedResultsContoller
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
navigationItem.title = "How To Use"
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)
tableView.register(SubtitleTableViewCell.self, forCellReuseIdentifier: cellId)
tableView.tableFooterView = UIView(frame: CGRect.zero)
model = UserInstructionsModel(coreDataStack: CoreDataStack.shared)
fetchHelpInstructions()
do {
try fetchedResultsController.performFetch()
print("try done")
} catch let fetchError {
print("Fetch Error: \(fetchError.localizedDescription)")
}
// Set the Show Help Screen Switch
self.defaults.set(true, forKey: "seenHelpInformation")
}
private func fetchHelpInstructions() {
let seenHelpInformation = self.defaults.bool(forKey: "seenHelpInformation")
if seenHelpInformation == false {
instructionURLComponents.scheme = ProcessingServer.scheme
instructionURLComponents.host = ProcessingServer.host
instructionURLComponents.port = ProcessingServer.port
instructionURLComponents.path = EndPoints.instructions
networkManager.fetchInstructions(url: instructionURLComponents.url!, completion: { Instruction in
guard let serverInstructions = Instruction else { return }
do {
try self.model.saveInstructions(instructions: serverInstructions)
} catch {
let alertController = UIAlertController(title: "Error Saving Instructions", message: error as? String, preferredStyle: .alert)
let OKAction = UIAlertAction(title: "OK", style: .default) { action in
print("Pressed OK")
}
alertController.addAction(OKAction)
self.present(alertController, animated: true, completion: nil)
}
})
}
}
}
extension InformationViewController {
// MARK: - Table view data source
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
guard let sections = fetchedResultsController.sections else { fatalError("No Sections") }
let sectionInformation = sections[section]
return sectionInformation.name
}
override func numberOfSections(in tableView: UITableView) -> Int {
guard let sections = fetchedResultsController.sections else { fatalError("FRC not configuired correctly") }
return sections.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let sections = fetchedResultsController.sections else { fatalError("FRC not configuired correctly") }
let sectionInformation = sections[section]
return sectionInformation.numberOfObjects
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
let instruction = fetchedResultsController.object(at: indexPath)
cell.textLabel?.text = instruction.headlineDisplayText
cell.detailTextLabel?.text = instruction.descriptionDisplayText
return cell
}
class SubtitleTableViewCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
}
extension InformationViewController : NSFetchedResultsControllerDelegate {
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, sectionIndexTitleForSectionName sectionName: String) -> String? {
return String(sectionName.hashValue)
}
}
型号详情
最佳答案
为了正确显示这些部分,您必须在与sectionNameKeyPath
对应的第一个位置指定一个排序描述符
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "sectionHeading.name", ascending: true),
NSSortDescriptor(key: "rowOrder", ascending: true)]
并将
numberOfSections
替换为override func numberOfSections(in tableView: UITableView) -> Int {
return fetchedResultsController.sections?.count ?? 0
}
那么您可以强制解开所有出现的
fetchedResultsController.sections
,因为如果numberOfSections
返回0,则不会调用所有其他数据源方法。