2014-12-16 12 views
10

Sto cercando di archiviare e recuperare semplicemente CoreData (cosa che ho fatto con successo prima con swift). Stavo diventando un nulla per i dati, ma ora (non sono sicuro di cosa sia cambiato) non sto ricevendo un errore, solo niente che mostra in tableview. Non sono sicuro se si tratta di un problema nella memorizzazione o nel recupero dell'oggetto. Ho seguito il modo in cui l'ho fatto in un'altra mia app il più vicino possibile, ma sembra che ci sia qualcosa di fondamentale che non riesco a ottenere. Ecco cosa ho.recupero dei dati di base nelle celle tableview swift

Il mio modello:

import Foundation 
import CoreData 

@objc(DataModel) 
class DataModel: NSManagedObject { 

@NSManaged var itemName: String 
@NSManaged var quantity: NSNumber 
@NSManaged var price: NSNumber 

} 

Nel mio tableviewcontroller con celle statiche per i campi di testo che voglio salvare i dati da:

import UIKit 
import CoreData 

class NewItemTableViewController: UITableViewController { 

@IBOutlet weak var itemNameTextField: UITextField! 
@IBOutlet weak var itemPriceTextField: UITextField! 
@IBOutlet weak var itemQuantityTextField: UITextField! 


override func viewDidLoad() { 
    super.viewDidLoad() 

} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 


@IBAction func saveButton(sender: AnyObject) { 
    //CoreData 
    let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate 
    let managedContext : NSManagedObjectContext = appDelegate.managedObjectContext! 
    let entity = NSEntityDescription.entityForName("Item", inManagedObjectContext: managedContext) 

    var newItem = DataModel(entity: entity!, insertIntoManagedObjectContext: managedContext) 


    newItem.itemName = itemNameTextField.text 
    //newItem.price = itemPriceTextField.text 
    //newItem.quantity = itemQuantityTextField 
    managedContext.save(nil) 

    self.navigationController?.popToRootViewControllerAnimated(true) 


} 
@IBAction func cancelButton(sender: AnyObject) { 
    self.navigationController?.popToRootViewControllerAnimated(true) 
} 

E nel mio tableviewcontroller che voglio recuperare il un dato mostra in celle dinamiche:

class ItemListTableViewController: UITableViewController { 

var items : Array<AnyObject> = [] 

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



override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

// MARK: - Table view data source 

override func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
    // #warning Potentially incomplete method implementation. 
    // Return the number of sections. 
    return 1 
} 

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    // #warning Incomplete method implementation. 
    // Return the number of rows in the section. 
    return items.count 
} 


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

    let CellID: NSString = "cell" 
    var cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(CellID) as UITableViewCell 
    var data: NSManagedObject = items[indexPath.row] as NSManagedObject 


    var itemName = data.valueForKey("itemName") as String 
    var price = data.valueForKey("price") as NSNumber 
    var quantity = data.valueForKey("quantity") as NSNumber 


    cell.textLabel!.text! = "\(itemName)" 
    cell.detailTextLabel!.text! = "Price: \(price) - Quantity: \(quantity)" 

    return cell 

} 

Qualsiasi aiuto su un concetto Potrei aver perso s da qualche parte qui sarebbe apprezzato! Grazie.

Aggiornamento: così ho rifatto il mio codice per essere modellato dopo il suggerimento di @Bluehound. ma sto ancora ricevendo un errore: non so come risolverlo. enter image description here

+0

Come e dove è il vostro array '' degli articoli popolato? – pbasdf

risposta

17

Quando si utilizzano i dati di base e una vista tabella, è necessario utilizzare NSFetchedResultsController. In pratica recupera i dati dai dati principali e li organizza per sezione e indexPath in modo che possa essere facilmente impostato come origine dati di tableView. Qui è un'implementazione completa di un potenziale UITableViewController conforme alla NSFetchedResultsControllerDelegate:

import Foundation 
import UIKit 
import CoreData 


class HomeViewController: UITableViewController, NSFetchedResultsControllerDelegate { 

    let managedObjectContext: NSManagedObjectContext? = (UIApplication.sharedApplication().delegate as? AppDelegate)?.managedObjectContext 

    var fetchedResultsController: NSFetchedResultsController? 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     fetchedResultsController = NSFetchedResultsController(fetchRequest: allEmployeesFetchRequest(), managedObjectContext: managedObjectContext!, sectionNameKeyPath: nil, cacheName: nil) 
     fetchedResultsController?.delegate = self 
     fetchedResultsController?.performFetch(nil) 


    } 

    func allEmployeesFetchRequest() -> NSFetchRequest { 

     var fetchRequest = NSFetchRequest(entityName: "Employee") 
     let sortDescriptor = NSSortDescriptor(key: "nameLast", ascending: true) 

     fetchRequest.predicate = nil 
     fetchRequest.sortDescriptors = [sortDescriptor] 
     fetchRequest.fetchBatchSize = 20 

     return fetchRequest 
    } 

    //MARK: UITableView Data Source and Delegate Functions 
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
     return fetchedResultsController?.sections?.count ?? 0 
    } 

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 

     return fetchedResultsController?.sections?[section].numberOfObjects ?? 0 
    } 

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCellWithIdentifier("HomeCell", forIndexPath: indexPath) as UITableViewCell 

     if let cellContact = fetchedResultsController?.objectAtIndexPath(indexPath) as? Employee { 
      cell.textLabel?.text = "\(cellContact.nameLast), \(cellContact.nameFirst)" 

     } 


     return cell 
    } 

    //MARK: NSFetchedResultsController Delegate Functions 
    func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) { 

     switch type { 
     case NSFetchedResultsChangeType.Insert: 
      tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Fade) 
      break 
     case NSFetchedResultsChangeType.Delete: 
      tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Fade) 
      break 
     case NSFetchedResultsChangeType.Move: 
      break 
     case NSFetchedResultsChangeType.Update: 
      break 
     default: 
      break 
     } 
    } 

    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { 
     if editingStyle == .Delete { 
     } 

     switch editingStyle { 
     case .Delete: 
      managedObjectContext?.deleteObject(fetchedResultsController?.objectAtIndexPath(indexPath) as Employee) 
      managedObjectContext?.save(nil) 
     case .Insert: 
      break 
     case .None: 
      break 
     } 

    } 

    func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) { 

     switch type { 
     case NSFetchedResultsChangeType.Insert: 
      tableView.insertRowsAtIndexPaths(NSArray(object: newIndexPath!), withRowAnimation: UITableViewRowAnimation.Fade) 
      break 
     case NSFetchedResultsChangeType.Delete: 
      tableView.deleteRowsAtIndexPaths(NSArray(object: indexPath!), withRowAnimation: UITableViewRowAnimation.Fade) 
      break 
     case NSFetchedResultsChangeType.Move: 
      tableView.deleteRowsAtIndexPaths(NSArray(object: indexPath!), withRowAnimation: UITableViewRowAnimation.Fade) 
      tableView.insertRowsAtIndexPaths(NSArray(object: newIndexPath!), withRowAnimation: UITableViewRowAnimation.Fade) 
      break 
     case NSFetchedResultsChangeType.Update: 
      tableView.cellForRowAtIndexPath(indexPath!) 
      break 
     default: 
      break 
     } 
    } 

    func controllerWillChangeContent(controller: NSFetchedResultsController) { 
     tableView.beginUpdates() 
    } 

    func controllerDidChangeContent(controller: NSFetchedResultsController) { 
     tableView.endUpdates() 
    } 
} 

See a sample GitHub project here.