I update one field in Core Data. This code works well:
func updateData(){
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest:NSFetchRequest = NSFetchRequest.init(entityName: "User")
fetchRequest.predicate = NSPredicate(format: "username = %@", "John")
do {
let test = try managedContext.fetch(fetchRequest)
let objectUpdate = test[0] as! NSManagedObject
objectUpdate.setValue("John2", forKey: "username")
objectUpdate.setValue("John2@example.com", forKey: "email")
objectUpdate.setValue("newPassword", forKey: "password")
do {
try managedContext.save()
}
catch {
print(error)
}
} catch {
print(error)
}
}
I would like to add a way to check if what I try to update exists. In that specific case, I want to check first if I have in the database the username John
hi,
if all you want is a "did it succeed" indication, you could use something like this, returning a boolean that indicates whether everything worked:
func updateData() -> Bool {
var success = false
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return success }
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest.init(entityName: "User")
fetchRequest.predicate = NSPredicate(format: "username = %@", "John")
do {
let test = try managedContext.fetch(fetchRequest)
if test.count == 1 {
let objectUpdate = test[0] as! NSManagedObject
objectUpdate.setValue("John2", forKey: "username")
objectUpdate.setValue("John2@example.com", forKey: "email")
objectUpdate.setValue("newPassword", forKey: "password")
appDelegate.saveContext() // look in AppDelegate.swift for this function
success = true
}
} catch {
print(error)
}
return success
}
check the return value of updateData() to issue your success message:
if updateData() {
print ("I have found the name and I have changed")
} else {
print ("I could not find the name you are looking for")
}
there are many variations on how to use what's above -- it's not the best code, it may not generalize well to whatever you specifically are doing, and the appDelegate may throw/catch an error in saveContext() that would not be recognized in this code.
but then, consider: your code would be cleaner and less prone to error if you used what XCode generates for you for whatever class of managed object you defined in the .xcdatamodeld file. if, for example, the NSManagedObject you're working with was defined as an entity named User -- with attributes named username, email, and password (all String types) -- this code should work (i think -- i did not test, but it mirrors code i have in a current project)
func updateData() -> Bool {
var success = false
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return success }
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest: NSFetchRequest<User> = User.fetchRequest() // this provided by XCode code generation
fetchRequest.predicate = NSPredicate(format: "username = %@", "John")
do {
let test = try managedContext.fetch(fetchRequest)
if test.count == 1 {
let userToUpdate = test[0]
userToUpdate.username = "John2"
userToUpdate.email = "John2@example.com"
userToUpdate.password = "newPassword"
appDelegate.saveContext() // look in AppDelegate.swift for this function
success = true
}
} catch {
print(error)
}
return success
}
hope that helps,
DMG
** EDIT A DAY LATER: line 5 above was updated to provide specificity for the type of fetchRequest as NSFetchRequest<User>.