2017-07-12 50 views
0

从例子一样,以查看所述核心数据:https://drive.google.com/open?id=0B3d4jY23eLOoejdRWkE0SG1VMkk隐形麻烦TableViewCells

步骤1.我实现了核心数据“数据库”。我现在有17条记录,并希望通过TableView中的单元格查看它们的全部... enter image description here

我像在教程中那样做,但它不起作用。我一个星期浪费,并:(它加载完全不能找到一个错误,但数据不会显示在单元格:(所以......

import Foundation 
 
import CoreData 
 

 
@available(iOS 10.0, *) 
 
class DatabaseController 
 
{ 
 
    private init() { } 
 
    
 
class func getContext() -> NSManagedObjectContext 
 
{ 
 
    return persistentContainer.viewContext 
 
} 
 
    
 
// MARK: - Core Data stack 
 
static var persistentContainer: NSPersistentContainer = 
 
{ 
 
    let container = NSPersistentContainer.init(name: "Database") 
 
    //let container = NSPersistentContainer(name: "Database") 
 
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in 
 
     if let error = error as NSError? 
 
     { 
 
      fatalError("Unresolved error \(error), \(error.userInfo)") 
 
     } 
 
    }) 
 
    return container 
 
}() 
 
    
 
// MARK: - Core Data Saving support 
 
class func saveContext() 
 
{ 
 
     let context = persistentContainer.viewContext 
 
     if context.hasChanges 
 
     { 
 
      do { 
 
       try context.save() 
 
      } 
 
      catch { 
 
       let nserror = error as NSError 
 
       fatalError("Unresolved error \(nserror), \(nserror.userInfo)") 
 
      } 
 
     } 
 
} 
 
    
 
}

主要是3个文件...保存/获得“DatabaseController.swift” /持续性容器 下一步“AppDelegate.Swift” ......

func applicationWillTerminate(_ application: UIApplication) 
{ 
    DatabaseController.saveContext() 
} 

// MARK: - Core Data stack 
lazy var applicationDocumentsDirectory: NSURL = 
{ 
    let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) 
    return urls[urls.count-1] as NSURL 
}() 

lazy var managedObjectModel: NSManagedObjectModel = 
{ 
    let modelURL = Bundle.main.url(forResource: "Database", withExtension: "momd")! 
    return NSManagedObjectModel(contentsOf: modelURL)! 
}() 

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = 
{ 
    var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) 
    let url = self.applicationDocumentsDirectory.appendingPathComponent("Database.sqlite") 
    var error: NSError? = nil 
    var failureReason = "There was an error creating or loading the application's saved data." 

    do 
    { 
     try coordinator!.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: nil) 
    } 
    catch { 
     coordinator = nil 

     let dict = NSMutableDictionary() 
     dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" 
     dict[NSLocalizedFailureReasonErrorKey] = failureReason 
     dict[NSUnderlyingErrorKey] = error 
     let error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict as? [AnyHashable : Any]) 
     NSLog("Unresolved error \(String(describing: error)), \(error.userInfo)") 
     print(error.localizedDescription) 
     abort() 
    } 
    return coordinator 
}() 

lazy var managedObjectContext: NSManagedObjectContext? = 
{ 
    let coordinator = self.persistentStoreCoordinator 
    if coordinator == nil 
    { 
     return nil 
    } 

    var managedObjectContext = NSManagedObjectContext() 
    managedObjectContext.persistentStoreCoordinator = coordinator 
    return managedObjectContext 
}() 

负责DataCore的 而对于最终的TableView文件主要功能。之前,我做它作为DataCore公司,细胞显示了类似下面这样

if indexPath.row == 0 { 
      cell.postImageView.image = UIImage(named: "ENTP") 
      cell.postTitleLabel.text = "ENTP" 
      cell.authorLabel.text = "Oleksandr Zheliezniak" 
      cell.authorImageView.image = UIImage(named: "author"): 
     } else if indexPath.row == 1 { 
      cell.postImageView.image = UIImage(named: "INTJ") 
      cell.postTitleLabel.text = "INTJ" 
      cell.authorLabel.text = "Gabriel Theodoropoulos" 
      cell.authorImageView.image = UIImage(named: "appcoda-300") 
     } else if indexPath.row == 2 { 
      cell.postImageView.image = UIImage(named: "ENTP") 
      cell.postTitleLabel.text = "ENTJ" 
      cell.authorLabel.text = "Gabriel Theodoropoulos" 
      cell.authorImageView.image = UIImage(named: "appcoda-300") 
     } else { 
      cell.postImageView.image = UIImage(named: "СеКс") 
      cell.postTitleLabel.text = "и виски" 
      cell.authorLabel.text = "Кокс Карибский))" 
      cell.authorImageView.image = UIImage(named: "appcoda-300") 
     } 

