Docs Menu
Docs Home
/ /
Atlas Device SDKs
/

Create Objects

On this page

  • Write Transactions
  • Managed and Unmanaged Objects
  • Create Object Methods
  • Create One Object
  • Create Multiple Objects
  • Create or Update an Object (Upsert)
  • Initialize Objects with a Value
  • Create Objects from JSON
  • Create an Unmanaged Copy of an Object
  • Copy an Object to Another Database
  • Create Objects in the Background

This page describes the concepts of write transactions and managed objects in a database, then explains how to create and persist a new object to a local or synced database using Atlas Device SDK. To learn more about object models and how to define them, refer to Define an SDK Object Model.

You can create objects whose object type is managed by the database instance. For more information, refer to:

Note

Write to a Synced Database

The syntax to write a new object to the database is the same for a local or a synced database. However, there are additional considerations that determine whether the write operation in a synced database is successful. For more information, refer to Write Data to a Synced Database.

The Atlas Device SDK persistence layer handles writes in terms of transactions. All writes must happen within a transaction. A transaction is a list of read and write operations that the database treats as a single indivisible operation: either all of the operations succeed or none of the operations in the transaction take effect.

The SDK represents each transaction as a callback function that contains zero or more read and write operations. To run a transaction, you define a transaction callback and pass it to one of the database's write methods. Within this callback, you can access a database instance and then create, read, update, and delete objects within the database.

A database file allows only one open write transaction at a time. The SDK blocks other writes on other threads until the open transaction on the database file is complete. This means there is never a race condition when reading values from the database within a transaction.

When you are done with your transaction, the SDK either commits it or cancels it:

  • When the SDK commits a write transaction, it writes all changes to disk. For synced databases, the SDK then queues the change for synchronization with the backend.

  • When the SDK cancels a write transaction or an operation in the transaction causes an error, it discards all changes.

The SDK's APIs may refer to objects as managed or unmanaged. When you create an object with the SDK, it is unmanaged until it is added to the database, which creates a managed instance.

  • Managed objects are SDK objects that persist in a database instance. Managed objects can only be accessed from an open database file. They can be updated with changes within write transactions as long as that database remains open. Managed objects are tied to the database instance from which they originated and cannot be directly written to another database. However, some of the SDKs supply a method to copy managed objects from one database file to another. Refer to the Copy an Object to Another Database section on this page.

    You can use the SDK's APIs with managed objects. For example, managed objects can have relationships with other objects and you can observe them for changes. You can also create an unmanaged copy of a managed object. Refer to the Create an Unmanaged Copy of an Object or Collection section on this page.

  • Unmanaged objects are SDK objects that behave like normal objects, but they are not persisted in the database. All SDK objects are unmanaged until you add them to a database within a write transaction. You cannot use the SDK's APIs with unmanaged objects or observe them for changes.

The SDK provides a variety of methods to create objects and perform write operations.

To create a new object and persist it to the database:

  1. Open a write transaction with Realm.write() function.

  2. Instantiate an unmanaged object instance within the realm namespace.

  3. Move the unmanaged object instance into the database using the Realm.add() function.

    When you move an object into a database, this consumes the object as an rvalue. You must use the managed object for any data access or observation. If you would like to immediately work with the object, return a managed version of the object.

  4. Work with the persisted SDK object through the returned instance. Note that this does not apply to asymmetric objects, which are write-only. Once an asymmetric object is synced, it is deleted from the database. You cannot read, update, or delete an asymmetric object from the device.

  1. Open a write transaction with the Realm.Write() or Realm.WriteAsync() methods. Prefer WriteAsync() to avoid blocking the UI, unless blocking the UI is desired.

  2. Instantiate an unmanaged object instance whose object model implements one of the SDK's object interfaces. For more information, refer to Define an SDK Object Model.

  3. Pass the unmanaged object instance to the Realm.Add() method to persist the object data to the database.

    Note that asymmetric objects are write-only. Once an asymmetric object is synced, it is deleted from the device database. You cannot read, update, or delete an asymmetric object from the device.

  1. Open a write transaction with a Realm.write() or Realm.writeAsync() methods.

  2. Instantiate an unmanaged object instance whose RealmObject model has been successfully created, generated, and imported into the file. For more information, refer to Define an SDK Object Model.

  3. Pass the unmanaged object instance to the Realm.add() method to persist the object data to the database. You can return managed objects from the write transaction block to observe or work with them immediately.

    Note that asymmetric objects are write-only. Once an asymmetric object is synced, it is deleted from the device database. You cannot read, update, or delete an asymmetric object from the device.

  1. Open a write transaction with the realm.executeTransaction() or realm.executeTransactionAsync() methods.

  2. Instantiate an unmanaged object instance whose model subclasses RealmObject or implements the RealmModel interface. For more information, refer to Define an SDK Object Model.

  3. Pass the unmanaged object instance to the realm.createObject() method or the createObjectFromJson() method to create an SDK object instance.

  1. Open a write transaction with the Realm.write() method.

  2. Instantiate an unmanaged object instance of your JavaScript class or a class that extends Realm.object. For more information, refer to Define an SDK Object Model.

  3. Pass the unmanaged object instance to the Realm.create() method to persist the object data to the database. You can assign the new managed object to a variable or return it from the write transaction block to observe or work with it immediately.

    Note that asymmetric objects are write-only. Once an asymmetric object is synced, it is deleted from the device database. You cannot read, update, or delete an asymmetric object from the device.

  1. Open a write transaction with realm.write() or realm.writeBlocking().

  2. Instantiate an unmanaged object instance with the class constructor. You can use an apply block to configure multiple properties at once.

  3. Pass the unmanaged object instance to copyToRealm() to persist the object data to the database. This method returns a live managed instance of the object.

    Important

    Asymmetric Objects Use Insert()

    Asymmetric objects are special write-only objects that do not persist to the database. They do not use copyToRealm(). Instead, you pass the asymmetric object instance to the insert() extension method within a write transaction. Refer to the Create an Asymmetric Object section on this page for more information.

  4. Work with the persisted SDK object through the returned instance. The live object is accessible until the write transaction completes. Note that this does not apply to asymmetric objects, which are write-only. Once an asymmetric object is synced, it is deleted from the device database. You cannot read, update, or delete an asymmetric object from the device.

