Reputation: 95
I am using CoreData to save a tableView to the device. I am relatively new to CoreData, and cannot figure this out. I get the error:
'Cannot convert value of type 'String' to expected argument type 'NSManagedObject''
On the line:
favourites.append(addNewMemory.text!)
//MARK:- Core Data
func save(name: String) {
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
// 1
let managedContext =
appDelegate.persistentContainer.viewContext
// 2
let entity =
NSEntityDescription.entity(forEntityName: "Memory",
in: managedContext)!
let person = NSManagedObject(entity: entity,
insertInto: managedContext)
// 3
person.setValue(name, forKeyPath: "name")
// 4
do {
try managedContext.save()
favourites.append(person)
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
}
var favourites: [NSManagedObject] = []
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return favourites.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCell.CellStyle.default, reuseIdentifier: "Cell")
/*cell.imageView?.image = UIImage(named: "applelogo")
cell.imageView?.setRounded()
cell.imageView?.clipsToBounds = true
*/
let favMemory = favourites[indexPath.row]
cell.textLabel?.text = favMemory.value(forKeyPath: "name") as? String
return cell
}
@IBAction func addButtonTapped(_ sender: UIButton) {
insertNewCell()
}
func insertNewCell() {
favourites.append(addNewMemory.text!)
let indexPath = IndexPath(row: favourites.count - 1, section: 0)
tableView.beginUpdates()
tableView.insertRows(at: [indexPath], with: .automatic)
tableView.endUpdates()
addNewMemory.text = ""
view.endEditing(true)
}
I expected the app to save the string, but it does not work. How can I fix this?
Upvotes: 3
Views: 597
Reputation: 285069
You are mixing up the text
property of the text field and the Core Data entity. Obviously favourites
is declared as [NSManagedObject]
so you can't append a string. That's what the error message is telling you.
You have to insert a new record in insertNewCell
. The easiest solution is to call save
and return a Bool from save
to indicate that the insertion was successful.
And you are encouraged to use more contemporary API. If there is no Memory
subclass create one
var favourites = [Memory]()
...
func save(name: String) -> Bool {
let appDelegate = UIApplication.shared.delegate as! AppDelegate // force unwrapping is perfectly fine
// 1
let managedContext = appDelegate.persistentContainer.viewContext
// 2
let person = Memory(context: managedContext)
// 3
person.name = name
// 4
do {
try managedContext.save()
favourites.append(person)
return true
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
return false
}
}
and change insertNewCell
to
func insertNewCell() {
guard save(name: addNewMemory.text!) else { return }
let indexPath = IndexPath(row: favourites.count - 1, section: 0)
tableView.insertRows(at: [indexPath], with: .automatic)
addNewMemory.text = ""
view.endEditing(true)
}
beginUpdates/endUpdates
is pointless.
Upvotes: 3