문서 메뉴
문서 홈
/ /
Atlas Device SDK
/ /

Realm 객체 모델 정의 - Swift SDK

이 페이지의 내용

  • 새 객체 유형 정의
  • 속성 선언
  • 지속형 속성 특성
  • 오브젝티브-C 동적 속성 특성
  • 선택/필수 속성 지정
  • 프라이머리 키 설정
  • 속성 인덱싱
  • 속성 무시
  • 열거형 속성 선언
  • 속성 이름 매핑
  • 클래스 프로젝션 정의
  • 이 예제들에 대하여
  • 클래스 프로젝션을 정의하는 방법
  • 비대칭 객체 정의
  • 비정형 데이터 정의

RLMObject 또는 RLMEmbeddedObject 클래스에서 파생하여 Realm 객체를 정의할 수 있습니다. 클래스 이름은 Realm의 테이블 이름이 되며 클래스의 속성은 데이터베이스에 유지됩니다. 이렇게 하면 일반 Objective-C 객체를 사용하는 것처럼 지속형 객체로 작업하는 것이 쉬워집니다.

// A dog has an _id primary key, a string name, an optional
// string breed, and a date of birth.
@interface Dog : RLMObject
@property RLMObjectId *_id;
@property NSString *name;
@property NSString *breed;
@property NSDate *dateOfBirth;
@end
@implementation Dog
+ (NSString *)primaryKey {
return @"_id";
}
+ (NSArray<NSString *> *)requiredProperties {
return @[
@"_id", @"name", @"dateOfBirth"
];
}
@end

Realm 객체는 Object 또는 EmbeddedObject 클래스에서 파생하여 정의할 수 있습니다. 클래스 이름은 Realm의 테이블 이름이 되며 클래스의 속성은 데이터베이스에 유지됩니다. 이렇게 하면 일반 Swift 객체를 사용하는 것처럼 지속형 객체를 사용하는 것이 쉬워집니다.

// A dog has an _id primary key, a string name, an optional
// string breed, and a date of birth.
class Dog: Object {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var name = ""
@Persisted var breed: String?
@Persisted var dateOfBirth = Date()
}

참고

클래스 이름은 최대 57자의 UTF-8 문자로 제한됩니다.

클래스 속성의 특성을 선언할 때 해당 속성을 Realm이 관리해야 하는지 여부를 지정할 수 있습니다. 관리되는 속성은 데이터베이스에 저장되거나 업데이트됩니다. 무시된 속성은 데이터베이스에 저장되지 않습니다. 클래스 내에서 괸리되는 속성과 무시되는 속성을 혼합할 수 있습니다.

속성을 관리됨 또는 무시됨으로 표시하는 구문은 사용하는 SDK 버전에 따라 다릅니다.

버전 10 에 추가되었습니다.10.0: @Persisted 선언 스타일은 이전 SDK 버전의 @objc dynamic, RealmOptionalRealmProperty 선언 표기법을 대체합니다. 이전 버전의 SDK에 대해서는 오브젝티브-C 동적 속성 특성(Objective-C Dynamic Property Attributes)을 참조하세요.

데이터베이스에 저장하려는 모델 속성을 @Persisted(으)로 선언합니다. 이를 통해 기본 데이터베이스 데이터에 액세스할 수 있습니다.

클래스 내에서 속성을 @Persisted(으)로 선언하면 해당 클래스 내의 다른 속성은 자동으로 무시됩니다.

클래스 정의 내에 @Persisted@objc dynamic 속성 지정을 혼합하면 @objc dynamic(으)로 표시된 모든 속성 특성이 무시됩니다.

다음도 참조하세요.

지원되는 속성 유형 페이지에는 속성 지정 치트 시트가 포함되어 있습니다.

버전 10.10.0의 변경된 기능: 이 속성 지정 정보는 10.10.0 이전 SDK 버전에 대한 것입니다.

