Core data 国际证监会第10号及;Switt3-核心数据不保存也不返回结果

Core data 国际证监会第10号及;Switt3-核心数据不保存也不返回结果,core-data,swift3,ios10,Core Data,Swift3,Ios10,我正在用核心数据构建一个应用程序。到目前为止,它一直对我有效。最近,, 我没有得到结果。没有错误。似乎没有数据被持久化。有人遇到过这种奇怪的故障吗 My viewcontroller:显示联系人列表 import UIKit import CoreData class ContactsTableViewController: UITableViewController { @IBAction func addContactAction(_ sender: An

我正在用核心数据构建一个应用程序。到目前为止,它一直对我有效。最近,, 我没有得到结果。没有错误。似乎没有数据被持久化。有人遇到过这种奇怪的故障吗

My viewcontroller:显示联系人列表

    import UIKit
    import CoreData

    class ContactsTableViewController: UITableViewController {

    @IBAction func addContactAction(_ sender: AnyObject) {
        alertDialog()
    }


    let identifier = "contactCell"
    var contacts:[String] = [String]()
    var managedContext:NSManagedObjectContext?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem()

        managedContext =  (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

        addContacts(numContacts: 30);
    }


    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        fetchContacts("") { (list) in
            for i in 0..<list.count {
                contacts.append(list[i].value(forKey:"name")! as! String)
            }
            tableView.reloadData()
        }
    }

    func alertDialog() {
        //It takes the title and the alert message and prefferred style
        let alertController = UIAlertController(title: "Add Contact", message: "", preferredStyle: .alert)


        alertController.addTextField { (textField) in
            textField.placeholder = "contact"

        }
        let defaultAction = UIAlertAction(title: "Add", style: .default) { (UIAlertAction) in

            let textField = alertController.textFields![0]
            self.addContact(name: textField.text!)
            self.tableView.reloadData()

        }

        let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)

        //now we are adding the default action to our alertcontroller
        alertController.addAction(defaultAction)
        alertController.addAction(cancelAction)

        //and finally presenting our alert using this method
        present(alertController, animated: true, completion: nil)
    }
      }




     extension ContactsTableViewController {

    // MARK: - Table view data source
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return contacts.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: identifier, for: indexPath)

        // Configure the cell...
        cell.textLabel?.text = contacts[indexPath.row]

        return cell
    }

    // MARK: - Table view delegate
    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {

            let contactToDelete = contacts[indexPath.row]
            deleteContact(contactToDelete)
            contacts.remove(at: (indexPath as NSIndexPath).row)
            tableView.deleteRows(at: [indexPath], with: .fade)

        } else if editingStyle == .insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }
    }
}

extension ContactsTableViewController {

    func addContacts(numContacts:Int) {

        for i in 1..<numContacts {

            let contact = NSEntityDescription.insertNewObject(forEntityName: "Contact", into: managedContext!) as! Contact

            contact.setValue("name \(i)", forKeyPath: "name")

            (UIApplication.shared.delegate as! AppDelegate).saveContext()

            do {
                try managedContext?.save()

                print("\(contact.value(forKeyPath: "name") as! String)) successfully saved")

            } catch  {

                fatalError("Failure to save context: \(error)")

            }
        }

        self.tableView.reloadData()
    }

    func addContact(name:String) {

        let contact = NSEntityDescription.insertNewObject(forEntityName: "Contact", into: managedContext!) as! Contact

        contact.setValue(name, forKeyPath: "name")

        (UIApplication.shared.delegate as! AppDelegate).saveContext()

        do {
            try managedContext?.save()

            print("\(contact.value(forKeyPath: "name") as! String)!) successfully saved")
        } catch  {
            fatalError("Failure to save context: \(error)")
        }

        self.tableView.reloadData()
    }

    func fetchContacts(_ predicate:String, completion:(_ array:[Contact]) -> ()) {

        var arr:[Contact] = [Contact]()


        let request:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Contact")

        request.predicate = NSPredicate(format: "name = %@", predicate)

        do {

            let results  =  try managedContext?.fetch(request) as! [Contact]

            for result in results {

                let name = (result as AnyObject).value(forKey: "name") as? String

                arr.append(result)

            } //for

            print(results)

            completion(arr as [Contact])

        } catch {
            print("error fetching results")
        } //do
    }

    func deleteContact(_ name:String) {

        fetchContacts(name) { (array) -> () in

            for result in array {

                let aContact = (result as AnyObject).value(forKey: "name") as? String

                if aContact == name {

                    //delete
                    self.managedContext?.delete(result)

                    //save
                    do {
                        try self.managedContext!.save()
                        print("\(aContact) deleted")
                    } catch {

                        print("error deleting contact")
                    } //do

                } // if
            } //for
        }
    }

}
生成的实体类

import Foundation
import CoreData


extension Contact {

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

    @NSManaged public var name: String?

}
<代码>导入基础 导入CoreData 扩展触点{ @nonobjc公共类func fetchRequest()->NSFetchRequest{ 返回NSFetchRequest(entityName:“联系人”); } @NSManaged公共变量名称:字符串? } 数据模型。很简单

<img src="https://drive.google.com/file/d/0B1Usy68B1DzYLUduNTlCY092VEk/view" width="1970" height="1084">

数据源和单元格标识符连接正确

fetchContacts(“”)
始终返回空列表,因为您没有名为“”的联系人。此外,无论何时向核心数据添加或插入,您都不会看到这些更改,因为您没有执行另一次获取和更新
联系人
数组

代码中其他更一般的问题:

  • 您应该将
    persistentcainer
    viewContext
    视为只读。要写入核心数据,请使用
    执行​背景​任务(\:​)
  • 创建
    persistentcainer
    后,设置
    container.viewContext.automaticallyMergesChangesFromParent=true
  • 使用
    fetchedResultsController
    将核心数据与视图同步
  • 如果您像在
    addContacts
    中那样对核心数据进行大量更改或插入,请在最后保存一次,而不是在循环中每次插入之后保存
fetchContacts(“”
始终返回空列表,因为您没有名为“”的联系人。此外,无论何时向核心数据添加或插入联系人,您都看不到这些更改,因为您没有进行另一次提取和更新
联系人
数组

代码中其他更一般的问题:

  • 您应该将
    persistentcainer
    viewContext
    视为只读。要写入核心数据,请使用
    执行​背景​任务(\:​)
  • 创建
    persistentcainer
    后,设置
    container.viewContext.automaticallyMergesChangesFromParent=true
  • 使用
    fetchedResultsController
    将核心数据与视图同步
  • 如果您像在
    addContacts
    中那样对核心数据进行大量更改或插入,请在最后保存一次,而不是在循环中每次插入之后保存
<img src="https://drive.google.com/file/d/0B1Usy68B1DzYLUduNTlCY092VEk/view" width="1970" height="1084">