CRUD - Update - Swift SDK
On this page
- Update Realm Objects
- About The Examples On This Page
- Update an Object
- Update Properties with Key-value Coding
- Upsert an Object
- Update a Map/Dictionary
- Update a MutableSet Property
- Update an AnyRealmValue Property
- Update an Embedded Object Property
- Overwrite an Embedded Object
- Update an Object Asynchronously
- Update Properties through Class Projections
- Change Class Projection Properties
Update Realm Objects
Updates to Realm Objects must occur within write transactions. For more information about write transactions, see: Transactions.
About The Examples On This Page
The examples on this page use the following models:
Update an Object
You can modify properties of a Realm object inside of a write transaction in the same way that you would update any other Swift or Objective-C object.
Tip
Update Related and Embedded Objects
To update a property of an embedded object or a related object, modify the property with dot-notation or bracket-notation as if it were in a regular, nested object.
Update Properties with Key-value Coding
Object
, Result
, and List
all conform to
key-value coding.
This can be useful when you need to determine which property to update
at runtime.
Applying KVC to a collection is a great way to update objects in bulk. Avoid the overhead of iterating over a collection while creating accessors for every item.
let realm = try! Realm() let allDogs = realm.objects(Dog.self) try! realm.write { allDogs.first?.setValue("Sparky", forKey: "name") // Move the dogs to Toronto for vacation allDogs.setValue("Toronto", forKey: "currentCity") }
You can also add values for embedded objects or relationships this way. In this example, we add a collection to an object's list property:
Upsert an Object
An upsert either inserts or updates an object depending on whether the object already exists. Upserts require the data model to have a primary key.
You can also partially update an object by passing the primary key and a subset of the values to update:
Update a Map/Dictionary
You can update a realm map as you would a standard Dictionary:
let realm = try! Realm() // Find the dog we want to update let wolfie = realm.objects(Dog.self).where { $0.name == "Wolfie" }.first! print("Wolfie's favorite park in New York is: \(wolfie.favoriteParksByCity["New York"])") XCTAssertTrue(wolfie.favoriteParksByCity["New York"] == "Domino Park") // Update values for keys, or add values if the keys do not currently exist try! realm.write { wolfie.favoriteParksByCity["New York"] = "Washington Square Park" wolfie.favoriteParksByCity.updateValue("A Street Park", forKey: "Boston") wolfie.favoriteParksByCity.setValue("Little Long Pond", forKey: "Seal Harbor") } XCTAssertTrue(wolfie.favoriteParksByCity["New York"] == "Washington Square Park")
Update a MutableSet Property
You can insert
elements into a MutableSet during write transactions to add them to the
property. If you are working with multiple sets, you can also insert or
remove set elements contained in one set from the other set. Alternately,
you can mutate a set to contain only the common elements from both.
let realm = try! Realm() // Record a dog's name, current city, and store it to the cities visited. let dog = Dog() dog.name = "Maui" dog.currentCity = "New York" try! realm.write { realm.add(dog) dog.citiesVisited.insert(dog.currentCity) } // Update the dog's current city, and add it to the set of cities visited. try! realm.write { dog.currentCity = "Toronto" dog.citiesVisited.insert(dog.currentCity) } XCTAssertEqual(dog.citiesVisited.count, 2) // If you're operating with two sets, you can insert the elements from one set into another set. // The dog2 set contains one element that isn't present in the dog set. try! realm.write { dog.citiesVisited.formUnion(dog2.citiesVisited) } XCTAssertEqual(dog.citiesVisited.count, 3) // Or you can remove elements that are present in the second set. This removes the one element // that we added above from the dog2 set. try! realm.write { dog.citiesVisited.subtract(dog2.citiesVisited) } XCTAssertEqual(dog.citiesVisited.count, 2) // If the sets contain common elements, you can mutate the set to only contain those common elements. // In this case, the two sets contain no common elements, so this set should now contain 0 items. try! realm.write { dog.citiesVisited.formIntersection(dog2.citiesVisited) } XCTAssertEqual(dog.citiesVisited.count, 0)
Update an AnyRealmValue Property
You can update an AnyRealmValue property through assignment, but you must specify the type of the value when you assign it. The Realm Swift SDK provides an AnyRealmValue enum that iterates through all of the types the AnyRealmValue can store.
let realm = try! Realm() // Get a dog to update let rex = realm.objects(Dog.self).where { $0.name == "Rex" }.first! try! realm.write { // As with creating an object with an AnyRealmValue, you must specify the // type of the value when you update the property. rex.companion = .object(Dog(value: ["name": "Regina"])) }
Update an Embedded Object Property
To update a property in an embedded object, modify the property in a write transaction. If the embedded object is null, updating an embedded object property has no effect.
Overwrite an Embedded Object
To overwrite an embedded object, reassign the embedded object property of a party to a new instance in a write transaction.
Update an Object Asynchronously
You can use Swift concurrency features to asynchronously update objects using an actor-isolated realm.
This function from the example RealmActor
defined on the
Use Realm with Actors page shows how you might
update an object in an actor-isolated realm:
func updateTodo(_id: ObjectId, name: String, owner: String, status: String) async throws { try await realm.asyncWrite { realm.create(Todo.self, value: [ "_id": _id, "name": name, "owner": owner, "status": status ], update: .modified) } }
And you might perform this update using Swift's async syntax:
let actor = try await RealmActor() // Read objects in functions isolated to the actor and pass primitive values to the caller func getObjectId(in actor: isolated RealmActor, forTodoNamed name: String) async -> ObjectId { let todo = actor.realm.objects(Todo.self).where { $0.name == name }.first! return todo._id } let objectId = await getObjectId(in: actor, forTodoNamed: "Keep it safe") try await actor.updateTodo(_id: objectId, name: "Keep it safe", owner: "Frodo", status: "Completed")
This operation does not block or perform I/O on the calling thread. For more information about writing to realm using Swift concurrency features, refer to Use Realm with Actors - Swift SDK.
Update Properties through Class Projections
Change Class Projection Properties
You can make changes to a class projection's properties in a write transaction.
// Retrieve all class projections of the given type `PersonProjection` // and filter for the first class projection where the `firstName` property // value is "Jason" let person = realm.objects(PersonProjection.self).first(where: { $0.firstName == "Jason" })! // Update class projection property in a write transaction try! realm.write { person.firstName = "David" }