Note

Frozen Objects

In Kotlin, objects returned from a write closure become frozen objects when the write transaction completes. For more information, refer to Live and Frozen Objects.

  1. Open a write transaction with the realm.executeTransaction() or realm.executeTransactionAsync() methods.

  2. Instantiate an unmanaged object instance whose model subclasses RealmObject or implements the RealmModel interface. For more information, refer to Define an SDK Object Model.

  3. Pass the unmanaged object instance to the realm.createObject() method or the createObjectFromJson() method to create an SDK object instance.

  1. Open a write transaction with the -[RLMRealm transactionWith:block] or the -[RLMRealm transactionWithoutNotifying:block:] methods.

  2. Instantiate an unmanaged object instance of a class that subclasses one of:

    For more information, refer to Define an SDK Object Model.

  3. Pass the unmanaged object instance to the -[RLMRealm addObject:] method to persist the object data to the database.

  1. Open a write transaction with the Realm.write(),``Realm.writeAsync()``, or Realm.asyncWrite() methods.

  2. Instantiate an unmanaged object instance of a class that subclasses one of:

    For more information, refer to Define an SDK Object Model.

  3. Pass the unmanaged object instance to the Realm.create() or Realm.add() methods to persist the object data to the database.

    Note that asymmetric objects are write-only. Once an asymmetric object is synced, it is deleted from the device database. You cannot read, update, or delete an asymmetric object from the device.

  1. Open a write transaction with the Realm.write() method.

  2. Instantiate an unmanaged object instance of a class that extends Realm.object. For more information, refer to Define an SDK Object Model.

  3. Pass the unmanaged object instance to the Realm.create() method to persist the object data to the database. You can assign the new managed object to a variable or return it from the write transaction block to observe or work with it immediately.

    Note that asymmetric objects are write-only. Once an asymmetric object is synced, it is deleted from the device database. You cannot read, update, or delete an asymmetric object from the device.

// Create an object using the `realm` namespace.
auto dog = realm::Dog{.name = "Rex", .age = 1};
std::cout << "dog: " << dog.name << "\n";
// Open the database with compile-time schema checking.
auto config = realm::db_config();
auto realm = realm::db(std::move(config));
// Persist your data in a write transaction
// Optionally return the managed object to work with it immediately
auto managedDog = realm.write([&] { return realm.add(std::move(dog)); });
var testItem = new Item
{
Name = "Do this thing",
Status = ItemStatus.Open.ToString(),
Assignee = "Aimee"
};
await realm.WriteAsync(() =>
{
realm.Add(testItem);
});
// Or
var testItem2 =
await realm.WriteAsync(() =>
{
return realm.Add<Item>(new Item
{
Name = "Do this thing, too",
Status = ItemStatus.InProgress.ToString(),
Assignee = "Satya"
});
}
);
final yoda = realm.write<Person>(() {
return realm.add(Person(ObjectId(), 'Yoda'));
});
realm.executeTransaction(r -> {
// Instantiate the class using the factory function.
Turtle turtle = r.createObject(Turtle.class, new ObjectId());
// Configure the instance.
turtle.setName("Max");
// Create a TurtleEnthusiast with a primary key.
ObjectId primaryKeyValue = new ObjectId();
TurtleEnthusiast turtleEnthusiast = r.createObject(TurtleEnthusiast.class, primaryKeyValue);
});
// Declare the variable that will hold the dog instance.
let dog;
// Open a transaction.
realm.write(() => {
// Assign a newly-created instance to the variable.
dog = realm.create("Dog", { name: "Max", age: 5 });
});
// use newly created dog object
// Open a write transaction
realm.write {
// Instantiate a new unmanaged Frog object
val unmanagedFrog = Frog().apply {
name = "Kermit"
age = 42
owner = "Jim Henson"
}
assertFalse(unmanagedFrog.isManaged())
// Copy the object to realm to return a managed instance
val managedFrog = copyToRealm(unmanagedFrog)
assertTrue(managedFrog.isManaged())
// Work with the managed object ...
}
realm.executeTransaction { r: Realm ->
// Instantiate the class using the factory function.
val turtle = r.createObject(Turtle::class.java, ObjectId())
// Configure the instance.
turtle.name = "Max"
// Create a TurtleEnthusiast with a primary key.
val primaryKeyValue = ObjectId()
val turtleEnthusiast = r.createObject(
TurtleEnthusiast::class.java,
primaryKeyValue
)
}
// Get the default realm.
// You only need to do this once per thread.
RLMRealm *realm = [RLMRealm defaultRealm];
// Instantiate the class.
Dog *dog = [[Dog alloc] init];
dog.name = @"Max";
dog.age = 5;
// Open a thread-safe transaction.
[realm transactionWithBlock:^() {
// Add the instance to the realm.
[realm addObject:dog];
}];
// Instantiate the class and set its values.
let dog = Dog()
dog.name = "Rex"
dog.age = 10
// Get the default realm. You only need to do this once per thread.
let realm = try! Realm()
// Open a thread-safe transaction.
try! realm.write {
// Add the instance to the realm.
realm.add(dog)
}
// The documentation does not currently have this code example in TypeScript.
// Please refer to the other languages or related pages for example code.