最终文件:

// 
// PersonTableViewController.swift 
// 
// Created by Oleksandr Z 2017(c). 
// 
import UIKit 
import Foundation 
import CoreData 

@available(iOS 10.0, *) 
class PersonTableViewController: UITableViewController, NSFetchedResultsControllerDelegate 
{ 
    @IBAction func addButtonPressed(_ sender: Any) 
    { 
     switchScreen() 
    } 
    @IBOutlet weak var menuButton:UIBarButtonItem! 
    let moc: NSManagedObjectContext? = (UIApplication.shared.delegate as? AppDelegate)?.managedObjectContext 
    var fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>? 
    var valueToPass:String! 
    //override var prefersStatusBarHidden: Bool {return true} 

    override func viewDidLoad() 
    { 
     super.viewDidLoad() 

     // MARK: - CORE DATA fetching out to the TableView 
     fetchedResultsController?.delegate = self 
     fetchedResultsController = NSFetchedResultsController(fetchRequest: IdentitiesFetchRequest(), managedObjectContext: self.moc!, sectionNameKeyPath: nil, cacheName: nil) 
     do 
     { 
      try fetchedResultsController?.performFetch() 
     } 
     catch let error as NSError 
     { 
      fatalError("Failed to initialize FetchedResultsController: \(error)") 
     } 

     //Visualization 
     if self.revealViewController() != nil 
     { 
      self.revealViewController().rearViewRevealWidth = 250 
      self.revealViewController().frontViewShadowRadius = 10 
      self.revealViewController().frontViewShadowColor = UIColor.black 
      self.revealViewController().frontViewShadowOpacity = 1 

      menuButton.target = self.revealViewController() 
      menuButton.action = #selector(SWRevealViewController.revealToggle(_:)) 
      self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer()) 
     } 
     self.clearsSelectionOnViewWillAppear = true 
    } 

    func IdentitiesFetchRequest() -> NSFetchRequest<NSFetchRequestResult> 
    { 
     let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Identity") 
     let sortDescriptor = NSSortDescriptor(key: "lastModified", ascending: true) 

     fetchRequest.predicate = nil 
     fetchRequest.sortDescriptors = [sortDescriptor] 
     fetchRequest.fetchBatchSize = 20 
     fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc!, sectionNameKeyPath: nil, cacheName: nil) 
     fetchedResultsController?.delegate = self 
     do 
     { 
      try fetchedResultsController?.performFetch() 
     } 
     catch 
     { 
      fatalError("Failed to initialize FetchedResultsController: \(error)") 
     } 

     return fetchRequest 
    } 

    //MARK: NSFetchedResultsController Delegate Functions 
    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 
     if editingStyle == .delete { } 

     switch editingStyle 
     { 
     case .delete: 
      do 
      { 
       moc?.delete(fetchedResultsController?.object(at: indexPath) as! Identity) 
       try moc?.save() 
      } 
      catch 
      { 
       print(error) 
      } 
     case .insert: 
      break 
     case .none: 
      break 
     } 

    } 

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) 
    { 
     switch type 
     { 
     case NSFetchedResultsChangeType.insert: 
      tableView.insertRows(at: NSArray(object: newIndexPath!) as! [IndexPath], with: UITableViewRowAnimation.fade) 
      break 
     case NSFetchedResultsChangeType.delete: 
      tableView.deleteRows(at: NSArray(object: indexPath!) as! [IndexPath], with: UITableViewRowAnimation.fade) 
      break 
     case NSFetchedResultsChangeType.move: 
      tableView.deleteRows(at: NSArray(object: indexPath!) as! [IndexPath], with: UITableViewRowAnimation.fade) 
      tableView.insertRows(at: NSArray(object: newIndexPath!) as! [IndexPath], with: UITableViewRowAnimation.fade) 
      break 
     case NSFetchedResultsChangeType.update: 
      tableView.cellForRow(at: indexPath! as IndexPath) 
      break 
      //default: 
      // break 
     } 
    } 

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

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

    // MARK: - Table view data source 
    override func numberOfSections(in tableView: UITableView) -> Int { 
     // Return the number of sections. 
     return fetchedResultsController?.sections?.count ?? 0 
    } 

    //Detailed viewCell 
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    { 
     print("You selected cell #\(indexPath.row)!") 
     /* 
     // Get Cell Label 
     let indexPath = tableView.indexPathForSelectedRow! 
     let currentCell = tableView.cellForRow(at: indexPath)! as UITableViewCell 

     valueToPass = currentCell.textLabel?.text 
     performSegue(withIdentifier: "yourSegueIdentifer", sender: self) 
     */ 
    } 

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    { 
     if (segue.identifier == "ShowPerson") 
     { 
      //var viewController = segue.destination as! PersonDetailViewController 
      //viewController.passedValue = valueToPass 
     } 
    } 

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     // Return the number of rows in the section. 
     return fetchedResultsController?.sections?[section].numberOfObjects ?? 0 
    } 

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as!PersonTableViewCell 

     if let cellContact = fetchedResultsController?.object(at: indexPath) as? Identity 
     { 
      cell.textLabel?.text = "\(String(describing: cellContact.pName)), \(String(describing: cellContact.lastModified))" 
     } 

     let identityClassName:String = String(describing: Identity.self) 
     //let typeClassName:String  = String(describing: Type.self) 
     let identity:Identity = NSEntityDescription.insertNewObject(forEntityName: identityClassName, into: DatabaseController.getContext()) as! Identity 
     //let type:Type = NSEntityDescription.insertNewObject(forEntityName: typeClassName, into: DatabaseController.getContext()) as! Type 

     let fetchRequest:NSFetchRequest<Identity> = Identity.fetchRequest() 
     do 
     { 
      let searchResults = try DatabaseController.getContext().fetch(fetchRequest) 
      print("number of results: \(searchResults.count)") 
      for result in searchResults as [Identity] 
      { 
       print("\(result.pName!) is \(result.accuracy)% Robesper. Updeted \(result.lastModified!).") 

       cell.postImageView.image = UIImage(named: "ENTP") 
       cell.postTitleLabel.text = identity.pName 
       cell.authorLabel.text = identity.imType 
       cell.authorImageView.image = UIImage(named: "author") 
      } 
     } 
     catch { print("Error: \(error)") } 

     return cell 
    } 

    // Override to support rearranging the table view. 
    override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to toIndexPath: IndexPath) { 
    } 

    // Override to support conditional rearranging of the table view. 
    override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { 
     // Return NO if you do not want the item to be re-orderable. 
     return true 
    } 

    func switchScreen() 
    { 
     let mainStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main) 
     let vc : UIViewController = mainStoryboard.instantiateViewController(withIdentifier: "PersonDetail") as UIViewController 
     self.present(vc, animated: false, completion: nil) 
    } 
} 

