2017-03-08 44 views
0

我需要用我的核心数据中的数据填充我的表视图。 我可以显示我的行,但是,我无法填充我的tableview! 我使用swift 3和Xcode 8. 这是我的代码,在这个控制器中我必须显示列表。从CoreData使用NSFetchRequest填充TableView - SWIFT3 Xcode 8

class iTableViewController: UITableViewController, NSFetchedResultsControllerDelegate{ 
@IBOutlet var iTableView: UITableView! 


override func viewDidLoad(){ 
    super.viewDidLoad() 

    iTableView.dataSource = self 
    iTableView.delegate = self 

    let appDelegate = UIApplication.shared.delegate as! AppDelegate 
    let managerContext = appDelegate.persistentContainer.viewContext 
    let interventsFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Intervento") 

    do{ 
     //results 
     let fetchedIntervents = try managerContext.fetch(interventsFetch) as! [Intervento] 

     for interv in fetchedIntervents{ 
      print(interv.stampRow()) 
     } 

     NSLog(String(fetchedIntervents.count)) 
    }catch{ 
     fatalError("Failed to fetch employees: \(error)") 
    } 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
} 

//number of sections 
override func numberOfSections(in tableView: UITableView) -> Int { 
    return 1 
} 

//numer of rows 
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return 1 
} 

//cell 
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: "cell") 

    cell.accessoryType = UITableViewCellAccessoryType.disclosureIndicator 

    //print the example cell 
    cell.textLabel?.text = "title" 
    cell.detailTextLabel?.text = "subtitle" 
    return cell 
} 

//swipe and delete 
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath){ 
    if(editingStyle == UITableViewCellEditingStyle.delete){ 
     //TODO 
    } 
} 

// click cell 
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){ 
    performSegue(withIdentifier: "segueDetail", sender: self) 
} 


override func viewDidAppear(_ animated: Bool){ 
    //iTableView.reloadData() 
} 

override func viewWillDisappear(_ animated: Bool) { 
    //iTableView.reloadData() 
    //fetchData() 
} 
} 

这是我的课

extension Intervento { 

@nonobjc public class func fetchRequest() -> NSFetchRequest<Intervento> { 
    return NSFetchRequest<Intervento>(entityName: "Intervento"); 
} 

@NSManaged public var cliente: Int32 
@NSManaged public var dataFine: String? 
@NSManaged public var dataInizio: String? 
@NSManaged public var descrizione: String? 
@NSManaged public var foto: String? 
@NSManaged public var id: Int32 
@NSManaged public var stato: String? 
@NSManaged public var tecnico: String? 

func stampRow()->String{ 
    let v1 = String(id) + " " + String(cliente) + " " 
    let v2 = dataInizio! + " " + dataFine! + " " 
    let v3 = stato! + " " + tecnico! + " " + descrizione! 
    return v1 + v2 + v3 
} 
} 

,这是我对保存数据(它的工作原理)

@IBAction func addButton(_ sender: Any){ 
    //genero la data 
    let dateFormatter = DateFormatter() 
    dateFormatter.dateFormat = "dd-MM-yyyy HH:mm" 
    let strDate = dateFormatter.string(from: myDatePicker.date) 

    let appDelegate = UIApplication.shared.delegate as! AppDelegate 
    let managerContext = appDelegate.persistentContainer.viewContext 
    let newInt = NSEntityDescription.insertNewObject(forEntityName: "Intervento", into: managerContext) 

    newInt.setValue(1, forKey: "id") 
    newInt.setValue(strDate, forKey: "dataInizio") 
    newInt.setValue("", forKey: "dataFine") 
    newInt.setValue(2, forKey: "cliente") 
    newInt.setValue("Matt", forKey: "tecnico") 
    newInt.setValue(stato[1], forKey: "stato") 
    newInt.setValue("", forKey: "descrizione") 
    newInt.setValue("", forKey: "foto") 

    do{ 
     try managerContext.save() 
     print("saved") 
    }catch let error as NSError{ 
     //errore salvataggio 
     print("Could not fetch \(error), \(error.userInfo)") 
    } 
} 
+1

