Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a new object when writing to Core Data

I have an app that has some form fields. When the form is submitted it writes the data to my Core Data Object. However, when the form is submitted again it overwrites the existing data instead of appending to it, which is what I want to happen instead.

    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
        return
    }

    let managedContext = appDelegate.persistentContainer.viewContext
    let userEntity = NSEntityDescription.entity(forEntityName: "User", in: managedContext)

    let newUser = NSManagedObject(entity: userEntity! , insertInto: managedContext)
    newUser.setValue(titleField, forKey: "title")
    newUser.setValue(firstNameField, forKey: "firstName")
    newUser.setValue(lastNameField, forKey: "lastName")
    newUser.setValue(emailField, forKey: "email")
    newUser.setValue(affiliatedOrgField, forKey: "affiliatedOrg")
    newUser.setValue(ukRegionField, forKey: "ukRegion")
    newUser.setValue(privacyChecked, forKey: "privacyPolicy")

    do {
        try managedContext.save()
    } catch let error as NSError {
        print("Could not save. \(error), \(error.userInfo)")
    }

I have tried using

let userEntity = NSEntityDescription.insertNewObject(forEntityName: "User", into: managedContext)
let newUser = NSManagedObject(entity: userEntity, insertInto: managedContext)

but I get the following error on my 'newUser' constant

Cannot convert value of type 'NSManagedObject' to expected argument type 'NSEntityDescription'

Can anybody help please?

like image 554
user1391152 Avatar asked Apr 13 '18 11:04

user1391152


People also ask

How do you update an object in Core Data?

To update a specific object you need to set up a NSFetchRequest . This class is equivalent to a SELECT statetement in SQL language. The array results contains all the managed objects contained within the sqlite file. If you want to grab a specific object (or more objects) you need to use a predicate with that request.


2 Answers

You need to keep a reference to your newly created user and then update that user. So do as Tom E suggested

let newUser = User(context: managedContext)
newUser.title = ...
newUser. firstName = ...

Then let newUser be a property in your class of type User or part of an array, [User], depending on your use case

var newUser: User?

When the form gets updated then instead of creating a new user, update the changed properties like

newUser.email = emailField

and call save to persist the update

try managedContext.save()
like image 84
Joakim Danielson Avatar answered Oct 11 '22 19:10

Joakim Danielson


Since you are using NSPersistentContainer you are using at least macOS 10.12 or iOS 10.10. Apple has added some very nice simplifications to Core Data so that it is unnecessary, for example, to use string-based keys which have the disadvantage to being resistant to compiler checking.

The “new Core Data pattern” looks like this:

let managedContext = appDelegate.persistentContainer.viewContext
let newUser = User(context: managedContext)
newUser.title = ...
newUser.firstName = ...

It could be as simple as that. Let me know if it works for you.

like image 4
Tom E Avatar answered Oct 11 '22 18:10

Tom E