CRUD - Criar - Swift SDK
Nesta página
- Criar um novo objeto
- Sobre os exemplos nesta página
- Criar um objeto
- Inicializar objetos com um valor
- Criar um objeto com JSON
- Criar um Objeto Embarcado
- Criar um objeto com uma propriedade de mapa
- Criar um objeto com uma propriedade MutableSet
- Criar um objeto com uma propriedade AnyRealmValue
- Criar um Objeto de Forma Assíncrona
- Criar um objeto assimétrico
- Copiar um Objeto para Outro Realm
Criar um novo objeto
Sobre os exemplos nesta página
Os exemplos nesta página usam os seguintes 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 { true) var id = 0 (primaryKey: 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? }
Criar um objeto
Para adicionar um objeto a um Realm, instancie-o como faria com qualquer outro objeto e, em seguida, passe-o para -[RLMRealm addObject:] dentro de uma transação de gravação.
// 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 adicionar um objeto a um domínio, instancie-o como faria com qualquer outro objeto e, em seguida, passe para Realm.add(_:update:) dentro de uma transação de gravação.
// 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 com um valor
Você pode inicializar um objeto passando um valor inicializador para Object.init(value:). O valor do inicializador pode ser uma codificação de valor-chave objeto compatível , um dicionário ou uma array contendo um elemento para cada propriedade gerenciada.
Observação
Se for usar uma matriz como valor inicializador, inclua todas as propriedades na mesma ordem em que foram definidas no 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]) }
Você pode até mesmo inicializar objetos relacionados ou incorporados aninhando valores do 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]]])
Alguns Tipos de Propriedades são Mutáveis Apenas nas Transações de Escrita
Alguns tipos de propriedades são mutáveis apenas nas transações de escrita. Por exemplo, é possível instanciar um objeto com uma propriedade MutableSet, mas só é possível definir o valor dessa propriedade em uma transação de gravação. Não é possível inicializar o objeto com um valor para essa propriedade, a menos que você faça isso dentro de uma transação de gravação.
Criar um objeto com JSON
O Realm não suporta diretamente JSON, mas você pode utilizar JSONSerialization.jsonObject(with:options:) para converter JSON em um valor que você pode transferir para 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) }
Objetos ou arrays aninhados no mapa JSON para relacionamentos para-um ou para-muitos.
Os nomes e tipos de propriedade JSON devem corresponder exatamente ao esquema de objeto de destino. Por exemplo:
float
as propriedades devem ser inicializadas comNSNumbers
baseada em números de pontos flutuantes.Date
e propriedades doData
não podem ser inferidas a partir de strings. Converta-os para o tipo apropriado antes de passar para Realm.create(_:value:update:).As propriedades obrigatórias não podem ser
null
ou estar ausentes no JSON.
O Realm ignora todas as propriedades no JSON não definidas no esquema de objetos.
Dica
Se o JSON schema não estiver alinhado exatamente com os objetos de Realm , considere a possibilidade de usar um framework de terceiros para transformar seu JSON. Existem muitas frameworks de mapeamento de modelos que funcionam com Realm. Veja uma lista parcial no repositório domínio-swift .
Criar um Objeto Embarcado
Para criar um objeto embarcado, atribua uma instância do objeto embarcado à propriedade de um objeto pai:
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) }
Criar um objeto com uma propriedade de mapa
Ao criar um objeto que tenha uma propriedade map, você pode definir os valores para chaves de algumas maneiras:
Definir chaves e valores no objeto e depois adicionar o objeto ao domínio
Definir as chaves e os valores do objeto diretamente dentro de uma transação de escrita
Use a programação de valores-chave para definir ou atualizar chaves e valores dentro de uma transação de escrita
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") }
O Realm não permite o uso de .
ou $
caracteres em chaves de mapa. Você pode usar a codificação e a decodificação percentual para armazenar uma chave de mapa que contenha um desses caracteres não permitidos.
// Percent encode . or $ characters to use them in map keys let mapKey = "New York.Brooklyn" let encodedMapKey = "New York%2EBrooklyn"
Criar um objeto com uma propriedade MutableSet
Você pode criar objetos que contenham propriedades MutableSet como faria com qualquer objeto Realm, mas só é possível alterar um MutableSet em uma transação de gravação. Isso significa que você só pode definir o(s) valor(es) de uma propriedade de conjunto mutável em uma transação de gravação.
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)")
Criar um objeto com uma propriedade AnyRealmValue
Ao criar um objeto com uma propriedade AnyRealmValue, você deve especificar o tipo do valor armazenado na propriedade. O SDK do Realm Swift fornece uma enumeração AnyRealmValue que itera por todos os tipos que o AnyRealmValue pode armazenar.
Mais tarde, quando você ler um AnyRealmValue, você deve verificar o tipo antes de fazer qualquer coisa com o 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)
Criar um Objeto de Forma Assíncrona
Você pode usar os recursos de simultaneidade do Swift para escrever de forma assíncrona em um realm isolado por atores.
Esta função do exemplo RealmActor
definido na página Usar Realm com Atores mostra como você pode escrever em um realm isolado do ator:
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 ]) } }
E você pode fazer essa escrita usando a sintaxe assíncrona do 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 operação não bloqueia nem executa E/S no thread de chamada. Para obter mais informações sobre como gravar no Realm usando os recursos de simultaneidade do Swift, consulte Use o Realm com atores — Swift SDK.
Criar um objeto assimétrico
Novidades na versão 10,29,0.
Somente é possível criar um AsymmetricObject usando create(_ type:, value:). Quando se cria um AsymmetricObject, ele faz a sincronização de forma unidirecional via ingestão de dados com o banco de dados do Atlas vinculado ao seu App Atlas App Services. Não é possível acessar um AsymmetricObject de forma local, adicioná-lo ou removê-lo de um domínio ou fazer uma consulta por ele.
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 ]) } }
Você pode criar objetos assimétricos para um domínio inicializado com uma configuração de Flexible Sync. Para mais informações, consulte: Abrir um Realm sincronizado para Flexible Sync.
Copiar um Objeto para Outro Realm
Para copiar um objeto de um Realm para outro, passe o objeto original para +[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 um objeto de um domínio para outro, passe o objeto original para 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
Os métodos create
não suportam o tratamento de gráficos de objetos cíclicos. Não passe um objeto que contenha relações que envolvam objetos que remetam a seus pais, direta ou indiretamente.