You can also upsert into a database using specific criteria. Refer to the Create or Update an Object (Upsert) section on this page.

Some of the SDKs provide a dedicated API to create multiple objects from a sequence or collection.

The SDK does not have a dedicated API to create multiple objects.

You can create multiple items in the database using the Add method. It takes a collection of standalone IRealmObject instances to add to the database.

To add multiple objects to a database, pass a list of multiple objects to Realm.addAll() inside a write transaction block.

The SDK does not have a dedicated API to create multiple objects.

The SDK does not have a dedicated API to create multiple objects.

The SDK does not have a dedicated API to create multiple objects.

The SDK does not have a dedicated API to create multiple objects.

You can create multiple items in the database using the -[RLMRealm addObjects:] method. It takes a collection of objects to add to the database.

You can create multiple items in the database using the add() method. It takes a sequence of objects to add to the database.

The SDK does not have a dedicated API to create multiple objects.

// The documentation does not currently have this code example in C++.
// Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in C#.
// Please refer to the other languages or related pages for example code.
realm.write(() {
realm.addAll([
Person(ObjectId(), 'Figrin D\'an'),
Person(ObjectId(), 'Greedo'),
Person(ObjectId(), 'Toro')
]);
});
// The Java SDK does not support this API.
// The Node.js SDK does not currently support this API.
// The Kotlin SDK does not currently support this API.
// The Java SDK does not support this API.
// The documentation does not currently have this code example in Objective-C.
// Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in Swift.
// Please refer to the other languages or related pages for example code.
// This API is not currently available in TypeScript.

An upsert is a write operation that either inserts a new object with a given primary key or updates an existing object that already has that primary key. We call this an upsert because it is an "update or insert" operation. This is useful when an object may or may not already exist, such as when bulk importing a dataset into an existing database. Upserting lets you update existing entries while adding any new entries.

This API is not currently supported in C++.

Upserting a document is the same as creating a new one, except you set the optional update parameter to true. In this example, we create a new Item object with a unique Id. We then insert an item with the same id but a different Name value. Because we have set the update parameter to true, the existing record is updated with the new name.

To upsert an object, call Realm.add() with the optional update flag set to true inside a transaction block.

The following example demonstrates how to upsert an object with the SDK. We create a new turtle enthusiast named "Drew" and then update their name to "Andy" using insertOrUpdate():

realm.executeTransaction(r -> {
ObjectId id = new ObjectId();
TurtleEnthusiast drew = new TurtleEnthusiast();
drew.set_id(id);
drew.setName("Drew");
drew.setAge(25);
// Add a new turtle enthusiast to the realm. Since nobody with this id
// has been added yet, this adds the instance to the realm.
r.insertOrUpdate(drew);
TurtleEnthusiast andy = new TurtleEnthusiast();
andy.set_id(id);
andy.setName("Andy");
andy.setAge(56);
// Judging by the ID, it's the same turtle enthusiast, just with a different name.
// As a result, you overwrite the original entry, renaming "Drew" to "Andy".
r.insertOrUpdate(andy);
});

You can also use copyToRealmOrUpdate() to either create a new object based on a supplied object or update an existing object with the same primary key value. Use the CHECK_SAME_VALUES_BEFORE_SET ImportFlag to only update fields that are different in the supplied object.

The following example demonstrates how to insert an object or, if an object already exists with the same primary key, update only those fields that differ:

To upsert an object, call Realm.create() with the update mode set to modified. The operation either inserts a new object with the given primary key or updates an existing object that already has that primary key.

To upsert an object into a database, insert an object with a primary key using copyToRealm(), as you would when creating a new object. Pass an UpdatePolicy parameter to specify how the SDK should handle existing objects with the same primary key:

  • UpdatePolicy.ALL: Update all properties on any existing objects identified with the same primary key.

  • UpdatePolicy.ERROR (default): Disallow updating existing objects and instead throw an exception if an object already exists with the same primary key. If you do not specify an update policy, the SDK uses this policy by default.

The following can occur depending on the update policy:

  • If no object exists that matches the primary key, the SDK creates the new object.

  • If an object with the same primary key already exists, the SDK either:

    • Updates all properties on any existing objects identified with the same primary key. Note that properties are marked as updated in change listeners, even if the property was updated to the same value.

    • Throws an exception indicating that an object already exists in the database.

In the following example, we attempt to insert a Frog object with a primary key that already exists in the database with UpdatePolicy.ALL. Then, we confirm the object is successfully upserted:

The following example demonstrates how to upsert an object with the SDK. We create a new turtle enthusiast named "Drew" and then update their name to "Andy" using insertOrUpdate():

realm.executeTransaction { r: Realm ->
val id = ObjectId()
val drew = TurtleEnthusiast()
drew._id = id
drew.name = "Drew"
drew.age = 25
// Add a new turtle enthusiast to the realm. Since nobody with this id
// has been added yet, this adds the instance to the realm.
r.insertOrUpdate(drew)
val andy = TurtleEnthusiast()
andy._id = id
andy.name = "Andy"
andy.age = 56
// Judging by the ID, it's the same turtle enthusiast, just with a different name.
// As a result, you overwrite the original entry, renaming "Drew" to "Andy".
r.insertOrUpdate(andy)
}

