¿Cómo se actualiza una entrada de CoreData que ya se guardó en Swift?

No estoy seguro de lo que estoy haciendo mal aquí, pero cuando guardo la primera vez en coredata, funciona bien. Cuando bash sobrescribir eso, no es así.

func testStuff() { var token = loadLoginData() println("Token \(token)") saveLoginData("New Token") var newToken = loadLoginData() println("Token \(newToken)") } func saveLoginData(accessToken: String) { var appDel: AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate) var context: NSManagedObjectContext = appDel.managedObjectContext! // save data to core data var loginData = NSEntityDescription.insertNewObjectForEntityForName("LoginData", inManagedObjectContext: context) as NSManagedObject loginData.setValue(accessToken, forKey: "accessToken") context.save(nil) println("Done saving user") } /* Output Token Optional("12345") Done saving user Token Optional("12345") */ 

Cargar datos de inicio de sesión Func la función que llama a los datos de saveLogin

 func loadLoginData() -> String? { var appDel: AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate) var context: NSManagedObjectContext = appDel.managedObjectContext! var request = NSFetchRequest(entityName: "LoginData") request.returnsObjectsAsFaults = false var results: NSArray = context.executeFetchRequest(request, error: nil)! if (results.count > 0) { var userData: NSManagedObject = results[0] as NSManagedObject var accessToken: String = userData.valueForKey("accessToken") as String return accessToken.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()) } else { println("0 results returned, potential error") return nil } } 

Dado que batchupdate es más útil en grandes cantidades de datos, creo que este es un enfoque más sutil.

 func saveLoginData(accessToken: String, userName: String) { var appDel: AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate) var context: NSManagedObjectContext = appDel.managedObjectContext! var fetchRequest = NSFetchRequest(entityName: "LoginData") fetchRequest.predicate = NSPredicate(format: "userName = %@", userName) if let fetchResults = appDel.managedObjectContext!.executeFetchRequest(fetchRequest, error: nil) as? [NSManagedObject] { if fetchResults.count != 0{ var managedObject = fetchResults[0] managedObject.setValue(accessToken, forKey: "accessToken") context.save(nil) } } } 

Traté de traducirlo un poco a su situación si no me equivoco, pero no lo he probado.

fetchRequest.predicate básicamente establece el filtro en el atributo userName de la entidad LoginData, con el nombre (usuario) que ingresas al llamar a la función. Suponiendo en este ejemplo, solo tiene un nombre de usuario con el mismo nombre. Luego realiza una búsqueda de fetch con el filtro dado, por lo que puede cambiar su valor con setValue con el accessToken que también ingresa al llamar a la función. el código después: if fetchResults.count! = 0, solo se ejecuta cuando el nombre de usuario existe

Swift> = 2 el método ahora devuelve un no-opcional y arroja un error en el caso de error, que debe ser manejado con try-catch:

  let context = self.fetchedResultsController.managedObjectContext let entity = self.fetchedResultsController.fetchRequest.entity! let fetchRequest = NSFetchRequest(entityName:entity.name!) fetchRequest.predicate = NSPredicate(format: "notificationId = 13") do { let list = try context.executeFetchRequest(fetchRequest) as? [NSManagedObject] if list!.count == 0 // Check notificationId available then not save { let newManagedObject = NSEntityDescription.insertNewObjectForEntityForName(entity.name!, inManagedObjectContext: context) newManagedObject.setValue("This is first message13", forKey: "message") newManagedObject.setValue(1, forKey: "appId") newManagedObject.setValue(13, forKey: "notificationId") newManagedObject.setValue("First one", forKey: "tital") } // success ... } catch let error as NSError { // failure print("Fetch failed: \(error.localizedDescription)") } 

Actualizado para Swift 4 y XCode 9.2

Para responder tu pregunta…

¿Cómo se actualiza una entrada de CoreData que ya se guardó en Swift?

Primero necesita obtener una referencia a su AppDelegate y viewContext . Luego necesita configurar una NSFetchRequest para la entidad que desea actualizar, en mi ejemplo que sería “Alert”. Luego configura su búsqueda para encontrar el resultado que está buscando. En el ejemplo, mi resultado encontró Alertas por su fecha de creación y tipo de alerta.

Para leer más acerca de cómo consultar usando un predicado. Ejemplo de desbordamiento de stack y documentación de Apple

Luego context.fetch(fetchRequest) , establecí los resultados en el valor que quería actualizar y traté con los errores en una captura de prueba. Finalmente, context.save() .

 let appDelegate = UIApplication.shared.delegate as! AppDelegate let context = appDelegate.persistentContainer.viewContext let fetchRequest = NSFetchRequest(entityName: "Alert") fetchRequest.predicate = NSPredicate(format: "creationDate = %@ AND alertType = %&", argumentArray: [creationDate, alertType]) do { let results = try context.fetch(fetchRequest) as? [NSManagedObject] if results?.count != 0 { // Atleast one was returned // In my case, I only updated the first item in results results[0].setValue(yourValueToBeSet, forKey: "yourCoreDataAttribute") } } catch { print("Fetch Failed: \(error)") } do { try context.save() } catch { print("Saving Core Data Failed: \(error)") } 

Está creando varios objetos nuevos LoginData , pero su método loadLoginData siempre devuelve el mismo objeto, el primero de los resultados de la solicitud de búsqueda.

Desea seguir actualizando el mismo objeto, por lo que debe cambiar su método saveLoginDetails .

En lugar de crear un objeto nuevo (que es lo que hace insertNewObjectForEntityName ), use el método loadLoginDetails para obtener el existente y cambie la propiedad allí.

  var context:NSManagedObjectContext = appDel.managedObjectContext! var en = NSEntityDescription.entityForName("ENTITIES_NAME", inManagedObjectContext: context) let batchUpdateRequest = NSBatchUpdateRequest(entity: en!) batchUpdateRequest.resultType = NSBatchUpdateRequestResultType.UpdatedObjectIDsResultType batchUpdateRequest.propertiesToUpdate = ["OBJECT_KEY": "NEWVALUE"] var batchUpdateRequestError: NSError? context.executeRequest(batchUpdateRequest, error:&batchUpdateRequestError) if let error = batchUpdateRequestError {println("error")} 

buena suerte

Hay una nueva característica llamada Batch Updates.

Creo que este artículo te ayudará a:

http://www.bignerdranch.com/blog/new-in-core-data-and-ios-8-batch-updating/

Básicamente, lo que hace es usar NSBatchUpdateRequest lugar de NSFetchRequest , filtrar los resultados con NSPredicate , cambiar el valor en los resultados y guardar los datos.

Otro tutorial en swift:

http://code.tutsplus.com/tutorials/ios-8-core-data-and-batch-updates–cms-22164