尝试的解决方案:Can't show the core data in tableview Swift,但它并没有帮助。尝试了所有类似的主题,但无法解决问题。

+0

这将是学习如何使用Xcode的调试器的好时机。 –

回答

0
var identities : [Identity] = [] 

override func viewDidLoad() 
{ 
    super.viewDidLoad() 
    tableView.dataSource = self 
    tableView.delegate = self 

我试了很多。无论使用哪种解决方案(扩展,懒惰,直接)。

您应该首先创建两个变量:ONE for all data array; SECOND对于数组中的单个数据。

这就是方式,它是如何工作的基本上是:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
{ 
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as!PersonTableViewCell 

    let identity = identities[indexPath.row] 

      cell.postImageView.image = UIImage(named: <picture name>) 
      cell.postTitleLabel.text = identity.<Your attribute of entity> 
      cell.authorLabel.text = identity.<Your attribute of entity> 
      cell.authorImageView.image = UIImage(named: <picture name>) 

    return cell 
} 
0

你似乎有两个独立的CoreData堆栈:一个由DatabaseController类,它从NSPersistentContainer(在iOS10介绍)使用viewContext成立,而另一个设置在AppDelegate中,它使用什么样子,从标准的样板较旧的项目模板。您的FRC使用后者,而您的其他代码使用前者。

虽然这些似乎使用相同的模型文件,我怀疑他们正在使用不同的持久存储。我认为,如果你改变这一行:

fetchedResultsController = NSFetchedResultsController(fetchRequest: IdentitiesFetchRequest(), managedObjectContext: self.moc!, sectionNameKeyPath: nil, cacheName: nil) 

到:

fetchedResultsController = NSFetchedResultsController(fetchRequest: IdentitiesFetchRequest(), managedObjectContext: DatabaseController.getContext(), sectionNameKeyPath: nil, cacheName: nil) 

您的FRC将使用相同的上下文创建对象的代码,所以你应该看到一些成果。你的代码还有其他问题,所以Tom Harrington在评论中说,你应该学习如何使用调试器来解决它。

+0

非常感谢您的回应!然而,它并没有改变很多,因为它不会工作,如果它没有正确声明:( 我的意思是数据类型,如managedObjectContext,NSPersistent ...这是一个只适用于一种类型的地方:)有时,即使调试器也很难分配错误,因为它在任何地方都显示“nil”值,并且ASSEMBLER :) 编写.ASM代码更简单:D – Oleksandr