You can also use copyToRealmOrUpdate() to either create a new object based on a supplied object or update an existing object with the same primary key value. Use the CHECK_SAME_VALUES_BEFORE_SET ImportFlag to only update fields that are different in the supplied object.

The following example demonstrates how to insert an object or, if an object already exists with the same primary key, update only those fields that differ:

To upsert an object, call -[RLMRealm addOrUpdateObject:].

RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
Person *jones = [[Person alloc] initWithValue:@{@"_id": @1234, @"name": @"Jones"}];
// Add a new person to the realm. Since nobody with ID 1234
// has been added yet, this adds the instance to the realm.
[realm addOrUpdateObject:jones];
Person *bowie = [[Person alloc] initWithValue:@{@"_id": @1234, @"name": @"Bowie"}];
// Judging by the ID, it's the same person, just with a different name.
// This overwrites the original entry (i.e. Jones -> Bowie).
[realm addOrUpdateObject:bowie];
}];

You can also partially update an object by passing the primary key and a subset of the values to update:

To upsert an object, call Realm.add(_:update:) with the second parameter, update policy, set to .modified.

let realm = try! Realm()
try! realm.write {
let person1 = Person(value: ["id": 1234, "name": "Jones"])
// Add a new person to the realm. Since nobody with ID 1234
// has been added yet, this adds the instance to the realm.
realm.add(person1, update: .modified)
let person2 = Person(value: ["id": 1234, "name": "Bowie"])
// Judging by the ID, it's the same person, just with a
// different name. When `update` is:
// - .modified: update the fields that have changed.
// - .all: replace all of the fields regardless of
// whether they've changed.
// - .error: throw an exception if a key with the same
// primary key already exists.
realm.add(person2, update: .modified)
}

You can also partially update an object by passing the primary key and a subset of the values to update:

To upsert an object, call Realm.create() with the update mode set to modified. The operation either inserts a new object with the given primary key or updates an existing object that already has that primary key.

// The C++ SDK does not currently support this API.
var id = ObjectId.GenerateNewId();
var item1 = new Item
{
Id = id,
Name = "Defibrillate the Master Oscillator",
Assignee = "Aimee"
};
// Add a new person to the realm. Since nobody with the existing Id
// has been added yet, this person is added.
await realm.WriteAsync(() =>
{
realm.Add(item1, update: true);
});
var item2 = new Item
{
Id = id,
Name = "Fluxify the Turbo Encabulator",
Assignee = "Aimee"
};
// Based on the unique Id field, we have an existing person,
// but with a different name. When `update` is true, you overwrite
// the original entry.
await realm.WriteAsync(() =>
{
realm.Add(item2, update: true);
});
// item1 now has a Name of "Fluxify the Turbo Encabulator"
// and item2 was not added as a new Item in the collection.
final id = ObjectId();
// Add Anakin Skywalker to the realm with primary key `id`
final anakin = Person(
id,
"Anakin Skywalker",
);
realm.write(() {
realm.add<Person>(anakin);
});
// Overwrite the 'Anakin' Person object
// with a new 'Darth Vader' object
final darthVader = Person(id, 'Darth Vader');
realm.write(() {
realm.add<Person>(darthVader, update: true);
});
realm.executeTransaction(r -> {
ObjectId id = new ObjectId();
TurtleEnthusiast drew = new TurtleEnthusiast();
drew.set_id(id);
drew.setName("Drew");
drew.setAge(25);
// Add a new turtle enthusiast to the realm. Since nobody with this id
// has been added yet, this adds the instance to the realm.
r.insertOrUpdate(drew);
TurtleEnthusiast andy = new TurtleEnthusiast();
andy.set_id(id);
andy.setName("Andy");
// Judging by the ID, it's the same turtle enthusiast, just with a different name.
// As a result, you overwrite the original entry, renaming "Drew" to "Andy".
// the flag passed ensures that we only write the updated name field to the db
r.copyToRealmOrUpdate(andy, ImportFlag.CHECK_SAME_VALUES_BEFORE_SET);
});
realm.write(() => {
// Add a new person to the realm. Since nobody with ID 1234
// has been added yet, this adds the instance to the realm.
person = realm.create(
"Person",
{ _id: 1234, name: "Joe", age: 40 },
"modified"
);
// If an object exists, setting the third parameter (`updateMode`) to
// "modified" only updates properties that have changed, resulting in
// faster operations.
person = realm.create(
"Person",
{ _id: 1234, name: "Joseph", age: 40 },
"modified"
);
});
realm.write {
val existingFrog = query<Frog>("_id == $0", PRIMARY_KEY_VALUE).find().first()
assertEquals(existingFrog.name, "Kermit")
// Use copyToRealm() to insert the object with the primary key
// ** UpdatePolicy determines whether to update or throw an error if object already exists**
copyToRealm(Frog().apply {
_id = PRIMARY_KEY_VALUE
name = "Wirt"
age = 4
species = "Greyfrog"
owner = "L'oric"
}, UpdatePolicy.ALL)
val upsertFrog = query<Frog>("_id == $0", PRIMARY_KEY_VALUE).find().first()
assertEquals(upsertFrog.name, "Wirt")
}
realm.executeTransaction { r: Realm ->
val id = ObjectId()
val drew = TurtleEnthusiast()
drew._id = id
drew.name = "Drew"
drew.age = 25
// Add a new turtle enthusiast to the realm. Since nobody with this id
// has been added yet, this adds the instance to the realm.
r.insertOrUpdate(drew)
val andy = TurtleEnthusiast()
andy._id = id
andy.name = "Andy"
// Judging by the ID, it's the same turtle enthusiast, just with a different name.
// As a result, you overwrite the original entry, renaming "Drew" to "Andy".
r.copyToRealmOrUpdate(andy,
ImportFlag.CHECK_SAME_VALUES_BEFORE_SET)
}
RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
// Only update the provided values.
// Note that the "name" property will remain the same
// for the person with primary key "_id" 123.
[Person createOrUpdateModifiedInRealm:realm
withValue:@{@"_id": @123, @"dogs": @[@[@"Buster", @5]]}];
}];
let realm = try! Realm()
try! realm.write {
// Use .modified to only update the provided values.
// Note that the "name" property will remain the same
// for the person with primary key "id" 123.
realm.create(Person.self,
value: ["id": 123, "dogs": [["Buster", 5]]],
update: .modified)
}
// The documentation does not currently have this code example in TypeScript.
// Please refer to the other languages or related pages for example code.