你的代码是混乱的。一个'UITableViewController'包含一个预定义的'UITableView'实例,连接了委托和数据源。你使用'NSFetchedResultsController'吗?该代码与手动获取数据非常不同。你的数据源数组在哪里?班级名称应该以大写字母开头。 – vadian

+0

PS:选中核心数据复选框创建一个新的主 - 明细项目。您几乎可以免费获得所需的全部代码。 – vadian

+0

谢谢你,我已经添加了我的课程和保存在数据库中的代码。也许我需要使用NsFetchedResultController,但是如何? :( – Matt

回答

1

首先,你的类应该实现此协议的代码:

UIViewController, UITableViewDataSource, UITableViewDelegate, NSFetchedResultsControllerDelegate 

您可以装载da TA从这个代码持久存储:

//load data 

//persistant container 
let persistentContainer = NSPersistentContainer.init(name: "Model") 

// 
lazy var fetchedResultsController: NSFetchedResultsController<Intervento> = { 
    // Create Fetch Request 
    let fetchRequest: NSFetchRequest<Intervento> = Intervento.fetchRequest() 

    // Configure Fetch Request 
    fetchRequest.sortDescriptors = [NSSortDescriptor(key: "dataInizio", ascending: false)] 

    let appDelegate = UIApplication.shared.delegate as! AppDelegate 
    let managerContext = appDelegate.persistentContainer.viewContext 

    // Create Fetched Results Controller 
    let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managerContext, sectionNameKeyPath: nil, cacheName: nil) 

    // Configure Fetched Results Controller 
    fetchedResultsController.delegate = self 

    return fetchedResultsController 
}() 

//carica 
func load(){ 
    //persistant container 
    persistentContainer.loadPersistentStores { (persistentStoreDescription, error) in 
     if let error = error { 
      print("Unable to Load Persistent Store") 
      print("\(error), \(error.localizedDescription)") 
     } else { 
      do { 
       try self.fetchedResultsController.performFetch() 
      } catch { 
       let fetchError = error as NSError 
       print("Unable to Perform Fetch Request") 
       print("\(fetchError), \(fetchError.localizedDescription)") 
      } 

     } 
    } 
} 

override func viewDidLoad(){ 
    super.viewDidLoad() 

    iTableView.delegate = self 
    iTableView.dataSource = self 

    // trigger load 
    load() 
} 

您的数据将被获取并会显示出来,因为你已经委派iTableViewController通过这行代码:

// Configure Fetched Results Controller 
fetchedResultsController.delegate = self 

为了使这项工作,您的视图控制器必须符合NSFetchedResultsControllerDelegate协议,在这里你可以找到一个不可能性的实现:

extension iTableViewController: NSFetchedResultsControllerDelegate { 

func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
    iTableView.beginUpdates() 
} 

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
    iTableView.endUpdates() 
} 

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { 
    switch (type) { 
    case .insert: 
     if let indexPath = newIndexPath { 
      iTableView.insertRows(at: [indexPath], with: .fade) 
     } 
     break; 
    case .delete: 
     if let indexPath = indexPath { 
      iTableView.deleteRows(at: [indexPath], with: .fade) 
     } 
     break; 
    case .update: 
     if let indexPath = indexPath, let cell = iTableView.cellForRow(at: indexPath) { 
      configureCell(cell, at: indexPath) 
     } 
     break; 
    case .move: 
     if let indexPath = indexPath { 
      iTableView.deleteRows(at: [indexPath], with: .fade) 
     } 

     if let newIndexPath = newIndexPath { 
      iTableView.insertRows(at: [newIndexPath], with: .fade) 
     } 
     break; 
    } 
} 
} 

总之,这是全面实施您的iTableViewController的(我也包括用于删除行必要的代码):

class iTableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{ 
@IBOutlet var iTableView: UITableView! 

//load data 

//persistant container 
let persistentContainer = NSPersistentContainer.init(name: "Model") 

// 
lazy var fetchedResultsController: NSFetchedResultsController<Intervento> = { 
    // Create Fetch Request 
    let fetchRequest: NSFetchRequest<Intervento> = Intervento.fetchRequest() 

    // Configure Fetch Request 
    fetchRequest.sortDescriptors = [NSSortDescriptor(key: "dataInizio", ascending: false)] 

    let appDelegate = UIApplication.shared.delegate as! AppDelegate 
    let managerContext = appDelegate.persistentContainer.viewContext 

    // Create Fetched Results Controller 
    let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managerContext, sectionNameKeyPath: nil, cacheName: nil) 

    // Configure Fetched Results Controller 
    fetchedResultsController.delegate = self 

    return fetchedResultsController 
}() 

//carica 
func load(){ 
    //persistant container 
    persistentContainer.loadPersistentStores { (persistentStoreDescription, error) in 
     if let error = error { 
      print("Unable to Load Persistent Store") 
      print("\(error), \(error.localizedDescription)") 
     } else { 
      do { 
       try self.fetchedResultsController.performFetch() 
      } catch { 
       let fetchError = error as NSError 
       print("Unable to Perform Fetch Request") 
       print("\(fetchError), \(fetchError.localizedDescription)") 
      } 

     } 
    } 
} 


override func viewDidLoad(){ 
    super.viewDidLoad() 

    iTableView.delegate = self 
    iTableView.dataSource = self 

    // trigger load 
    load() 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
} 

//numero di sezioni 
func numberOfSections(in tableView: UITableView) -> Int { 
    return 1 
} 

//numero di righe 
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    guard let quotes = fetchedResultsController.fetchedObjects else { return 0 } 
    return quotes.count 
} 

//gestisco la cella 
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    //genero la cella 
    let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: "cell") 

    configureCell(cell, at:indexPath) 
    return cell 
} 

//swipe and delete 
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath){ 
    if(editingStyle == .delete){ 

     // Fetch Quote 
     let quote = fetchedResultsController.object(at: indexPath) 

     // Delete Quote 
     quote.managedObjectContext?.delete(quote) 
    } 
} 

// click cell 
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){ 
    performSegue(withIdentifier: "segueDetail", sender: self) 
} 


func configureCell(_ cell: UITableViewCell, at indexPath: IndexPath) { 

    //get intervento 
    let intervento = fetchedResultsController.object(at: indexPath) 

    //fill the cell 
    cell.textLabel?.text = intervento.dataInizio 
    cell.detailTextLabel?.text = "SOME_THING" 
} 

//quando appare aggiorno la table view 
override func viewDidAppear(_ animated: Bool){ 
    self.iTableView.reloadData() 
} 
} 

extension iTableViewController: NSFetchedResultsControllerDelegate { 

func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
    iTableView.beginUpdates() 
} 

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
    iTableView.endUpdates() 
} 

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { 
    switch (type) { 
    case .insert: 
     if let indexPath = newIndexPath { 
      iTableView.insertRows(at: [indexPath], with: .fade) 
     } 
     break; 
    case .delete: 
     if let indexPath = indexPath { 
      iTableView.deleteRows(at: [indexPath], with: .fade) 
     } 
     break; 
    case .update: 
     if let indexPath = indexPath, let cell = iTableView.cellForRow(at: indexPath) { 
      configureCell(cell, at: indexPath) 
     } 
     break; 
    case .move: 
     if let indexPath = indexPath { 
      iTableView.deleteRows(at: [indexPath], with: .fade) 
     } 

     if let newIndexPath = newIndexPath { 
      iTableView.insertRows(at: [newIndexPath], with: .fade) 
     } 
     break; 
    } 
} 
} 

不要忘记当你操作与您的数据(你什么时候总是使用相同的情况下,例如添加新数据)。

let appDelegate = UIApplication.shared.delegate as! AppDelegate 
let managerContext = appDelegate.persistentContainer.viewContext 

对于一个完整的例子,你应该看看这里:https://github.com/bartjacobs/ExploringTheFetchedResultsControllerDelegateProtocol

+0

wooow谢谢!!你了解我的问题!!!它工作! – Matt