Crear un nuevo objeto
Acerca de los ejemplos en esta página
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 { var name = "" } class Dog: Object { var name = "" var age = 0 var color = "" var currentCity = "" var citiesVisited: MutableSet<String> var companion: AnyRealmValue // To-one relationship var favoriteToy: DogToy? // Map of city name -> favorite park in that city var favoriteParksByCity: Map<String, String> } class Person: Object { (primaryKey: true) var id = 0 var name = "" // To-many relationship - a person can have many dogs var dogs: List<Dog> // Embed a single object. // Embedded object properties must be marked optional. var address: Address? convenience init(name: String, address: Address) { self.init() self.name = name self.address = address } } class Address: EmbeddedObject { var street: String? var city: String? var country: String? var postalCode: String? }
Crear un objeto
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) }
Inicializar objetos con un valor
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 propiedades solo se pueden modificar en una transacción de escritura
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.
Crear un objeto con JSON
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:
floatLas propiedades deben inicializarse con un valor flotanteNSNumbers.Datey no se pueden inferir las propiedades deDataa partir de cadenas. Convierte las propiedades al tipo adecuado antes de pasarlas a Realm.create(_:value:update:).Las propiedades obligatorias no pueden ser
nullo 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.
Crear un objeto incrustado
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) }
Crear un objeto con una propiedad de mapa
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"
Crear un objeto con una propiedad MutableSet
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)")
Crear un objeto con una propiedad AnyRealmValue
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)
Crear un objeto de forma asincrónica
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.
Crear un objeto asimétrico
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.
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.
Copiar un objeto a otro reino
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.