오브젝티브-C 런타임에서 동적 Realm 모델 속성을 선언합니다. 이를 통해 기본 데이터베이스 데이터에 액세스할 수 있습니다.

둘 중 하나를 수행하면 됩니다.

  • 개별 속성을 선언하려면 @objc dynamic var을(를) 사용합니다.

  • 클래스를 선언하려면 @objcMembers을(를) 사용합니다. 그런 다음 dynamic var(으)로 개별 속성을 선언합니다.

let을(를) 사용하여 LinkingObjects, List, RealmOptionalRealmProperty을(를) 선언합니다. 오브젝티브-C 런타임은 이러한 일반 속성을 나타낼 수 없습니다.

버전 10.8.0의 변경된 기능: RealmProperty이(가) RealmOptional을(를) 대체합니다.

다음도 참조하세요.

지원되는 속성 유형 페이지에는 속성 지정 치트 시트가 포함되어 있습니다.

Realm이 속성으로 사용하기 위해 지원하는 유형에 대한 참고는 지원되는 속성 유형을 참조하세요.

일반적이지 않은 속성을 선언할 때는 @Persisted 어노테이션을 사용합니다. @Persisted 속성은 Realm 모델 속성을 기본 데이터베이스 데이터에 대한 접근자로 바꿉니다.

일반 오브젝티브-C 인터페이스에서처럼 객체 유형에 대한 속성을 선언합니다.

Realm 배열에서 인터페이스를 사용하려면 인터페이스 이름을 RLM_COLLECTION_TYPE() 매크로에 전달하세요. 인터페이스의 헤더 파일 하단에 넣을 수 있습니다. RLM_COLLECTION_TYPE() 매크로는 유형으로 RLMArray 에 태그를 지정할 수 있는 프로토콜을 생성합니다.

// Task.h
@interface Task : RLMObject
@property NSString *description;
@end
// Define an RLMArray<Task> type
RLM_COLLECTION_TYPE(Task)
// User.h
// #include "Task.h"
@interface User : RLMObject
@property NSString *name;
// Use RLMArray<Task> to have a list of tasks
// Note the required double tag (<Task *><Task>)
@property RLMArray<Task *><Task> *tasks;
@end

@objc dynamic var 일반이 @objc dynamic var 아닌 속성을 @objcMembers 4 선언할 때는 주석을 사용하세요. 속성은 Realm 모델 속성을 기본 데이터베이스 데이터에 대한 접근자로 바꿉니다. 클래스가 (Swift 이상)로 선언된 경우 없이 속성을 로 선언할 수 dynamic var @objc있습니다.

일반 유형 LinkingObjects, ListRealmProperty 의 속성을 선언하려면 let 을 사용합니다. 일반 속성은 Realm이 동적 속성의 동적 디스패치에 사용하는 오브젝티브-C 런타임에서 표현될 수 없습니다.

참고

속성 이름은 최대 63자의 UTF-8 문자로 제한됩니다.

표준 Swift 구문을 사용하여 속성을 선택 사항 또는 필수 사항(비선택 사항)으로 선언할 수 있습니다.

class Person: Object {
// Required string property
@Persisted var name = ""
// Optional string property
@Persisted var address: String?
// Required numeric property
@Persisted var ageYears = 0
// Optional numeric property
@Persisted var heightCm: Float?
}

지정된 속성을 필수로 선언하려면 requiredProperties 메서드를 구현하고 필수 속성 이름의 배열을 반환합니다.

@interface Person : RLMObject
// Required property - included in `requiredProperties`
// return value array
@property NSString *name;
// Optional string property - not included in `requiredProperties`
@property NSString *address;
// Required numeric property
@property int ageYears;
// Optional numeric properties use NSNumber tagged
// with RLMInt, RLMFloat, etc.
@property NSNumber<RLMFloat> *heightCm;
@end
@implementation Person
// Specify required pointer-type properties here.
// Implicitly required properties (such as properties
// of primitive types) do not need to be named here.
+ (NSArray<NSString *> *)requiredProperties {
return @[@"name"];
}
@end

