Docs Menu
Docs Home
/ /
CRUD

CRUD - Crear - Swift SDK

Los ejemplos de esta página utilizan los siguientes modelos:

// DogToy.h
@interface DogToy : RLMObject
@property NSString *name;
@end
// Dog.h
@interface Dog : RLMObject
@property NSString *name;
@property int age;
@property NSString *color;
// To-one relationship
@property DogToy *favoriteToy;
@end
// Enable Dog for use in RLMArray
RLM_COLLECTION_TYPE(Dog)
// Person.h
// A person has a primary key ID, a collection of dogs, and can be a member of multiple clubs.
@interface Person : RLMObject
@property int _id;
@property NSString *name;
// To-many relationship - a person can have many dogs
@property RLMArray<Dog *><Dog> *dogs;
// Inverse relationship - a person can be a member of many clubs
@property (readonly) RLMLinkingObjects *clubs;
@end
RLM_COLLECTION_TYPE(Person)
// DogClub.h
@interface DogClub : RLMObject
@property NSString *name;
@property RLMArray<Person *><Person> *members;
@end
// Dog.m
@implementation Dog
@end
// DogToy.m
@implementation DogToy
@end
// Person.m
@implementation Person
// Define the primary key for the class
+ (NSString *)primaryKey {
return @"_id";
}
// Define the inverse relationship to dog clubs
+ (NSDictionary *)linkingObjectsProperties {
return @{
@"clubs": [RLMPropertyDescriptor descriptorWithClass:DogClub.class propertyName:@"members"],
};
}
@end
// DogClub.m
@implementation DogClub
@end
class DogToy: Object {
@Persisted var name = ""
}
class Dog: Object {
@Persisted var name = ""
@Persisted var age = 0
@Persisted var color = ""
@Persisted var currentCity = ""
@Persisted var citiesVisited: MutableSet<String>
@Persisted var companion: AnyRealmValue
// To-one relationship
@Persisted var favoriteToy: DogToy?
// Map of city name -> favorite park in that city
@Persisted var favoriteParksByCity: Map<String, String>
}
class Person: Object {
@Persisted(primaryKey: true) var id = 0
@Persisted var name = ""
// To-many relationship - a person can have many dogs
@Persisted var dogs: List<Dog>
// Embed a single object.
// Embedded object properties must be marked optional.
@Persisted var address: Address?
convenience init(name: String, address: Address) {
self.init()
self.name = name
self.address = address
}
}
class Address: EmbeddedObject {
@Persisted var street: String?
@Persisted var city: String?
@Persisted var country: String?
@Persisted var postalCode: String?
}

Para agregar un objeto a un reino, instancielo como lo haría con cualquier otro objeto y luego páselo a -[RLMRealm addObject:] dentro de una transacción de escritura.

// 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];
}];

Para agregar un objeto a un reino, instancielo como lo haría con cualquier otro objeto y luego páselo a Realm.add(_:update:) dentro de una transacción de escritura.

// 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)
}

Puede inicializar un objeto pasando un valor de inicialización a Object.init(value:). El valor de inicialización puede ser un código clave-valor. objeto compatible, un diccionario o una matriz que contiene un elemento para cada propiedad administrada.

Nota

Al utilizar un arreglo como valor inicializador, debes incluir todas las propiedades en el mismo orden en que se definen en el modelo.

// (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];
}];
// (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])
}

Incluso puedes inicializar objetos relacionados o incrustados anidando valores de inicializador:

// 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]]]];
// 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]]])

Algunos tipos de propiedad solo son mutables en una transacción de escritura. Por ejemplo, se puede instanciar un objeto con una propiedad MutableSet, pero solo se puede establecer el valor de esa propiedad en una transacción de escritura. No se puede inicializar el objeto con un valor para esa propiedad a menos que se haga dentro de una transacción de escritura.

Realm no admite JSON directamente, pero puedes usar JSONSerialization.jsonObject(with:options:) para convertir JSON en un valor que puedas pasar a Realm.create(_:value:update:).

// 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)
}

Los objetos anidados o matrices en el mapa JSON se asignan a relaciones de uno a muchos.

Los nombres y tipos de propiedades JSON deben coincidir exactamente con el esquema del objeto de destino. Por ejemplo:

  • float Las propiedades deben inicializarse con un valor flotante NSNumbers.

  • Date y no se pueden inferir las propiedades de Data a partir de cadenas. Convierte las propiedades al tipo adecuado antes de pasarlas a Realm.create(_:value:update:).

  • Las propiedades obligatorias no pueden ser null o faltar en el JSON.

