EEYatHo 앱 깎는 이야기

Swift ) Realm List Migration - EEYatHo iOS 본문

iOS, Swift

Swift ) Realm List Migration - EEYatHo iOS

EEYatHo 2021. 11. 14. 20:41
반응형

일반적인 값들의 마이그레이션 방법

 

Realm 클래스를 마이그레이션 할 때, oldObject의 값에 접근하기 위해서는,

아래처럼 oldObject의 string 키값으로 접근하는 것이 일반적일텐데,

해당 방법으로는 List 값에는 접근이 안된다. 

 

( firstName과 lastName을 더해서 fullName이라는 값을 추가하는. List가 필요없는 케이스는 잘 됨. )

migrationBlock: { migration, oldSchemaVersion in
    if oldSchemaVersion < 1 {
        migration.enumerateObjects(ofType: Person.className()) { oldObject, newObject in
			
            guard let oldObject = oldObject else { return }
            if let firstName = oldObject?["firstName"] as? String,
               let lastName = oldObject?["lastName"] as? String {
               
                newObject!["fullName"] = firstName + lastName
               
            }
        }
    }
}
import RealmSwift

// new Person
class Person: Object {
    @objc dynamic var firstName: String = ""
    @objc dynamic var lastName: String = ""
    @objc dynamic var fullName: String = ""
}

// old Person
// class Person: Object {
//     @objc dynamic var firstName: String = ""
//     @objc dynamic var lastName: String = ""
// }

 

마이그레이션할 때, List에 접근하는 방법 

 

Realm의 Object에서 지원하는, dynamicList 함수를 사용하여야 한다.

 

( phoneNumberList에서, 첫번째 값을 mainPhoneNumber로 추가하는 케이스 )

migrationBlock: { migration, oldSchemaVersion in
    if oldSchemaVersion < 1 {
        migration.enumerateObjects(ofType: Person.className()) { oldObject, newObject in
			
            guard let oldObject = oldObject else { return }
            
            let phoneNumberDynamicObjectList = oldObject.dynamicList("phoneNumberList")
            
            let phoneNumberStringList = List<String>()
            phoneNumberStringList.append(objectsIn: phoneNumberDynamicObjectList.map{
                return $0.description
            })
            
            newObject!["mainPhoneNumber"] = phoneNumberStringList.first ?? ""
            
        }
    }
}
import RealmSwift

// new Person
class Person: Object {
    @objc dynamic var mainPhoneNumber: String = ""
    
    let phoneNumberList: List<String> = List<String>()
    
    var phoneNumberArray: [String] {
        get {
            return phoneNumberList.map {$0}
        }
        set {
            phoneNumberList.removeAll()
            phoneNumberList.append(objectsIn: newValue)
        }
    }
}

// old Person
// class Person: Object {
//    let phoneNumberList: List<String> = List<String>()
//    
//    var phoneNumberArray: [String] {
//        get {
//            return phoneNumberList.map {$0}
//        }
//        set {
//            phoneNumberList.removeAll()
//            phoneNumberList.append(objectsIn: newValue)
//        }
//    }
// }

 

추가로,

dynamicList의 결과값은 List<DynamicObject> 인데, DynamicObject 값이

 

RealmObject라면, $0["key"]

String이라면, $0.description

Int라면, Int($0.description)

Data라면, Data(unsafeBitCast($0, to: DispatchData.self))

 

등으로 접근이 가능하다.

 

Comments