버전 10.8.0의 변경된 기능: RealmProperty이(가) RealmOptional을(를) 대체합니다.

표준 Swift 구문을 사용하여 String, Date, DataObjectId 속성을 선택 사항 또는 필수(선택 사항이 아님)로 선언할 수 있습니다. RealmProperty 유형을 사용하여 선택적 숫자 유형을 선언합니다.

class Person: Object {
// Required string property
@objc dynamic var name = ""
// Optional string property
@objc dynamic var address: String?
// Required numeric property
@objc dynamic var ageYears = 0
// Optional numeric property
let heightCm = RealmProperty<Float?>()
}

RealmProperty는 Int, Float, Double, BoolInt 의 모든 크기 버전(Int8, Int16, Int32, Int64)을 지원합니다.

속성을 클래스의 프라이머리 키로 지정할 수 있습니다.

프라이머리 키를 사용하면 객체를 효율적으로 찾고, 업데이트하고, 업서트할 수 있습니다.

프라이머리 키에는 다음과 같은 제한 사항이 적용됩니다.

  • 객체 모델당 프라이머리 키는 하나만 정의할 수 있습니다.

  • 프라이머리 키 값은 Realm에 있는 객체의 모든 인스턴스에서 고유해야 합니다. 중복된 프라이머리 키 값을 삽입하려고 하면 Realm에서 오류가 발생합니다.

  • 프라이머리 키 값은 변경되지 않습니다. 객체의 프라이머리 키 값을 변경하려면 원본 객체를 삭제하고 프라이머리 키 값이 다른 새 객체를 삽입해야 합니다.

  • 포함된 객체는 프라이머리 키를 정의할 수 없습니다.

@Persisted 표기법에서 primaryKey: true 로 속성을 선언하여 모델의 프라이머리 키를 설정합니다.

class Project: Object {
@Persisted(primaryKey: true) var id = 0
@Persisted var name = ""
}

모델의 프라이머리 키를 설정하려면 +[RLMObject 프라이머리 키] 를 재정의합니다.

@interface Project : RLMObject
@property NSInteger id; // Intended primary key
@property NSString *name;
@end
@implementation Project
// Return the name of the primary key property
+ (NSString *)primaryKey {
return @"id";
}
@end

Object.primaryKey() 를 재정의하여 모델의 기본 키를 설정합니다.

class Project: Object {
@objc dynamic var id = 0
@objc dynamic var name = ""
// Return the name of the primary key property
override static func primaryKey() -> String? {
return "id"
}
}

모델의 특정 속성에 대한 인덱스를 만들 수 있습니다. 인덱스는 등호 및 IN 연산자를 사용하여 쿼리 속도를 높입니다. 삽입 및 업데이트 작업 속도는 약간 느려집니다. 인덱스는 메모리를 사용하고 Realm 파일에서 더 많은 공간을 차지합니다. 각 인덱스 항목은 최소 12 바이트입니다. 특정 상황에 대한 읽기 성능을 최적화하는 경우에만 인덱스를 추가하는 것이 가장 좋습니다.

Realm은 문자열, 정수, 부울, Date, UUID, ObjectIdAnyRealmValue 속성에 대한 인덱싱을 지원합니다.

버전 10.8.0의 새로운 기능: UUIDAnyRealmValue 유형

속성을 인덱싱하려면 @Persisted 표기법에서 indexed:true 를 사용하여 속성을 선언합니다.

class Book: Object {
@Persisted var priceCents = 0
@Persisted(indexed: true) var title = ""
}

속성을 인덱싱하려면 +[RLMObject indexedProperties] 를 재정의하고 인덱싱된 속성 이름 목록을 반환합니다.

@interface Book : RLMObject
@property int priceCents;
@property NSString *title;
@end
@implementation Book
// Return a list of indexed property names
+ (NSArray *)indexedProperties {
return @[@"title"];
}
@end