Realm ignora cualquier propiedad en JSON que no esté definida en el esquema del objeto.

Tip

Si su esquema JSON no se ajusta exactamente a sus objetos de Realm, considere usar un framework de terceros para transformar su JSON. Existen muchos frameworks de mapeo de modelos compatibles con Realm. Consulte una lista parcial en el repositorio realm-swift.

Para crear un objeto incrustado, asigne una instancia del objeto incrustado a una propiedad del objeto principal:

RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
Address *address = [[Address alloc] init];
address.street = @"123 Fake St.";
address.city = @"Springfield";
address.country = @"USA";
address.postalCode = @"90710";
Contact *contact = [Contact contactWithName:@"Nick Riviera"];
// Assign the embedded object property
contact.address = address;
[realm addObject:contact];
NSLog(@"Added contact: %@", contact);
}];
// Open the default realm
let realm = try! Realm()
try! realm.write {
let address = Address()
address.street = "123 Fake St"
address.city = "Springfield"
address.country = "USA"
address.postalCode = "90710"
let contact = Person(name: "Nick Riviera", address: address)
realm.add(contact)
}

Cuando crea un objeto que tiene una propiedad de mapa, puede establecer los valores de las claves de varias maneras:

  • Establece claves y valores en el objeto y luego agrega el objeto al realm

  • Establezca las claves y los valores del objeto directamente dentro de una transacción de escritura

  • Utilice la codificación clave-valor para establecer o actualizar claves y valores dentro de una transacción de escritura

let realm = try! Realm()
// Record a dog's name and current city
let dog = Dog()
dog.name = "Wolfie"
dog.currentCity = "New York"
// Set map values
dog.favoriteParksByCity["New York"] = "Domino Park"
// Store the data in a realm
try! realm.write {
realm.add(dog)
// You can also set map values inside a write transaction
dog.favoriteParksByCity["Chicago"] = "Wiggly Field"
dog.favoriteParksByCity.setValue("Bush Park", forKey: "Ottawa")
}

Realm no permite el uso de caracteres . o $ en las claves de mapa. Puedes usar la codificación y decodificación porcentual para almacenar una clave de mapa que contenga uno de estos caracteres no permitidos.

// Percent encode . or $ characters to use them in map keys
let mapKey = "New York.Brooklyn"
let encodedMapKey = "New York%2EBrooklyn"

Puedes crear objetos que contengan propiedades MutableSet como cualquier objeto Realm, pero solo puedes mutar un MutableSet dentro de una transacción de escritura. Esto significa que solo puedes establecer los valores de una propiedad de conjunto mutable dentro de una transacción de escritura.

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)
// You can only mutate the MutableSet in a write transaction.
// This means you can't set values at initialization, but must do it during a write.
dog.citiesVisited.insert(dog.currentCity)
}
// You can also add multiple items to the set.
try! realm.write {
dog.citiesVisited.insert(objectsIn: ["Boston", "Chicago"])
}
print("\(dog.name) has visited: \(dog.citiesVisited)")

Al crear un objeto con una propiedad AnyRealmValue, debe especificar el tipo del valor que almacena en ella. El SDK de Swift de Realm proporciona una enumeración AnyRealmValue que itera sobre todos los tipos que AnyRealmValue puede almacenar.

Más tarde, cuando lea un AnyRealmValue, deberá verificar el tipo antes de hacer cualquier cosa con el valor.

// Create a Dog object and then set its properties
let myDog = Dog()
myDog.name = "Rex"
// This dog has no companion.
// You can set the field's type to "none", which represents `nil`
myDog.companion = .none
// Create another Dog whose companion is a cat.
// We don't have a Cat object, so we'll use a string to describe the companion.
let theirDog = Dog()
theirDog.name = "Wolfie"
theirDog.companion = .string("Fluffy the Cat")
// Another dog might have a dog as a companion.
// We do have an object that can represent that, so we can specify the
// type is a Dog object, and even set the object's value.
let anotherDog = Dog()
anotherDog.name = "Fido"
// Note: this sets Spot as a companion of Fido, but does not set
// Fido as a companion of Spot. Spot has no companion in this instance.
anotherDog.companion = .object(Dog(value: ["name": "Spot"]))
// Add the dogs to the realm
let realm = try! Realm()
try! realm.write {
realm.add([myDog, theirDog, anotherDog])
}
// After adding these dogs to the realm, we now have 4 dog objects.
let dogs = realm.objects(Dog.self)
XCTAssertEqual(dogs.count, 4)

