The examples on this page use the following models:
@interface DogToy : RLMObject@property NSString *name;@end@interface Dog : RLMObject@property NSString *name;@property int age;@property NSString *color;@property DogToy *favoriteToy;@endRLM_COLLECTION_TYPE(Dog)@interface Person : RLMObject@property int _id;@property NSString *name;@property RLMArray<Dog *><Dog> *dogs;@property (readonly) RLMLinkingObjects *clubs;@endRLM_COLLECTION_TYPE(Person)@interface DogClub : RLMObject@property NSString *name;@property RLMArray<Person *><Person> *members;@end@implementation Dog@end@implementation DogToy@end@implementation Person+ (NSString *)primaryKey { return @"_id";}+ (NSDictionary *)linkingObjectsProperties { return @{ @"clubs": [RLMPropertyDescriptor descriptorWithClass:DogClub.class propertyName:@"members"], };}@end@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 @Persisted var favoriteToy: DogToy? @Persisted var favoriteParksByCity: Map<String, String>}class Person: Object { @Persisted(primaryKey: true) var id = 0 @Persisted var name = "" @Persisted var dogs: List<Dog> @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?}
To add an object to a realm, instantiate it as you would any other object and then pass it to -[RLMRealm addObject:] inside of a write transaction.
RLMRealm *realm = [RLMRealm defaultRealm];Dog *dog = [[Dog alloc] init];dog.name = @"Max";dog.age = 5;[realm transactionWithBlock:^() { [realm addObject:dog];}];
To add an object to a realm, instantiate it as you would any other object and then pass it to Realm.add(_:update:) inside of a write transaction.
let dog = Dog()dog.name = "Rex"dog.age = 10let realm = try! Realm()try! realm.write { realm.add(dog)}
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.
NoteWhen using an array as an initializer value, you must include all properties in the same order as they are defined in the model.
Dog *myDog = [[Dog alloc] initWithValue:@{@"name" : @"Pluto", @"age" : @3}];Dog *myOtherDog = [[Dog alloc] initWithValue:@[@"Pluto", @3]];RLMRealm *realm = [RLMRealm defaultRealm];[realm transactionWithBlock:^() { [realm addObject:myDog]; [realm addObject:myOtherDog];}];
let myDog = Dog(value: ["name": "Pluto", "age": 3])let myOtherDog = Dog(value: ["Fido", 5])let realm = try! Realm()try! realm.write { realm.add([myDog, myOtherDog])}
You can even initialize related or embedded objects by nesting initializer values:
Person *aPerson = [[Person alloc] initWithValue:@[@123, @"Jane", @[aDog, anotherDog]]];Person *anotherPerson = [[Person alloc] initWithValue:@[@123, @"Jane", @[@[@"Buster", @5], @[@"Buddy", @6]]]];
let aPerson = Person(value: [123, "Jane", [aDog, anotherDog]])let anotherPerson = Person(value: [123, "Jane", [["Buster", 5], ["Buddy", 6]]])
Some property types are only mutable in a write transaction. For example, you can instantiate an object with a MutableSet 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.
Realm 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:).
NSData *data = [@"{\"name\": \"Tennis ball\"}" dataUsingEncoding: NSUTF8StringEncoding];RLMRealm *realm = [RLMRealm defaultRealm];[realm transactionWithBlock:^{ id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL]; [DogToy createInRealm:realm withValue:json];}];
let data = "{\"name\": \"Tennis ball\"}".data(using: .utf8)!let realm = try! Realm()try! realm.write { let json = try! JSONSerialization.jsonObject(with: data, options: []) realm.create(DogToy.self, value: json)}
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 schema 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.
Realm ignores any properties in the JSON not defined in the object schema.
TipIf your JSON schema doesn't exactly align with your Realm objects, consider using a third-party framework to transform your JSON. There are many model mapping frameworks that work with Realm. See a partial list in the realm-swift repository.
To create an embedded object, assign an instance of the embedded object to a parent object's property:
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"]; contact.address = address; [realm addObject:contact]; NSLog(@"Added contact: %@", contact);}];
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)}
When you create an object that has a map property, you can set the values for keys in a few ways:
Set keys and values on the object and then add the object to the realm
Set the object's keys and values directly inside a write transaction
Use key-value coding to set or update keys and values inside a write transaction
let realm = try! Realm()let dog = Dog()dog.name = "Wolfie"dog.currentCity = "New York"dog.favoriteParksByCity["New York"] = "Domino Park"try! realm.write { realm.add(dog) dog.favoriteParksByCity["Chicago"] = "Wiggly Field" dog.favoriteParksByCity.setValue("Bush Park", forKey: "Ottawa")}
Realm disallows the use of .
or $
characters in map keys. You can use percent encoding and decoding to store a map key that contains one of these disallowed characters.
// Percent encode . or $ characters to use them in map keyslet mapKey = "New York.Brooklyn"let encodedMapKey = "New York%2EBrooklyn"
You can create objects that contain MutableSet properties as you would any Realm object, but you can only mutate a MutableSet within a write transaction. This means you can only set the value(s) of a mutable set property within a write transaction.
let realm = try! Realm()let dog = Dog()dog.name = "Maui"dog.currentCity = "New York"try! realm.write { realm.add(dog) dog.citiesVisited.insert(dog.currentCity)}try! realm.write { dog.citiesVisited.insert(objectsIn: ["Boston", "Chicago"])}print("\(dog.name) has visited: \(dog.citiesVisited)")
When you create an object with an AnyRealmValue property, you must specify the type of the value you store in the property. The Realm Swift SDK provides an AnyRealmValue enum that iterates through all of the types the AnyRealmValue can store.
Later, when you read an AnyRealmValue, you must check the type before you do anything with the value.
let myDog = Dog()myDog.name = "Rex"myDog.companion = .nonelet theirDog = Dog()theirDog.name = "Wolfie"theirDog.companion = .string("Fluffy the Cat")let anotherDog = Dog()anotherDog.name = "Fido"anotherDog.companion = .object(Dog(value: ["name": "Spot"]))let realm = try! Realm()try! realm.write { realm.add([myDog, theirDog, anotherDog])}let dogs = realm.objects(Dog.self)XCTAssertEqual(dogs.count, 4)
You can use Swift concurrency features to write asynchronously to an actor-isolated realm.
This function from the example RealmActor
defined on the Use Realm with Actors page shows how you might write to an actor-isolated realm:
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 { 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 realm using Swift concurrency features, refer to Use Realm with Actors - Swift SDK.
New in version 10.29.0.
You can only create an AsymmetricObject using create(_ type:, value:). When you create an AsymmetricObject, it syncs unidirectionally via Data Ingest to the Atlas database linked to your Atlas App Services App. You cannot access an AsymmetricObject locally, add it to or remove it from a realm, or query for it.
@MainActorfunc 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 ]) }}
You can create AsymmetricObjects for a realm initialized with a Flexible Sync configuration. For more information, see: Open a Synced Realm for Flexible Sync.
To copy an object from one realm to another, pass the original object to +[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];}];Dog *wolfie = [[Dog objectsInRealm:realm where:@"name == 'Wolfie'"] firstObject];RLMRealmConfiguration *otherConfiguration = [RLMRealmConfiguration defaultConfiguration];otherConfiguration.inMemoryIdentifier = @"second realm";RLMRealm *otherRealm = [RLMRealm realmWithConfiguration:otherConfiguration error:nil];[otherRealm transactionWithBlock:^{ Dog *wolfieCopy = [[wolfie class] createInRealm:otherRealm withValue:wolfie]; wolfieCopy.age = 2; XCTAssertNotEqual(wolfie.age, wolfieCopy.age);}];
To copy an object from one realm to another, pass the original object to 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)}let wolfie = realm.objects(Dog.self).first(where: { $0.name == "Wolfie" })!let otherRealm = try! Realm(configuration: Realm.Configuration(inMemoryIdentifier: "second realm"))try! otherRealm.write { let wolfieCopy = otherRealm.create(type(of: wolfie), value: wolfie) wolfieCopy.age = 2 XCTAssertNotEqual(wolfie.age, wolfieCopy.age)}
Important
The create
methods do not support handling cyclical object graphs. Do not pass in an object containing relationships involving objects that refer back to their parents, either directly or indirectly.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4