속성을 인덱싱하려면 Object.indexedProperties() 를 재정의하고 인덱싱된 속성 이름 목록을 반환합니다.

class Book: Object {
@objc dynamic var priceCents = 0
@objc dynamic var title = ""
// Return a list of indexed property names
override static func indexedProperties() -> [String] {
return ["title"]
}
}

무시된 속성은 일반 속성과 똑같이 작동합니다. 쿼리에 사용할 수 없으며 알림을 trigger Realm 하지 않습니다. KVO를사용하여 계속 관찰할 수 있습니다.

Realm은 읽기 전용 속성을 자동으로 무시합니다.

버전 10 이후 더 이상 사용되지 않습니다.10.0: ignoredProperties()

모델의 필드를 해당 Realm에 저장하지 않으려면 속성 특성(property attribute)에서 @Persisted 표기법을 그대로 둡니다.

또한 클래스 내에서 @Persisted 속성 선언과 @objc dynamic 속성 선언을 혼합하면 @objc dynamic 속성이 무시됩니다.

class Person: Object {
// If some properties are marked as @Persisted,
// any properties that do not have the @Persisted
// annotation are automatically ignored.
var tmpId = 0
// The @Persisted properties are managed
@Persisted var firstName = ""
@Persisted var lastName = ""
// Read-only properties are automatically ignored
var name: String {
return "\(firstName) \(lastName)"
}
// If you mix the pre-10.10 property declaration
// syntax `@objc dynamic` with the 10.10+ @Persisted
// annotation within a class, `@objc dynamic`
// properties are ignored.
@objc dynamic var email = ""
}

모델의 필드를 해당 Realm에 저장하지 않으려면 +[RLMObject ignoreProperties] 를 재정의하고 무시된 속성 이름 목록을 반환합니다.

@interface Person : RLMObject
@property NSInteger tmpId;
@property (readonly) NSString *name; // read-only properties are automatically ignored
@property NSString *firstName;
@property NSString *lastName;
@end
@implementation Person
+ (NSArray *)ignoredProperties {
return @[@"tmpId"];
}
- (NSString *)name {
return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
}
@end

모델의 필드를 해당 Realm에 저장하지 않으려면 Object.ignoredProperties() 를 재정의하고 무시된 속성 이름 목록을 반환합니다.

class Person: Object {
@objc dynamic var tmpId = 0
@objc dynamic var firstName = ""
@objc dynamic var lastName = ""
// Read-only properties are automatically ignored
var name: String {
return "\(firstName) \(lastName)"
}
// Return a list of ignored property names
override static func ignoredProperties() -> [String] {
return ["tmpId"]
}
}

버전 10.10.0에서 변경됨: 프로토콜은 RealmEnum이 아닌 PersistableEnum입니다.

@Persisted 와 함께 열거형을 사용하려면 열거형을 PersistableEnum 프로토콜을 준수하는 것으로 표시합니다. PersistableEnum 는 원시 유형이 Realm이 지원하는 유형인 RawRepresentable 열거형일 수 있습니다.

// Define the enum
enum TaskStatusEnum: String, PersistableEnum {
case notStarted
case inProgress
case complete
}
// To use the enum:
class Task: Object {
@Persisted var name: String = ""
@Persisted var owner: String?
// Required enum property
@Persisted var status = TaskStatusEnum.notStarted
// Optional enum property
@Persisted var optionalTaskStatusEnumProperty: TaskStatusEnum?
}

Realm은 Int지원 @objc 열거형만 지원합니다.

// Define the enum
@objc enum TaskStatusEnum: Int, RealmEnum {
case notStarted = 1
case inProgress = 2
case complete = 3
}
// To use the enum:
class Task: Object {
@objc dynamic var name: String = ""
@objc dynamic var owner: String?
// Required enum property
@objc dynamic var status = TaskStatusEnum.notStarted
// Optional enum property
let optionalTaskStatusEnumProperty = RealmProperty<TaskStatusEnum?>()
}

다음도 참조하세요.

