How do you update a CoreData entry that has already been saved in Swift?

Since batchupdate is more useful in larger chunks of data, I think this is a more subtle approach.

func saveLoginData(accessToken: String, userName: String) {
    var appDel: AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
    var context: NSManagedObjectContext = appDel.managedObjectContext!

    var fetchRequest = NSFetchRequest<NSFetchRequestResult>(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)
        }
    }
}

I tried to translate it a bit to your situation if I'm not mistaken, but have not tested it.

fetchRequest.predicate basically sets the filter on the attribute userName from the entity LoginData, with the (user)name you enter when calling the function. Assuming in this example you have only one username with the same name. Then it does a fetchrequest with the given filter, so you can change it's value with setValue with the accesToken you also enter when calling the function. The code after: if fetchResults.count != 0 , only executes when the username exists.


Updated for Swift 4 & XCode 9.2

To answer your question...

How do you update a CoreData entry that has already been saved in Swift?

You first need to get a reference to your AppDelegate and viewContext. You then need to set up a NSFetchRequest for the Entity you are looking to update, in my example that would be "Alert". You then set up your fetch to find the result you are looking for. In the example, my result found Alerts by their creation date and alert type.

To further read how to query using a predicate. Stack Overflow Example & Apple Documentation

I then context.fetch(fetchRequest), set the results to the value I wanted to update, and dealt with errors in a try catch. Finally I context.save().

let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(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)")
}

Swift 5

You can create a method that can work to both, include and update. Assuming you have an entity created on CoreData with the name Users:

 var context: NSManagedObjectContext {
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    return appDelegate.persistentContainer.viewContext
 }
 let user: Users!

 let fetchUser: NSFetchRequest<Users> = Users.fetchRequest()
 fetchUser.predicate = NSPredicate(format: "id = %@", id as String)

 let results = try? context.fetch(fetchUser)

 if results?.count == 0 {
    // here you are inserting
    user = Users(context: context)
 } else {
    // here you are updating
    user = results?.first
 }

 user.id = id
 user.name = name
 ...


try context.save()

Swift >= 2 the method now returns a non-optional and throws an error in the error case, which must be handled with try-catch:

let context = self.fetchedResultsController.managedObjectContext
let entity = self.fetchedResultsController.fetchRequest.entity!
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity.name!)
fetchRequest.predicate = NSPredicate(format: "notificationId = 13")

do {
    let list = try context.executeFetchRequest(fetchRequest) as? [NSManagedObject]
    // Check notificationId available then not save
    if list!.count == 0 {
        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)")
}

You're creating multiple new LoginData objects, but your loadLoginData method is always returning the same object, the first one from the fetch request results.

You want to keep updating the same object, so you need to change your saveLoginDetails method.

Instead of creating a new object (which is what insertNewObjectForEntityName) does, use the loadLoginDetails method to get your existing one, and change the property on there.