Some of the SDKs provide specific methods to initialize objects with a value. Others use language-idiomatic methods to set the values of objects during initialization.

Some property types are only mutable in a write transaction. For example, you can instantiate an object with a Set property, but you can only set that property's value in a write transaction. You cannot initialize the object with a value for that property unless you do so inside a write transaction.

This SDK does not provide specialized methods to initialize objects with a value. Instead, use standard language features to create objects with initial values, or set the values after creating an object.

This SDK does not provide specialized methods to initialize objects with a value. Instead, use standard language features to create objects with initial values, or set the values after creating an object.

This SDK does not provide specialized methods to initialize objects with a value. Instead, use standard language features to create objects with initial values, or set the values after creating an object.

This SDK does not provide specialized methods to initialize objects with a value. Instead, use standard language features to create objects with initial values, or set the values after creating an object.

This SDK does not provide specialized methods to initialize objects with a value. Instead, use standard language features to create objects with initial values, or set the values after creating an object.

This SDK does not provide specialized methods to initialize objects with a value. Instead, use standard language features to create objects with initial values, or set the values after creating an object.

This SDK does not provide specialized methods to initialize objects with a value. Instead, use standard language features to create objects with initial values, or set the values after creating an object.

You can initialize an object by passing an initializer value to RLMObject initWithValue. The initializer value can be a key-value coding compliant object, a dictionary, or an array containing one element for each managed property.

Note

When using an array as an initializer value, you must include all properties in the same order as they are defined in the model.

You can initialize an object by passing an initializer value to Object.init(value:). The initializer value can be a key-value coding compliant object, a dictionary, or an array containing one element for each managed property.

Note

When using an array as an initializer value, you must include all properties in the same order as they are defined in the model.

This SDK does not provide specialized methods to initialize objects with a value. Instead, use standard language features to create objects with initial values, or set the values after creating an object.

// The C++ SDK does not currently support this API.
// The .NET SDK does not currently support this API.
// The Flutter SDK does not currently support this API.
// The Java SDK does not support this API.
// The Node.js SDK does not currently support this API.
// The Kotlin SDK does not currently support this API.
// The Java SDK does not support this API.
// (1) Create a Dog object from a dictionary
Dog *myDog = [[Dog alloc] initWithValue:@{@"name" : @"Pluto", @"age" : @3}];
// (2) Create a Dog object from an array
Dog *myOtherDog = [[Dog alloc] initWithValue:@[@"Pluto", @3]];
RLMRealm *realm = [RLMRealm defaultRealm];
// Add to the realm with transaction
[realm transactionWithBlock:^() {
[realm addObject:myDog];
[realm addObject:myOtherDog];
}];

You can even initialize related or embedded objects by nesting initializer values:

// Instead of using pre-existing dogs...
Person *aPerson = [[Person alloc]
initWithValue:@[@123, @"Jane", @[aDog, anotherDog]]];
// ...we can create them inline
Person *anotherPerson = [[Person alloc]
initWithValue:@[@123, @"Jane", @[@[@"Buster", @5], @[@"Buddy", @6]]]];
// (1) Create a Dog object from a dictionary
let myDog = Dog(value: ["name": "Pluto", "age": 3])
// (2) Create a Dog object from an array
let myOtherDog = Dog(value: ["Fido", 5])
let realm = try! Realm()
// Add to the realm inside a transaction
try! realm.write {
realm.add([myDog, myOtherDog])
}

You can even initialize related or embedded objects by nesting initializer values:

// Instead of using pre-existing dogs...
let aPerson = Person(value: [123, "Jane", [aDog, anotherDog]])
// ...we can create them inline
let anotherPerson = Person(value: [123, "Jane", [["Buster", 5], ["Buddy", 6]]])
// This API is not currently available in TypeScript.

Working with JSON returned from an API is a common development use case. Most of the supported SDK languages do not directly support creating objects from JSON. However, you may use language or platform-idiomatic APIs to transform JSON to a structure that matches your object schema, and create a matching object. Or you may model unstructured data to work with unstructured data that is highly variable or whose structure is unknown at runtime.

This language is currently missing an example of how to create objects from JSON.

This language is currently missing an example of how to create objects from JSON.

This language is currently missing an example of how to create objects from JSON.