버전 10.33.0의 새로운 기능

객체 모델에 있는 속성의 퍼블릭 이름을 다른 프라이빗 이름에 매핑하여 Realm에 저장할 수 있습니다. 예를 들어 프로젝트에서 Swift 관용적 카멜 표기법을 사용하고 Device Sync 스키마 속성 이름에 스네이트 표기법을 사용하는 경우 이 작업을 수행할 수 있습니다.

프로젝트에서 사용하려는 이름을 객체 모델의 @Persisted 속성으로 선언합니다. 그런 다음 propertiesMapping() 함수를 통해 속성 이름에 대한 퍼블릭 및 프라이빗 값을 포함하는 사전을 전달합니다.

이 예제에서 firstName은(는) CRUD 작업을 수행하기 위해 프로젝트 전체의 코드에서 사용하는 퍼블릭 속성 이름입니다. propertiesMapping() 함수를 사용하여 Realm에 프라이빗 속성 이름 first_name을(를) 사용하여 값을 저장하도록 매핑합니다. 동기화된 Realm에 작성하는 경우 Sync 스키마는 프라이빗 속성 이름 first_name을(를) 사용하여 저장된 값을 확인합니다.

class Person: Object {
@Persisted var firstName = ""
@Persisted var lastName = ""
override class public func propertiesMapping() -> [String: String] {
["firstName": "first_name",
"lastName": "last_name"]
}
}

이 섹션의 예제에서는 간단한 데이터 세트를 사용합니다. Realm 객체의 두 가지 유형은 Person 및 포함된 객체 Address입니다. Person에는 이름과 성, 선택적 Address 및 기타 Person 객체로 구성된 친구 목록이 있습니다. Address에는 도시와 국가가 있습니다.

아래에서 이 두 클래스의 스키마 PersonAddress를 참조하세요.

class Person: Object {
@Persisted var firstName = ""
@Persisted var lastName = ""
@Persisted var address: Address?
@Persisted var friends = List<Person>()
}
class Address: EmbeddedObject {
@Persisted var city: String = ""
@Persisted var country = ""
}

버전 10.21.0의 새로운 기능

프로젝션 유형의 클래스를 생성하여 클래스 프로젝션을 정의합니다. 클래스 프로젝션에서 사용할 속성이 있는 객체 또는 포함된 객체 베이스를 지정합니다. @Projected 속성 래퍼를 사용하여 기본 객체의 @Persisted 속성에서 프로젝션하려는 속성을 선언합니다.

참고

클래스 프로젝션에서 List 또는 MutableSet 를 사용하는 경우 클래스 프로젝션의 유형은 ProjectedCollection이어야 합니다.

class PersonProjection: Projection<Person> {
@Projected(\Person.firstName) var firstName // Passthrough from original object
@Projected(\Person.address?.city) var homeCity // Rename and access embedded object property through keypath
@Projected(\Person.friends.projectTo.firstName) var firstFriendsName: ProjectedCollection<String> // Collection mapping
}

클래스 프로젝션을 정의할 때 다음과 같은 여러 가지 방법으로 원본 @Persisted 속성을 변환할 수 있습니다.

  • 패스스루: 속성이 원본 객체와 이름 및 유형이 동일합니다.

  • 이름 바꾸기: 속성의 유형은 원본 객체와 동일하지만 이름은 다릅니다.

  • 키 경로 확인: 키 경로 확인을 사용하여 포함된 객체 속성을 포함한 원본 객체의 속성에 액세스합니다.

  • 컬렉션 매핑: 프로젝트 목록, Object변경 가능한 세트 또는 EmbeddedObject을(를) 프라이머리 값 컬렉션으로 표시합니다.

  • 제외: 클래스 프로젝션을 사용할 때 클래스 프로젝션을 통해 @Projected 이외의 기본 객체의 속성은 제외됩니다. 이렇게 하면 클래스 프로젝션의 변경 사항을 관찰할 수 있으며 클래스 프로젝션에 포함되지 않은 속성의 변경 사항은 볼 수 없습니다.

