CRUD - 만들기 - Swift SDK
이 페이지의 내용
새 객체 만들기
이 페이지의 예시 관련 정보
이 페이지의 예시에서는 다음 모델을 사용합니다.
// 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? }
객체 생성
Realm 에 객체 를 추가하려면 다른 객체 와 마찬가지로 객체를 인스턴스화한 다음 쓰기 트랜잭션( 쓰기 트랜잭션 (write transaction) ) 내에서 -[RLMRealm addObject:] 영역 전달합니다.
// 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]; }];
영역에 객체를 추가하려면 다른 객체와 마찬가지로 객체를 인스턴스화한 다음 쓰기 트랜잭션(write transaction) 내에서 Realm.add(_:update:)로 전달합니다.
// 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) }
값으로 객체 초기화
Object.init(value:) 에 이니셜라이저 값을 전달하여 객체를 초기화할 수 있습니다. 이니셜라이저 값은 키-값 코딩 일 수 있습니다. 호환 객체, 사전 또는 각 관리 속성에 대해 하나의 요소를 포함하는 배열입니다.
참고
배열을 이니셜라이저 값으로 사용할 때는 모델에 정의된 순서와 동일한 순서로 모든 속성을 포함해야 합니다.
// (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]) }
이니셜라이저 값을 중첩하여 관련 또는 내장된 객체를 초기화할 수도 있습니다.
// 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]]])
일부 속성 유형은 쓰기 트랜잭션에서만 변경할 수 있습니다.
일부 속성 유형은 쓰기 트랜잭션(write transaction)에서만 변경할 수 있습니다. 예를 들어 MutableSet 속성을 사용하여 객체를 인스턴스화할 수 있지만 쓰기 트랜잭션(write transaction)에서는 해당 속성의 값만 설정할 수 있습니다. 쓰기 트랜잭션(write transaction) 내에서 초기화하지 않는 한 해당 속성의 값으로 객체를 초기화할 수 없습니다.
JSON으로 객체 생성
Realm 은 JSON 을 직접 지원 하지 않지만 JSONSerialization.jsonObject(with:options:) JSON 을 Realm.create(_:value: 업데이트:)에 전달할 수 있는 값으로 변환합니다.
// 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) }
JSON의 중첩된 객체 또는 배열을 일대일 또는 다대다 관계에 매핑합니다.
JSON 속성 이름과 유형은 대상 객체 스키마와 정확히 일치해야 합니다. 예시:
float
속성은 플롯 지원NSNumbers
(으)로 초기화해야 합니다.Date
및Data
속성은 문자열에서 유추할 수 없습니다. Realm.create(_:value: 업데이트:)에 전달하기 전에 적절한 유형으로 변환합니다.필수 속성은
null
이거나 JSON에 누락될 수 없습니다.
Realm은 객체 스키마에 정의되지 않은 JSON의 모든 속성을 무시합니다.
팁
JSON schema 가 Realm 객체와 정확히 일치하지 않는 경우 타사 프레임워크 를 사용하여 JSON 을 변환하는 것을 고려하세요. Realm 과 함께 작동하는 모델 매핑 프레임워크는 여러 가지가 있습니다. Realm-swift 리포지토리 의 일부 목록을 참조하세요.
내장된 객체 생성
내장된 객체를 생성하려면 내장된 객체의 인스턴스를 상위 객체의 속성에 할당합니다.
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) }
지도 속성을 사용하여 객체 생성
지도 속성 이 있는 객체를 만들 때 다음과 같은 몇 가지 방법으로 키 값을 설정할 수 있습니다.
객체에 키와 값을 설정한 다음 객체를 영역에 추가
쓰기 트랜잭션(write transaction) 내에서 직접 객체의 키와 값 설정
키-값 코딩을 사용하여 쓰기 트랜잭션(write transaction) 내에서 키와 값을 설정 또는 업데이트
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에서는 지도 키에 .
또는 $
문자를 사용할 수 없습니다. 백분율 인코딩 및 디코딩을 사용하여 허용되지 않는 문자 중 하나가 포함된 지도 키를 저장할 수 있습니다.
// Percent encode . or $ characters to use them in map keys let mapKey = "New York.Brooklyn" let encodedMapKey = "New York%2EBrooklyn"
MutableSet 속성으로 객체 생성
다른 Realm 객체와 마찬가지로 MutableSet 속성을 포함하는 객체를 만들 수 있지만 쓰기 트랜잭션(write transaction) 내에서만 MutableSet를 변경할 수 있습니다. 이는 쓰기 트랜잭션(write transaction) 내에서 변경 가능한 설정 속성의 값만 설정할 수 있음을 의미합니다.
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)")
AnyRealmValue 속성으로 객체 생성
AnyRealmValue 속성 을 사용하여 객체 를 만들 때는 속성 에 저장 하는 값의 유형을 지정해야 합니다. Realm Swift SDK 는 AnyRealmValue가 저장 수 있는 모든 유형을 반복하는 AnyRealmValue 열거형 을 제공합니다.
추후 AnyRealmValue를 읽을 때는 값으로 어떤 작업을 수행하기 전에 유형을 확인해야 합니다.
// 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)
비동기적 객체 생성
Swift 동시성 기능을 사용하여 행위자가 격리된 영역에 비동기적으로 기록할 수 있습니다.
행위자와 Realm 사용 페이지에 정의된
RealmActor
예제의 함수는 행위자 격리 영역에 기록할 수 있는 방법을 보여줍니다.
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 ]) } }
그리고 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()
이 작업은 호출 스레드에서 I/O를 차단하거나 수행하지 않습니다. Swift 동시성 기능을 사용하여 Realm에 쓰는 방법에 대해 자세히 알아보려면 Actors와 함께 Realm 사용 - Swift SDK를 참조하세요.
비대칭 객체 생성
버전 10.29.0의 새로운 기능
AsymmetricObject는 create(_ type:, value:) 를 통해서만 만들 수 있습니다. AsymmetricObject를 생성하면 데이터 수집 을 통해 Atlas App Services 앱에 연결된 Atlas 데이터베이스에 단방향으로 동기화됩니다. AsymmetricObject에 로컬로 액세스하거나 Realm에 추가 또는 제거하거나 쿼리할 수 없습니다.
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 ]) } }
Flexible Sync 구성 으로 초기화된 Realm에 대해 영역 를 생성할 수 있습니다. 자세한 내용 은 Flexible Sync를 위해 동기화된 Realm 열기를 참조하세요.
객체를 다른 Realm에 복사
Realm 간에 객체 를 복사하려면 원본 객체 를 +[ 영역 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); }];
한 Realm에서 다른 Realm으로 객체를 복사하려면 원본 객체를 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) }
중요
create
메서드는 주기적 객체 그래프 처리를 지원하지 않습니다. 상위 항목을 직접 또는 간접적으로 참조하는 객체와 관련된 관계가 있는 객체를 전달하지 않도록 합니다.