You can insert objects into the database from JSON. The SDK supports creating objects from String, JSONObject, and InputStream types. The SDK ignores any properties present in the JSON that are not defined in the SDK object schema.

The following example demonstrates how to create a single object from JSON with createObjectFromJson() or multiple objects from JSON with createAllFromJson():

This language is currently missing an example of how to create objects from JSON.

This language is currently missing an example of how to create objects from JSON.

You can insert objects into the database from JSON. The SDK supports creating objects from String, JSONObject, and InputStream types. The SDK ignores any properties present in the JSON that are not defined in the SDK object schema.

The following example demonstrates how to create a single object from JSON with createObjectFromJson() or multiple objects from JSON with createAllFromJson():

The SDK does not directly support JSON, but you can use NSJSONSerialization to convert JSON into a value that you can pass to RLMObject createInRealm(withValue:).

Nested objects or arrays in the JSON map to to-one or to-many relationships.

The JSON property names and types must match the destination object model exactly. For example:

  • float properties must be initialized with float-backed NSNumbers.

  • Date and Data properties cannot be inferred from strings. Convert them to the appropriate type before passing to RLMObject createInRealm(withValue:).

  • Required properties cannot be null or missing in the JSON.

The SDK ignores any properties in the JSON not defined in the object schema.

Tip

If your JSON schema doesn't exactly align with your SDK objects, consider using a third-party framework to transform your JSON. There are many model mapping frameworks that work with the SDK. See a partial list in the realm-swift repository.

The SDK does not directly support JSON, but you can use JSONSerialization.jsonObject(with:options:) to convert JSON into a value that you can pass to Realm.create(_:value:update:).

Nested objects or arrays in the JSON map to to-one or to-many relationships.

The JSON property names and types must match the destination object model exactly. For example:

  • float properties must be initialized with float-backed NSNumbers.

  • Date and Data properties cannot be inferred from strings. Convert them to the appropriate type before passing to Realm.create(_:value:update:).

  • Required properties cannot be null or missing in the JSON.

The SDK ignores any properties in the JSON not defined in the object schema.

Tip

If your JSON schema doesn't exactly align with your SDK objects, consider using a third-party framework to transform your JSON. There are many model mapping frameworks that work with the SDK. See a partial list in the realm-swift repository.

This language is currently missing an example of how to create objects from JSON.