버전 10.29.0의 새로운 기능

앱에서 Flexible Sync를 사용하는 경우 데이터 수집 을 사용하여 기기에서 Atlas App Services 앱에 연결된 데이터베이스에 단방향으로 객체를 동기화할 수 있습니다. AsymmetricObject에서 상속하여 비대칭 객체를 정의합니다 .

class WeatherSensor: AsymmetricObject {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var deviceId: String
@Persisted var temperatureInFahrenheit: Float
@Persisted var barometricPressureInHg: Float
@Persisted var windSpeedInMph: Int
}

버전 10.42.4의 변경된 기능: 비대칭 는 포함된 객체에 연결할 수 있습니다.

AsymmetricObject 몇 가지 예외를 제외하고는 Object(와)과 동일한 속성 유형을 광범위하게 지원합니다.

  • 비대칭 객체는 포함된 객체에만 링크할 수 있습니다.
    • ObjectList<Object> 속성은 Swift SDK 버전 10.42.3 이하에서 지원되지 않습니다. Swift SDK 버전 10.42.4 이상에서는 비대칭 객체가 포함된 객체에 링크할 수 있습니다.

    • EmbeddedObjectList<EmbeddedObject>이(가) 지원됩니다.

Object내에서 AsymmetricObject에 연결할 수 없습니다. 연결 시에는 오류가 발생합니다.

비대칭 객체는 다른 Realm 객체와 같은 방식으로 작동하지 않습니다. 다음을 수행할 수 없습니다.

  • Realm에 비대칭 객체 추가

  • Realm에서 비대칭 객체 제거

  • 비대칭 객체 쿼리

비대칭 객체만 생성할 수 있으며 이 객체는 Device Sync를 통해 앱에 연결된 Atlas 데이터베이스와 단방향으로 동기화됩니다.

자세한 내용은 비대칭 객체 생성하기를 참조하세요.

버전 10 에 추가되었습니다.51.0.

SDK 버전 10 부터 시작됩니다.51.0, AnyRealmValue 속성 내에 혼합 데이터 컬렉션을 저장할 수 있습니다. 이 기능을 사용하면 엄격한 데이터 모델을 정의하지 않고도 JSON 또는 MongoDB 문서와 같은 복잡한 데이터 구조를 모델링할 수 있습니다.

구조화되지 않은 데이터 는 예상 스키마와 쉽게 일치하지 않는 데이터로, 개별 데이터 클래스를 모델링하기가 어렵거나 비실용적입니다. 예를 들어 앱에 매우 가변적인 데이터나 런타임에 구조를 알 수 없는 동적 데이터가 있을 수 있습니다.

혼합 속성에 컬렉션을 저장하면 Device Sync 사용 시 성능 동기화를 포함하여 기능을 저하시키지 않으면서도 유연성을 확보할 수 있습니다. 그리고 혼합되지 않은 컬렉션과 동일한 방식으로 작업할 수 있습니다.

그러나 혼합된 컬렉션에 데이터를 저장하는 것은 구조화된 스키마를 사용하거나 JSON blob을 단일 문자열 속성으로 직렬화하는 것보다 성능이 떨어집니다.

앱에서 구조화되지 않은 데이터를 모델링하려면 스키마에서 적절한 속성을 AnyRealmValue 유형으로 정의합니다. 그런 다음 이러한 AnyRealmValue 속성을 AnyRealmValue 요소의 목록 또는 사전 컬렉션으로 설정할 수 있습니다. AnyRealmValueMutableSet 또는 포함된 객체를 나타낼 수 없습니다 .

  • 유형을 알 수 없지만 각 값에 고유 식별자가 있는 경우 혼합 데이터 유형의 맵을 사용합니다.

  • 유형을 알 수 없지만 객체의 순서가 의미 있는 경우 혼합 데이터 유형 목록을 사용합니다.

돌아가기

모델 데이터

다음

관계