Reputation: 6795
I have two Realm
model classes
class ModelA: Object {
let id = RealmOptional<Int>()
dynamic var name: String!
// some other variables that are also String! type
}
class ModelB: Object {
let id = RealmOptional<Int>()
let models = List<ModelA>()
// other variables
}
And I have some JSON
object which contains data for that models. I create ModelB
instance then populate it with ModelA
instances list the following way:
let json: JSON = ... // get it from somewhere, then use SwiftyJSON
let myModelB = ModelB()
myModelB.id.value = json["id"].object as? Int
// set other properties
let modelsA = json["models"].map { ModelA(value: $0.1.object) }
myModelB.models.appendContentsOf(modelsA)
The reason why I am using different approaches here is that propery names in JSON
doesn't match to my property names for ModelB
but for ModelA
it is ok.
Somewhere later I use realm.add(objects, update: true)
(inside realm.write
) and that leads to the following exception:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ valueForUndefinedKey:]: this class is not key value coding-compliant for the key (null).'
According to the documentation:
If your model class includes a primary key, you can have Realm intelligently update or add objects based off of their primary key values using Realm().add(_:update:).
so both ModelA
and ModelB
has primaryKey()
function and I believe that should work but it is not.
Furthermore, I removed update
parameter in the call and added call to the realm.deleteAll()
before adding new objects (both in write
callback). In that case I get the following exception:
Terminating app due to uncaught exception 'RLMException', reason: 'Can't set primary key property 'id' to existing value 'xxxxxxx'.
Additionally if I try to go through the call stack, Xcode crashes. It also crashes if I try to inspect any Realm
object in the debugger. I already have installed Realm
Xcode plugin but nothing changes. I cannot understand what is going wrong here and why I get so strange behavior. Could someone tell me where is my mistake please?
Upvotes: 4
Views: 2548
Reputation: 4485
I start project from scratch, base on example project. So I finished with:
import UIKit
import RealmSwift
// Dog model
class Dog: Object {
dynamic var name = ""
dynamic var age = 0
dynamic var owner: Person? // Properties can be optional
override class func primaryKey() -> String? { return "name" }
}
// Person model
class Person: Object {
dynamic var name = ""
let dogs = List<Dog>()
override class func primaryKey() -> String? { return "name" }
}
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
do {
try NSFileManager.defaultManager().removeItemAtPath(Realm.Configuration.defaultConfiguration.path!)
} catch {}
let dogRexJSON: AnyObject = ["name": "Rex", "age" : 20]
let dogLuckyJSON: AnyObject = ["name": "Lucky", "age" : 25]
var somePerson = Person(value: ["name" : "Shurik", "dogs" : [dogRexJSON]])
// Realms are used to group data together
let realm = try! Realm() // Create realm pointing to default file
// Save your object
realm.beginWrite()
realm.add(somePerson)
try! realm.commitWrite()
somePerson = Person(value: ["name" : "Shurik", "dogs" : [dogRexJSON, dogLuckyJSON]])
try! realm.write { () -> Void in
realm.add([somePerson], update: true)
return
}
let val = realm.objectForPrimaryKey(Dog.self, key: "Lucky")
print(val!.name) // as expected log >> Lucky
return true
}
}
Seems all works fine.
Upvotes: 3