// The documentation does not currently have this code example in C++.
// Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in C#.
// Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in Dart.
// Please refer to the other languages or related pages for example code.
// Insert from a string
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.createObjectFromJson(Frog.class,
"{ name: \"Doctor Cucumber\", age: 1, species: \"bullfrog\", owner: \"Wirt\" }");
}
});
// Insert multiple items using an InputStream
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
try {
InputStream inputStream = new FileInputStream(
new File("path_to_file"));
realm.createAllFromJson(Frog.class, inputStream);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
// The documentation does not currently have this code example in JavaScript.
// Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in Kotlin.
// Please refer to the other languages or related pages for example code.
// Insert from a string
realm.executeTransaction { realm ->
realm.createObjectFromJson(
Frog::class.java,
"{ name: \"Doctor Cucumber\", age: 1, species: \"bullfrog\", owner: \"Wirt\" }"
)
}
// Insert multiple items using an InputStream
realm.executeTransaction { realm ->
try {
val inputStream: InputStream =
FileInputStream(File("path_to_file"))
realm.createAllFromJson(Frog::class.java, inputStream)
} catch (e: IOException) {
throw RuntimeException(e)
}
}
// Specify a dog toy in JSON
NSData *data = [@"{\"name\": \"Tennis ball\"}" dataUsingEncoding: NSUTF8StringEncoding];
RLMRealm *realm = [RLMRealm defaultRealm];
// Insert from NSData containing JSON
[realm transactionWithBlock:^{
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
[DogToy createInRealm:realm withValue:json];
}];
// Specify a dog toy in JSON
let data = "{\"name\": \"Tennis ball\"}".data(using: .utf8)!
let realm = try! Realm()
// Insert from data containing JSON
try! realm.write {
let json = try! JSONSerialization.jsonObject(with: data, options: [])
realm.create(DogToy.self, value: json)
}
// The documentation does not currently have this code example in TypeScript.
// Please refer to the other languages or related pages for example code.

Some of the SDKs provide APIs to create an unmanaged, in-memory copy of a managed object or collection. In other SDKs, this API is not needed or not currently implemented.

Create an unmanaged version of a managed object by calling the detach() function. This returns a value of the managed type. For example, calling the detach() function on a managed string property of a managed object returns a std::string copy of that property.

The SDK does not provide a C# API to directly create an unmanaged copy of an object. Instead, you can use a third-party library such as AutoMapper to create unmanaged objects.

The API to create an unmanaged copy of an object is either not needed or not currently supported in this SDK.

Use realm.copyFromRealm() to create an in-memory instance of a database object.

The API to create an unmanaged copy of an object is either not needed or not currently supported in this SDK.

Create an unmanaged copy of a managed object by passing it to copyFromRealm(). For collections, this is a deep copy that includes all referenced objects up to the specified depth.

In the following example, we create an unmanaged copy of an existing managed Pond object that contains a list of two Frog objects. After copying the object from the database, we confirm that the copy is unmanaged and contains both referenced Frog objects:

Use realm.copyFromRealm() to create an in-memory instance of a database object.

The API to create an unmanaged copy of an object is either not needed or not currently supported in this SDK.

The API to create an unmanaged copy of an object is either not needed or not currently supported in this SDK.

The API to create an unmanaged copy of an object is either not needed or not currently supported in this SDK.

// The documentation does not currently have this code example in C++.
// Please refer to the other languages or related pages for example code.
// The .NET SDK does not currently support this API.
// The Flutter SDK does not currently support this API.
// The documentation does not have this code example in Java.
// Please refer to the other languages or related pages for example code.
// The Node.js SDK does not currently support this API.
realm.writeBlocking {
// Fetch the managed object you want to copy
val managedPond = query<Pond>("name == $0", "Big Pond").find().first()
assertTrue(managedPond.isManaged())
// Create an unmanaged copy of the object
val unmanagedPond = copyFromRealm(managedPond)
assertFalse(unmanagedPond.isManaged())
Log.v("Unmanaged pond name: ${unmanagedPond.name}")
// Confirm the unmanaged copy contains all elements
// in the copied object's RealmList
val unmanagedFrogs = unmanagedPond.frogsThatLiveHere
assertFalse(unmanagedFrogs[0].isManaged())
assertFalse(unmanagedFrogs[1].isManaged())
assertEquals(2, unmanagedFrogs.size)
Log.v("Unmanaged frogs: ${unmanagedFrogs[0].name}, ${unmanagedFrogs[1].name}")
}
Unmanaged pond name: Big Pond
Unmanaged frogs: Kermit, Froggy Jay
// The documentation does not have this code example in Kotlin for the Java SDK.
// Please refer to the other languages or related pages for example code.
// The Swift SDK does not currently support this API.
// The Swift SDK does not currently support this API.
// This API is not currently available in TypeScript.

You can copy objects that are managed by one database instance to another database instance.

The selected language does not currently have an example of how to copy an object to another database instance.

The SDK does not provide a C# API to directly copy an object to another database instance. Instead, you can use a third-party library such as AutoMapper to create unmanaged objects and then copy them into another database instance.

The selected language does not currently have an example of how to copy an object to another database instance.

Use realm.copyToRealm() in a write transaction to copy a managed object to another database instance.

Alternately, to copy an object that does not exist, or update an object that does exist, use realm.copyToRealmOrUpdate(). This copies an object where the target database instance does not contain an object with the same primary key. If the target database instance already contains an object with a matching primary key, it updates the object.

To copy a managed object to another database instance, call the Realm.create() method in a write transaction with the object to copy. You can optionally specify the UpdateMode to determine how to handle copying objects where the target database instance already contains an object with a matching primary key.

You can copy an SDK object to a MutableRealm instance with the copyToRealm() method. The UpdatePolicy you specify determines how to handle copying objects where the target database instance already contains an object with a matching primary key.

Use realm.copyToRealm() in a write transaction to copy a managed object to another database instance.

Alternately, to copy an object that does not exist, or update an object that does exist, use realm.copyToRealmOrUpdate(). This copies an object where the target database instance does not contain an object with the same primary key. If the target database instance already contains an object with a matching primary key, it updates the object.

To copy a managed object to another database instance, call the RLMObject createOrUpdateInRealm:withValue or RLMObject createOrUpdateModifiedInRealm:withValue method in a write transaction.

If the object type does not have a primary key, or no object with a matching primary key exists, this method creates a new object in the target database instance.

If an object with a matching primary key already exists in the target database instance, createOrUpdateInRealm sets each property defined in its schema by copying from value using key-value coding.

Alternately, createOrUpdateModifiedInRealm only sets values which have changed. Checking which properties have changed imposes a small amount of overhead, and so this method may be slower when all or nearly all of the properties being set have changed. If most or all of the properties being set have not changed, this method is much faster than unconditionally setting all of them. It also reduces how much data has to be written to the database, saving both i/o time and disk space.

To copy a managed object to another database instance, call the create(value: update:) method in a write transaction.

If the object type does not have a primary key, or no object with a matching primary key exists, this method creates a new object in the target database instance. If an object with a matching primary key already exists in the target database instance, and you set the update policy to .modified or .all, this method updates the existing object returns a reference to it.

To copy a managed object to another database instance, call the Realm.create() method in a write transaction with the object to copy. You can optionally specify the UpdateMode to determine how to handle copying objects where the target database instance already contains an object with a matching primary key.

// The documentation does not currently have this code example in C++.
// Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in C#.
// Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in Dart.
// Please refer to the other languages or related pages for example code.
// The documentation does not have this code example in Java.
// Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in JavaScript.
// Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in Kotlin.
// Please refer to the other languages or related pages for example code.
// The documentation does not have this code example in Kotlin for the Java SDK.
// Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in Objective-C.
// Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in Swift.
// Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in TypeScript.
// Please refer to the other languages or related pages for example code.

When performing large write operations, you may want to create objects in the background. This avoids blocking the UI thread while performing large write operations. This is particularly useful when using Device Sync, where you don't know when and for how long the Sync client will be writing.

Open a write transaction with the or Realm.WriteAsync() method to avoid blocking the UI thread.

You can add, modify, or delete objects asynchronously using Realm.writeAsync().

When you use Realm.writeAsync() to perform write operations, waiting to obtain the write lock and committing a transaction occur in the background. Only the write itself occurs on the main process.

You can add, modify, or delete objects in the background using writeAsync.

With writeAsync, you don't need to pass a thread-safe reference or frozen objects across threads. Instead, call realm.writeAsync. You can provide a completion block for the method to execute on the source thread after the write completes or fails.

Things to consider when performing background writes:

  • Async writes block closing or invalidating the database

  • You can explicitly commit or cancel transactions

The SDK provides a Bool to signal whether the database is currently performing an async write. The isPerformingAsynchronousWriteOperations variable becomes true after a call to one of:

  • writeAsync

  • beginAsyncWrite

  • commitAsyncWrite

It remains true until all scheduled async write operations have completed. While this is true, this blocks closing or invalidating the database.

To complete an async write, you or the SDK must call either:

When you use the writeAsync method, the SDK handles committing or canceling the transaction. This provides the convenience of the async write without the need to manually keep state tied to the scope of the object. However, while in the writeAsync block, you can explicitly call commitAsyncWrite or cancelAsyncWrite. If you return without calling one of these methods, writeAsync either:

  • Commits the write after executing the instructions in the write block

  • Returns an error

In either case, this completes the writeAsync operation.

For more control over when to commit or cancel the async write transaction, use the beginAsyncWrite method. When you use this method, you must explicitly commit the transactions. Returning without committing an async write cancels the transaction. beginAsyncWrite returns an ID that you can pass to cancelAsyncWrite.

commitAsyncWrite asynchronously commits a write transaction. This is the step that persists the data to the database. commitAsyncWrite can take an onComplete block. This block executes on the source thread once the commit completes or fails with an error.

Calling commitAsyncWrite immediately returns. This allows the caller to proceed while the SDK performs the I/O on a background thread. This method returns an ID that you can pass to cancelAsyncWrite. This cancels the pending invocation of the completion block. It does not cancel the commit itself.

You can group sequential calls to commitAsyncWrite. Batching these calls improves write performance; particularly when the batched transactions are small. To permit grouping transactions, set the isGroupingAllowed parameter to true.

You can call cancelAsyncWrite on either beginAsyncWrite or commitAsyncWrite. When you call it on beginAsyncWrite, this cancels the entire write transaction. When you call it on commitAsyncWrite, this cancels only an onComplete block you may have passed to commitAsyncWrite. It does not cancel the commit itself. You need the ID of the beginAsyncWrite or the commitAsyncWrite you want to cancel.

You can use Swift concurrency features to write asynchronously to an actor-isolated database.

The following function is taken from the example RealmActor defined on the Define a Custom Database Actor page. It shows how you might write to an actor-isolated database:

func createTodo(name: String, owner: String, status: String) async throws {
try await realm.asyncWrite {
realm.create(Todo.self, value: [
"_id": ObjectId.generate(),
"name": name,
"owner": owner,
"status": status
])
}
}

And you might perform this write using Swift's async syntax:

func createObject() async throws {
// Because this function is not isolated to this actor,
// you must await operations completed on the actor
try await actor.createTodo(name: "Take the ring to Mount Doom", owner: "Frodo", status: "In Progress")
let taskCount = await actor.count
print("The actor currently has \(taskCount) tasks")
}
let actor = try await RealmActor()
try await createObject()

This operation does not block or perform I/O on the calling thread. For more information about writing to a database using Swift concurrency features, refer to Use Atlas Device SDK for Swift with Actors.

The asyncWrite() API allows for performing async writes using Swift async/await syntax.

The asyncWrite() API suspends the calling task while waiting for its turn to write rather than blocking the thread. In addition, the actual I/O to write data to disk is done by a background worker thread. For small writes, using this function on the main thread may block the main thread for less time than manually dispatching the write to a background thread.

// The documentation does not currently have this code example in C++.
// Please refer to the other languages or related pages for example code.
var testItem = new Item
{
Name = "Do this thing",
Status = ItemStatus.Open.ToString(),
Assignee = "Aimee"
};
await realm.WriteAsync(() =>
{
realm.Add(testItem);
});
// Or
var testItem2 =
await realm.WriteAsync(() =>
{
return realm.Add<Item>(new Item
{
Name = "Do this thing, too",
Status = ItemStatus.InProgress.ToString(),
Assignee = "Satya"
});
}
);
// Add Leia to the realm using `writeAsync`
Person leia = Person(ObjectId(), "Leia");
realm.writeAsync(() {
realm.add<Person>(leia);
});
// The documentation does not have this code example in Java.
// Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in JavaScript.
// Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in Kotlin.
// Please refer to the other languages or related pages for example code.
// The documentation does not have this code example in Kotlin for the Java SDK.
// Please refer to the other languages or related pages for example code.
// The documentation does not currently have this code example in Objective-C.
// Please refer to the other languages or related pages for example code.
let realm = try! Realm()
// Query for a specific person object on the main thread
let people = realm.objects(Person.self)
let thisPerson = people.where {
$0.name == "Dachary"
}.first
// Perform an async write to add dogs to that person's dog list.
// No need to pass a thread-safe reference or frozen object.
realm.writeAsync {
thisPerson?.dogs.append(objectsIn: [
Dog(value: ["name": "Ben", "age": 13]),
Dog(value: ["name": "Lita", "age": 9]),
Dog(value: ["name": "Maui", "age": 1])
])
} onComplete: { _ in
// Confirm the three dogs were successfully added to the person's dogs list
XCTAssertEqual(thisPerson!.dogs.count, 3)
// Query for one of the dogs we added and see that it is present
let dogs = realm.objects(Dog.self)
let benDogs = dogs.where {
$0.name == "Ben"
}
XCTAssertEqual(benDogs.count, 1)
}
// The documentation does not currently have this code example in TypeScript.
// Please refer to the other languages or related pages for example code.

Back

Read & Write Data

Next

Create Objects