Navigation

MutableSet (beta) - iOS SDK

On this page

  • Overview
  • MutableSet as a Property
  • MutableSet Intersection Methods

New in version 10.8.0: MutableSet type

Warning

This feature is currently in beta. We encourage you to try out the feature and give feedback, but please be aware that:

  • The API may change.
  • New data types are not backwards compatible.

To add new data types via development mode, you must update the client SDK. Realm Sync client applications using older protocol versions will no longer be able to connect.

A MutableSet collection represents a to-many relationship containing distinct values. A MutableSet supports the following types (and their optional versions):

  • Bool,
  • Int,
  • Int8,
  • Int16,
  • Int32,
  • Int64,
  • Float,
  • Double,
  • String,
  • Data,
  • Date,
  • Decimal128,
  • ObjectId

Like Swift's Set, MutableSet is a generic type that is parameterized on the type it stores. Unlike native Swift collections, Realm mutable sets are reference types, as opposed to value types (structs).

You can only call the MutableSets mutation methods during a write transaction. As a result, MutableSets are immutable if you open the managing realm as a read-only realm.

You can filter and sort a MutableSet with the same predicates as Results. Like other Realm collections, you can register a change listener on a MutableSet.

For example, a Dog class model might contain a MutableSet for citiesVisited:

class Dog: Object {
@Persisted var name = ""
@Persisted var currentCity = ""
@Persisted var citiesVisited: MutableSet<String>
}
Note

When declaring default values for @Persisted MutableSet property attributes, both of these syntax types is valid:

  • @Persisted var value: MutableSet<String>
  • @Persisted var value = MutableSet<String>()

However, the second will result in significantly worse performance. This is because the MutableSet is created when the parent object is created, rather than lazily as needed.

You can then update the MutableSet during write transactions:

let realm = try! Realm()
// Record a dog's name and current city
let dog = Dog()
dog.name = "Maui"
dog.currentCity = "New York"
// Store the data in a realm. Add the dog's current city
// to the citiesVisited MutableSet
try! realm.write {
realm.add(dog)
dog.citiesVisited.insert(dog.currentCity)
}
// Later... 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)
}
// Send him back to New York
try! realm.write {
dog.currentCity = "New York"
dog.citiesVisited.insert(dog.currentCity)
}
// Get some information about the cities he has visited
print("Cities Maui has visited: \(dog.citiesVisited)")
// Prints "New York", "Toronto"
// Because 'citiesVisited' is a MutableSet, you only see
// New York listed once, even though he has been there twice
XCTAssert(dog.citiesVisited.count == 2)

Realm MutableSet also provides some set-specific methods to work with the data, including methods to compare sets and mutate them in place. For example, MutableSet intersection methods:

// Record another dog's name and give it a longer set of cities,
// some of which overlap the first dog's set
let dog2 = Dog()
dog2.name = "Lita"
dog2.currentCity = "New York"
// Create an array of strings that represents all the cities the dog has visited
let dog2Cities = ["Boston", "New York", "Toronto", "Montreal", "Boston"]
// Use an iterator to store the data as a Realm MutableSet
try! realm.write {
realm.add(dog2)
for city in dog2Cities {
dog2.citiesVisited.insert(city)
}
}
// The array of strings initially assigned to the set contains 5 items,
// but only 4 of them are distinct, so the set count should be 4
print("Cities Lita has visited: \(dog2.citiesVisited)")
XCTAssert(dog2.citiesVisited.count == 4)
// Check whether Lita and Maui have visited some of the same cities.
// Use "intersects" to find out whether the values of the two sets share common elements
let isInBothCitiesVisited = (dog.citiesVisited.intersects(dog2.citiesVisited))
print("Lita and Maui have visited some of the same cities: \(isInBothCitiesVisited)")
// Prints "Lita and Maui have visited some of the same cities: true"
// Mutate the set in place with elements that both dogs have in common
try! realm.write {
dog2.citiesVisited.formIntersection(dog.citiesVisited)
}
// This prints New York and Toronto, because those are the cities both sets have in common
print("Cities that both Maui and Lita have visited: \(dog2.citiesVisited)")
// Prints "New York" and "Toronto", because those are the cities both sets have in common
// Because this method mutates the set in place, the set now only contains 2 elements
XCTAssert(dog2.citiesVisited.count == 2)
Tip
See also:
Give Feedback

On this page

  • Overview
  • MutableSet as a Property
  • MutableSet Intersection Methods