Reputation: 1825
I've added a calculation
property to a realm object and now I'm stuck on setting the value to it inside a migration block because I cannot instantiate an object to pass it to the calculator.
Here is my model:
import Foundation
import RealmSwift
class Loan: Object {
dynamic var id: String = NSUUID().UUIDString
dynamic var creationDate: NSDate = NSDate()
dynamic var title: String = ""
dynamic var amount: Double = 0.0
dynamic var rate: Float = 0.0
dynamic var term: Int = 0
dynamic var type: Int = TYPE_ANNUITY
dynamic var firstPaymentDate: NSDate = NSDate()
dynamic var issueDate: NSDate?
let extras = List<Extra>() // this is a list of nested realm models which is also used for calculation
dynamic var calculation: CalculationResult? // !! added this property !!
static let TYPE_ANNUITY = 0
static let TYPE_GRADED = 1
override class func primaryKey() -> String? {
return LoanPropNames.Id
}
}
struct LoanPropNames {
static let CreationDate = "creationDate"
static let Id = "id"
static let Calculation = "calculation"
}
The value for the calculation
is calculated by a helper method with signature like this:
func calculate(loan: Loan) -> CalculationResult
Here is the code for configuration for the Realm:
class RealmConfigurator {
private static let schemaVersionAddedCalculationProp: UInt64 = 1
private static let schemaVersionLatest = schemaVersionAddedCalculationProp
static func createConfiguration() -> Realm.Configuration {
return Realm.Configuration(
schemaVersion: schemaVersionLatest,
migrationBlock: {
migration, oldSchemaVersion in
if oldSchemaVersion < schemaVersionAddedCalculationProp {
migration.enumerate(Loan.className()) {
oldObject, newObject in
if let oldObject = oldObject,
let newObject = newObject {
// this is how I try to instantiate a loan to pass it to the CalculationHelper
let loan = Loan(value: oldObject, schema: migration.oldSchema)
newObject[LoanPropNames.Calculation] = CalculationHelper.calculate(loan)
}
}
}
}
)
}
}
The problem is in the line
let loan = Loan(value: oldObject, schema: migration.oldSchema)
The compiler says
Cannot convert value of type 'Schema' to expected argument type 'RLMSchema'
If I try to run it like this: let loan = Loan(value: oldObject)
I get runtime error:
Terminating app due to uncaught exception 'RLMException', reason: 'Invalid property name
calculation
for classLoan
.'
Question: How can I instantiate a Loan object during migration in order to fill the calculation
property?
I do not want to make it lazy
because it needs to be recalculated when other properties are changed. Also making it a computed property is not a good solution because it takes a while to compute the value with each access.
Upvotes: 0
Views: 1008
Reputation: 10573
I think that you can use KVC to fill loan object's properties. Like the following:
// 1. Create empty loan object
let loan = Loan()
// 2. Fill loan object's properties with old object
let propertyNames = oldObject.objectSchema.properties.map { $0.name }
let values = oldObject.dictionaryWithValuesForKeys(propertyNames)
loan.setValuesForKeysWithDictionary(values)
// 3. Create standalone calcuration object
let calculation = CalculationHelper.calculate(loan)
// 4. Save calculation object and assign
newObject[LoanPropNames.Calculation] = migration.create(CalculationResult.className(), value: calculation)
Upvotes: 1