Puede utilizar las funciones de concurrencia de Swift para escribir de forma asincrónica en un ámbito aislado del actor.

Esta función del ejemplo RealmActor definido en la página Usar reino con actores muestra cómo se puede escribir en un reino aislado de actores:

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
])
}
}

Y puedes realizar esta escritura utilizando la sintaxis asíncrona de Swift:

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()

Esta operación no bloquea ni realiza operaciones de E/S en el hilo que realiza la llamada. Para obtener más información sobre cómo escribir en el dominio usando las funciones de concurrencia de Swift, consulte Usar dominio con actores - SDK de Swift.

Nuevo en la versión 10.29.0.

Solo se puede crear un AsymmetricObject mediante create(_ type:, value:). Al crear un AsymmetricObject, este se sincroniza unidireccionalmente mediante la ingesta de datos con la base de datos de Atlas vinculada a la aplicación de Atlas App Services. No se puede acceder a un AsymmetricObject localmente, añadirlo o eliminarlo de un dominio, ni consultarlo.

@MainActor
func useRealm(_ asymmetricRealm: Realm, _ user: User) async {
try! asymmetricRealm.write {
asymmetricRealm.create(WeatherSensor.self,
value: [ "_id": ObjectId.generate(),
"deviceId": "WX1278UIT",
"temperatureInFahrenheit": 66.7,
"barometricPressureInHg": 29.65,
"windSpeedInMph": 2
])
}
}

Puedes crear objetos asimétricos para un dominio inicializado con una configuración de sincronización flexible. Para obtener más información, consulta: Abrir un dominio sincronizado para la sincronización flexible.

Para copiar un objeto de un reino a otro, pase el objeto original a +[RLMObject createInRealm:withValue:]:

RLMRealmConfiguration *configuration = [RLMRealmConfiguration defaultConfiguration];
configuration.inMemoryIdentifier = @"first realm";
RLMRealm *realm = [RLMRealm realmWithConfiguration:configuration error:nil];
[realm transactionWithBlock:^{
Dog *dog = [[Dog alloc] init];
dog.name = @"Wolfie";
dog.age = 1;
[realm addObject:dog];
}];
// Later, fetch the instance we want to copy
Dog *wolfie = [[Dog objectsInRealm:realm where:@"name == 'Wolfie'"] firstObject];
// Open the other realm
RLMRealmConfiguration *otherConfiguration = [RLMRealmConfiguration defaultConfiguration];
otherConfiguration.inMemoryIdentifier = @"second realm";
RLMRealm *otherRealm = [RLMRealm realmWithConfiguration:otherConfiguration error:nil];
[otherRealm transactionWithBlock:^{
// Copy to the other realm
Dog *wolfieCopy = [[wolfie class] createInRealm:otherRealm withValue:wolfie];
wolfieCopy.age = 2;
// Verify that the copy is separate from the original
XCTAssertNotEqual(wolfie.age, wolfieCopy.age);
}];

Para copiar un objeto de un reino a otro, pase el objeto original a Realm.create(_:value:update:)::

let realm = try! Realm(configuration: Realm.Configuration(inMemoryIdentifier: "first realm"))
try! realm.write {
let dog = Dog()
dog.name = "Wolfie"
dog.age = 1
realm.add(dog)
}
// Later, fetch the instance we want to copy
let wolfie = realm.objects(Dog.self).first(where: { $0.name == "Wolfie" })!
// Open the other realm
let otherRealm = try! Realm(configuration: Realm.Configuration(inMemoryIdentifier: "second realm"))
try! otherRealm.write {
// Copy to the other realm
let wolfieCopy = otherRealm.create(type(of: wolfie), value: wolfie)
wolfieCopy.age = 2
// Verify that the copy is separate from the original
XCTAssertNotEqual(wolfie.age, wolfieCopy.age)
}

Importante

Los métodos create no admiten el manejo de grafos de objetos cíclicos. No pase un objeto que contenga relaciones que involucren objetos que remitan a sus padres, ya sea directa o indirectamente.

Volver

CRUD

En esta página