Navigation

Realm Objects

Overview

MongoDB Realm applications model data as objects composed of field-value pairs that each contain one or more primitive data types or other Realm objects. Realm objects are essentially the same as regular objects in most programming languages, but they also include additional features like real-time updating data views and reactive change event handlers.

Every Realm object has an object type that refers to the object’s class. Objects of the same type share an object model that defines the properties and relationships of those objects. In Swift and Objective-C, you define object schemas as classes that derive from Realm’s Object class.

Note

If you are using Realm Sync, the primary key of an object must be an ObjectId, String, or Int called _id.

Example

The following code block shows an object model that describes a Dog. Every Dog object must include a name and age and may optionally include the dog’s breed and a reference to a Person object that represents the dog’s owner.

class Dog: Object {
    @objc dynamic var name = ""
    @objc dynamic var age = 0
    @objc dynamic var breed: String? = nil
    @objc dynamic var owner: Person? = nil
}
@interface Dog : RLMObject
@property NSString *name;
@property NSString *breed;
@property int age;
@property Person *owner;
@end

@implementation Dog
@end

Key Concepts

Live Object

Objects in Realm clients are live objects that update automatically to reflect data changes, including synced remote changes, and emit notification events that you can subscribe to whenever their underlying data changes. You can use live objects to work with object-oriented data natively without an ORM tool.

Live objects are direct proxies to the underlying stored data, which means that a live object doesn’t directly contain data. Instead, a live object always references the most up-to-date data on disk and lazy loads property values when you access them from a collection. This means that a realm can contain many objects, but you only pay the performance cost for data that the application is actually using.

Valid write operations on a live object automatically persist to the realm and propagate to any other synced clients. You do not need to call an update method, modify the realm, or otherwise “push” updates.

Object Model

An object model is a configuration object that defines the fields and relationships of a Realm object type. Realm Swift and Objective-C client applications define object models as classes derived from Object in Swift or RLMObject in Objective-C.

You can use the following types to define your object model properties:

  • Boolean Bool
  • Integral types Int, Int8, Int16, Int32, Int64
  • Double
  • String
  • Date
  • Data
  • ObjectId
  • User-defined Object-derived types
  • List

Additionally, you can use the optional String?, Date? and Data? types. You must make user-defined Object properties optional. You can use RealmOptional to represent integers, doubles, and other types as optional.

You can use the following types to define your object model properties:

  • Boolean types BOOL, bool
  • Integral types int, NSInteger, long, long long
  • double
  • NSString
  • NSDate
  • NSData
  • RLMObjectId
  • User-defined RLMObject-derived types
  • RLMList

Additionally, you can represent optional number types with NSNumber tagged with RLMInt, RLMDouble, or RLMBool:

@property NSNumber<RLMInt> *age;

Primary Key

A primary key is a String or ObjectId property that uniquely identifies an object. You may optionally define a primary key for an object type as part of the object model. Realm Database automatically indexes primary key properties, which allows you to efficiently read and modify objects based on their primary key.

If an object type has a primary key, then all instances of that type must include the primary key property with a value that is unique among objects of the same type in a realm. You cannot change the primary key property for an object type after any object of that type is added to a realm.

Specify your primary key to Realm by overriding the primaryKey method in your class and returning the name of the property:

class Person: Object {
    @objc dynamic var _id = ObjectId()
    @objc dynamic var name = ""
    let dogs = LinkingObjects(fromType: Dog.self, property: "owner")
    override static func primaryKey() -> String? {
        return "_id"
    }
}
@interface Person : RLMObject
@property RLMObjectId *_id;
@property NSString *name;
@property (readonly) RLMLinkingObjects *dogs;
@end

@implementation Person
+ (NSString *)primaryKey {
    return @"_id";
}
+ (NSDictionary *)linkingObjectsProperties {
    return @{
        @"dogs": [RLMPropertyDescriptor descriptorWithClass:Dog.class propertyName:@"owner"],
    };
}
- (instancetype)init {
    if ((self = [super init])) {
        self._id = [RLMObjectId objectId];
    }
    return self;
}
@end

Optional or Required Properties

Because Swift supports optional values, whether a property is optional or required is built into the type of that property. You can use RealmOptional to make optional integral properties:

class Person: Object {
    // Required string property
    @objc dynamic var name: String = ""

    // Optional string property
    @objc dynamic var address: String? = nil

    // Optional integral type property
    let age = RealmOptional<Int>()
}

To declare a given property as required, implement the requiredProperties method and return an array of required property names.

@interface Person : RLMObject
@property NSString *name;
@property NSDate *birthday;
@end

@implementation Person
+ (NSArray *)requiredProperties {
    return @[@"name"];
}
@end

Summary

  • Realm objects are classes derived from Object in Swift and RLMObject in Objective-C.
  • Realm objects are live: they always reflect the latest version on disk and update automatically when the underlying object changes.
  • A Realm object type may have a primary key property to uniquely identify each instance of the object type.
  • The Realm object model defines the properties of the object and which properties are optional.