How To Use RealmEmbeddedObject

YongJunCha·2021년 11월 2일
0

Realm

목록 보기
2/4
post-thumbnail
import RealmSwift
import Then

 open class KeywordEngine: Object, ObjectKeyIdentifiable {
    
     @Persisted(primaryKey: true) public var keywordType: Int = 0 // 키워드 타입
     @Persisted public var name: String = "" // 검색엔진명
     @Persisted public var priority: Int = 0 //순번
     @Persisted public var keywords: List<Keyword> // 키워드 목록
     @Persisted public var isConnected: Bool = false // 연결 여부
     @Persisted public var isAuthenticated: Bool = false // 인증 여부
     @Persisted public var timestamp: Date = Date() // 등록 및 수정 날짜
    
     
     convenience init(keywordType: Int, name: String, priority: Int, keywords: [Keyword], isConnected: Bool, isAuthenticated: Bool, timestamp: Date) {
         self.init()
         self.keywordType = keywordType
         self.name = name
         self.priority = priority
         self.keywords.append(objectsIn: keywords)
         self.isConnected = isConnected
         self.isAuthenticated = isAuthenticated
     }
    
}

예전에는 @objc dynamic var 로 설정했다면 업데이트 되면서는
@Persisted로도 선언이 가능하다.

open class Keyword: EmbeddedObject {
    
    @Persisted public var id: CLong = 0// 키 ( 인덱스 )
    @Persisted public var keywordType: Int = 0 // 키워드 타입
    @Persisted public var mainType: Int = 0 // 메인 종류 ( 유튜브[1:유튜브, 2:유튜브뮤직] / 구글[null] )
    @Persisted public var subType: Int = 0 // 검색어 종류 ( 0:기타, 1:검색, 2:시청, 3:방문, 4:조회 )
    @Persisted public var name: String = "" // 검색어
    @Persisted public var dateTime: Date = Date() // 주문 날짜
    @Persisted public var image: String = "" // 썸네일 이미지 URL
    @Persisted public var timestamp: Date = Date() // 등록 및 수정 날짜
    
}

객체는 위의 두개의 코드 예시대로 설정하면 된다.

   public func getLastDate(keywordType: Int) -> Date {
        var lastDate : Date = getCustomedZeroDate()
        let keywordLastDate = realm.objects(KeywordEngine.self).filter("ANY keywords.keywordType = %@", keywordType).first?.keywords.sorted(byKeyPath: "dateTime", ascending: false).first?.dateTime ?? getCustomedZeroDate()
        
        lastDate = keywordLastDate
        return lastDate
        }
    }

임베디드 오브젝트의 최대 단점은 쿼리가 길어지고
부모의 PK에 따라 데이터가 하나하나 종속되기 때문에
모든 종속 데이터를 한번에 가져와야 하는 경우 손이 많이 간다.

  • 안드로이드는 위의 선언한 Keyword 객체에 직접 접근해서 읽기는 되나,
    쓰기와 업데이트는 해도 반영이 안 된다고 한다.
   public func insertFormattedKeyword(keywords: [Keyword], promise: @escaping(Result<Bool,Error>) -> Void) {
        
        realm.executeTransactionAsync {
            do {
                guard let keywordEngine = realm.object(ofType: KeywordEngine.self, forPrimaryKey: keywordType) else {
                    print("Contact \(keywordType) not found")
                    return
                }
                try realm.write() {
                    print("KEYWORD COUNT DAO :: \(keywords.count)")
                    keywordEngine.keywords.append(objectsIn: keywords)
                }
                promise(.success(true))
            } catch let error {
                print("\(error)")
                promise(.failure(error))
            }
        }
        
    }

위의 코드는 읽기 코드이다.
하나의 트랜잭션에서 부모뷰를 먼저 불러준 후 임베디드 데이터인
'keywords'에 접근해서 write를 하면 된다.

임베디드를 사용하게 될 경우 반드시 고려해야하는 것이
물리적으로 종속이 되야하는지, 반드시 임베디드가 아니면 안 되는지
고려해봐야할 것 같다. 읽거나 쿼리하는 부분이 복잡해지기 때문이다.

개발을 하면서 임베디드 오브젝트는 접근이 너무 힘들다고 했는데,
접근자체는 어렵지 않았으나 자료와 사례가 너무 없었고,
StackOverFlow에는 많은 사람들이 .compactMap과 .filter로 데이터를
정제해서 썼다.

0개의 댓글