Projection

open class Projection<Root> : RealmCollectionValue, ProjectionObservable where Root : RLMObjectBase, Root : RealmCollectionValue, Root : ThreadConfined
extension Projection: KeypathSortable
extension Projection: ThreadConfined where Root: ThreadConfined
extension Projection: ObservableObject, RealmSubscribable where Root: ThreadConfined

Projection is a light weight model of the original Realm Object or EmbeddedObject. You can use Projection as a view model to minimize boilerplate.

Example of usage:

public class Person: Object {
    @Persisted var firstName = ""
    @Persisted var lastName = ""
    @Persisted var address: Address?
    @Persisted var friends: List<Person>
    @Persisted var reviews: List<String>
}

public class Address: EmbeddedObject {
    @Persisted var city: String = ""
    @Persisted var country = ""
}

class PersonProjection: Projection<Person> {
    @Projected(\Person.firstName) var firstName
    @Projected(\Person.lastName.localizedUppercase)
    var lastNameCaps
    @Projected(\Person.address.city) var homeCity
    @Projected(\Person.friends.projectTo.firstName)
    var friendsFirstName: ProjectedCollection<String>
}

### Supported property types

Projection can transform the original @Persisted properties in several ways:

  • Passthrough - Projection‘s property will have same name and type as original object. See PersonProjection.firstName.
  • Rename - Projection’s property will have same type as original object just with the new name.
  • Keypath resolution - you can access the certain properties of the projected Object. See PersonProjection.lastNameCaps and PersonProjection.homeCity.
  • Collection mapping - List and MutableSetof Objects or EmbeddedObjects can be projected as a collection of primitive values. See PersonProjection.friendsFirstName.
  • Exclusion - all properties of the original Realm object that were not defined in the projection model will be excluded from projection. Any changes happened on those properties will not trigger a change notification for the Projection. You still can access the original Object or EmbeddedObject and observe notifications directly on it.

Note

each @Persisted property can be @Projected in different ways in the same Projection class. Each Object or EmbeddedObject can have sevaral projections of same or different classes at once.

Querying

You can retrieve all Projections of a given type from a Realm by calling the objects(_:) of Realm or init(projecting:) of Projection’s class:

let projections = realm.object(PersonProjection.self)
let personObject = realm.create(Person.self)
let singleProjection = PersonProjection(projecting: personObject)

Available where Root: ThreadConfined

  • The Realm which manages the object, or nil if the object is unmanaged. Note: Projection can be instantiated for the managed objects only therefore realm will never be nil. Unmanaged objects are not confined to a thread and cannot be passed to methods expecting a ThreadConfined object.

    Declaration

    Swift

    public var realm: Realm? { get }
  • Indicates if the object can no longer be accessed because it is now invalid.

    Declaration

    Swift

    public var isInvalidated: Bool { get }
  • Indicates if the object is frozen. Frozen objects are not confined to their source thread. Forming a ThreadSafeReference to a frozen object is allowed, but is unlikely to be useful.

    Declaration

    Swift

    public var isFrozen: Bool { get }
  • Returns a frozen snapshot of this object. Unlike normal Realm live objects, the frozen copy can be read from any thread, and the values read will never update to reflect new writes to the Realm. Frozen collections can be queried like any other Realm collection. Frozen objects cannot be mutated, and cannot be observed for change notifications. Unmanaged Realm objects cannot be frozen.

    Warning

    Holding onto a frozen object for an extended period while performing write transaction on the Realm may result in the Realm file growing to large sizes. See Realm.Configuration.maximumNumberOfActiveVersions for more information.

    Declaration

    Swift

    public func freeze() -> Self
  • Returns a live (mutable) reference of this object. Will return self if called on an already live object.

    Declaration

    Swift

    public func thaw() -> `Self`?
  • A publisher that emits Void each time the projection changes.

    Despite the name, this actually emits after the projection has changed.

    Declaration

    Swift

    public var objectWillChange: RealmPublishers.WillChange<Projection> { get }