2017-03-08 19 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