【问题标题】:Core Data Error when trying to save using a tuple尝试使用元组保存时出现核心数据错误
【发布时间】:2018-05-03 17:29:24
【问题描述】:

在我的 newJobNote 类中尝试将字符串保存到 coreData 时出现此错误。好像在函数private func createNote()就崩溃了let tuple = CoreDataManager.shared.createJobNote(jobNote: jobNote, job: job)就行了

这是错误:

2018-05-03 17:37:53.180012+0100 Shoot[7022:3228759] *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“不可接受的属性值类型:属性 = “note”;所需类型 = NSString;给定类型 = JobNote; value = (实体:JobNote;id:0x1c002f080;数据:{ 工作=“0xd000000000580000”; 注意=无; })。'

我有一个名为 Job 的实体,它存储了一个作业名称 - 然后我将其传递给我的 JobNoteVC。

我还有一个名为:JobNote 的实体,其属性名为:note。我还为我的核心数据做了一个结构:

func createJobNote(jobNote: String, job: Job) -> (JobNote?, Error?) {
        let context = persistentContainer.viewContext
        // create note
        let jobNote = NSEntityDescription.insertNewObject(forEntityName: "JobNote", into: context) as! JobNote

        jobNote.job = job

        jobNote.setValue(jobNote, forKey: "note")

        do {
            try context.save()
            return (jobNote, nil)
        } catch let error {
            print ("Failed to add camera:", error)
            return (nil, error)
        }
    }

然后我有一个笔记页面,其中包含一个 tableView,它将显示存储在 coredata 中的所有笔记:

import UIKit
import CoreData

class notes : UIViewController, UITableViewDelegate, UITableViewDataSource, NewJobNoteControllerDelegate {

    let cellId = "cellId"
    var tableView = UITableView()
    var jobNotesArray = [JobNote]()

    var job: Job? {
        let tabBarController = self.tabBarController as! jobTabController
        return tabBarController.job
    }

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

        self.tabBarController?.navigationItem.title = "NOTES"
        let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(HandleNewNote))
        self.tabBarController?.navigationItem.rightBarButtonItems = [addButton]

        addTableView()
        fetchJobNotes()
    }

    func addTableView() {
        // TABLE VIEW SETUP
        tableView.frame = self.view.frame
        self.view.addSubview(tableView)
        tableView.delegate = self
        tableView.dataSource = self
    }

    private func fetchJobNotes(){
        guard let jobNotes = job?.jobNotes?.allObjects as? [JobNote] else { return }
        self.jobNotesArray = jobNotes
    }

    func didAddJobNote(jobNote: JobNote) {
        jobNotesArray.append(jobNote)
        tableView.reloadData()
    }

    func didEditJobNote(jobNote: JobNote) {
        let row = jobNotesArray.index(of: jobNote)
        let reloadIndexPath = IndexPath(row: row!, section: 0)
        tableView.reloadRows(at: [reloadIndexPath], with: .middle)
    }

    @IBAction func HandleNewNote(sender : UIButton) {
        let newNote = newJobNote()
        newNote.delegate = self
        newNote.job = job
        let navController = UINavigationController(rootViewController: newNote)
        present(navController, animated: true, completion: nil)
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
         return jobNotesArray.count
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
        return cell
    }
}

这是我的新NoteVC:

import CoreData

protocol NewJobNoteControllerDelegate {
    func didAddJobNote(jobNote : JobNote)
    func didEditJobNote(jobNote: JobNote)
}

class newJobNote: UIViewController {

    var delegate: NewJobNoteControllerDelegate?
    var job: Job?

    let noteLabel: UILabel = {
        let label = UILabel()
        label.text = "NOTE"
        label.translatesAutoresizingMaskIntoConstraints = false
        label.textColor = UIColor(red:0.63, green:0.63, blue:0.63, alpha:1.0)
        return label
    }()

    var noteTextField: UITextField = {
        let textField = UITextField()
        textField.placeholder = "Enter Note..."
        textField.tintColor = UIColor(red:0.87, green:0.30, blue:0.32, alpha:1.0)
        textField.translatesAutoresizingMaskIntoConstraints = false
        return textField
    }()


    var jobNote : JobNote? {
        didSet {
            noteTextField.text = jobNote?.note
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.white
        let backButton = UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(HandleBack))
        navigationItem.leftBarButtonItem = backButton
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        navigationItem.title = "NEW NOTE"
    }

    private func createNote() {
        guard let jobNote = noteTextField.text else { return }
        guard let job = self.job else { return }

        let tuple = CoreDataManager.shared.createJobNote(jobNote: jobNote, job: job)

        if let error = tuple.1 {
            print(error)
        } else {
            dismiss(animated: true, completion: {
                self.delegate?.didAddJobNote(jobNote: tuple.0!)
            })
        }
    }

    private func saveNoteChanges() {
        let context = CoreDataManager.shared.persistentContainer.viewContext

        jobNote?.note = noteTextField.text

        do {
            try context.save()
            dismiss(animated: true) {
                self.delegate?.didEditJobNote(jobNote: self.jobNote!)
            }
        } catch let error {
            print ("Failed to save camera changes:", error)
        }
    }

    @IBAction private func HandleBack(sender : UIButton) {
        if jobNote == nil {
            createNote()
            print("back to note and saved")
        } else {
            saveNoteChanges()
            print("back to note and saved")
        }
    }
}

【问题讨论】:

    标签: ios swift xcode core-data


    【解决方案1】:

    问题来了

    jobNote.setValue(jobNote, forKey: "note")
    

    您不能将实体实例设置为实体本身内部的属性,请更改参数名称

    func createJobNote(sendedNote: String, job: Job) -> (JobNote?, Error?) {
    
      let context = persistentContainer.viewContext
        // create note
        let jobNote = NSEntityDescription.insertNewObject(forEntityName: "JobNote", into: context) as! JobNote
    
        jobNote.job = job
    
        jobNote.setValue(sendedNote, forKey: "note")
    
        do {
            try context.save()
            return (jobNote, nil)
        } catch let error {
            print ("Failed to add camera:", error)
            return (nil, error)
        }
    
     }
    

    【讨论】:

    • 更改参数名称后我仍然收到相同的错误。 'Unacceptable type of value for attribute: property = "note";
    • 抱歉,我忘记将 jobNote.setValuejobNote 更改为 sendedNote。完美运行!
    猜你喜欢
    • 1970-01-01
    • 2021-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多