Search code examples
swiftgenericsrealm

Instantiating Realm objects using Generics in Swift


I am working in a iOS project involving Realm and the use of Generics. I am exploring ways to clone a retrieved Realm object to update it outside a write transaction and then send it to an update function using generics.

I am facing a weird problem and i don't know if it is related to Realm or to the Generics stuff. You help will be appreciated

Setting: One class GenericObject that inherits from Realm Object, and a subclass called Sale:

GenericObject: Object 

Sale: Generic Object  // This class includes a primary key called "id"

I fetch a Sale object from the web and I am able to save it in Realm, creating a new object outside the write transaction (I could save it without worrying about the write transaction, but I want to use the same code and flow for any update)

When I modify a property of the object and try to update Realm, it throws an exception because the primary key can't be found. (The primaryKey is defined in the subclass Sale)

I have been able to pinpoint the problem to my newItem() method in Sale as follows:

override func newItem<T:GenericObject>(ofType itemType: T.Type) -> T {
    let dictionary = self.getDictionary()
    let newItem = T.init()
    newItem.updateWithDictionary(dict: dictionary)
    print("Type: \(type(of: newItem)) - Object: \(newItem)")
    return newItem
}

And then, I call it as follows:

let newObject = object.newItem(ofType: Sale.self)
self.realm.add(newObject, update: true)

So far, so good. I retrieve the object from the web and it works. The print() reports that type(of:) the instantiate object is Sale, and the printout of the object also says Sale

Type: Sale - Object: Sale { .... 

When I update the object and save it, it fails saying that Realm could not find the primary key, type(of:) reports Sale, but the instance is printed as the GenericObject superclass, as follows:

Type: Sale - Object: GenericObject { .... 

This result is running the same code and the same code execution. I am using Xcode 10 and Swift 4.2, with Realm 3 Any idea what may be happening here?


Solution

  • After 6 months, the problem seems to be fixed without a clear indication of what was going on.

    As of 2019-04-22, having migrated to Realm 3.14.1, Xcode 10.2.1 and Swift 5.0, I am able to get a clone of the object using T.init(), and saving it successfully outside the Realm write transaction with the original code used when I posted the question

    I don't see anything related to a syntax change from Swift 4.2 to 5.0, but I understand that Xcode 10.2.1 includes updates to LLVM/clang.

    I'd love to spend some time checking the new compiler with the previous Realm version