What am I missing in regards to ImportableUniqueObjects, to avoid it inserting a new row every time? #163

Closed
opened 2025-12-29 15:26:00 +01:00 by adam · 5 comments
Owner

Originally created by @JakeSteam on GitHub (Sep 5, 2017).

So, I have a pretty simple database, with 5-6 tables that need to sync with remote JSON data. They all use id (Int64) as a primary key.

As the later versions of CoreStore permit using the .xcdatamodeld directly, I opted for that method to avoid duplicating schemas. As such, I'm extending my model classes to obey the ImportableUniqueObject protocol. Inserting, querying etc all works fine, the only issue is with update vs insert.

I'm very much a novice Swift developer, so there's likely something very obvious I'm missing. Perhaps extensions can't be utilised in this manner?

Expected behaviour: If a row already exists for that id, the values for that row are updated. If not, a new row is inserted.
Observed behaviour: A new row is always inserted, regardless of whether the id is in use already.

extension Website: ImportableUniqueObject {
    public typealias ImportSource = [String: Any]
    public typealias UniqueIDType = Int64
    public class var uniqueIDKeyPath: String {
        return #keyPath(Website.id)
    }
    public var uniqueIDValue: Int64 {
        get { return self.id }
        set { self.id = newValue }
    }
    public class func uniqueID(from source: ImportSource, in transaction: BaseDataTransaction) throws -> Int64? {
        return Int64(source["id"] as! String)
    }
    public func update(from source: ImportSource, in transaction: BaseDataTransaction) throws {
        print("Saving website with ID \(source["id"] as! String)")
        self.id = Int64(source["id"] as! String)!
        self.name = source["name"] as? String
        self.hex = source["hex"] as? String
        self.last_updated = getDate(source["updated"] as! String)
    }
}

This is called via transaction.importObjects(Into<Website>(), sourceArray: jsonArray), where jsonArray is a JSON array containing something similar to https://pastebin.com/4707LPKk

Originally created by @JakeSteam on GitHub (Sep 5, 2017). So, I have a pretty simple database, with 5-6 tables that need to sync with remote JSON data. They all use `id` (Int64) as a primary key. As the later versions of CoreStore permit using the `.xcdatamodeld` directly, I opted for that method to avoid duplicating schemas. As such, I'm extending my model classes to obey the `ImportableUniqueObject` protocol. Inserting, querying etc all works fine, the only issue is with update vs insert. I'm very much a novice Swift developer, so there's likely something very obvious I'm missing. Perhaps extensions can't be utilised in this manner? **Expected behaviour**: If a row already exists for that `id`, the values for that row are updated. If not, a new row is inserted. **Observed behaviour**: A new row is always inserted, regardless of whether the `id` is in use already. ``` extension Website: ImportableUniqueObject { public typealias ImportSource = [String: Any] public typealias UniqueIDType = Int64 public class var uniqueIDKeyPath: String { return #keyPath(Website.id) } public var uniqueIDValue: Int64 { get { return self.id } set { self.id = newValue } } public class func uniqueID(from source: ImportSource, in transaction: BaseDataTransaction) throws -> Int64? { return Int64(source["id"] as! String) } public func update(from source: ImportSource, in transaction: BaseDataTransaction) throws { print("Saving website with ID \(source["id"] as! String)") self.id = Int64(source["id"] as! String)! self.name = source["name"] as? String self.hex = source["hex"] as? String self.last_updated = getDate(source["updated"] as! String) } } ``` This is called via `transaction.importObjects(Into<Website>(), sourceArray: jsonArray)`, where `jsonArray` is a JSON array containing something similar to https://pastebin.com/4707LPKk
adam closed this issue 2025-12-29 15:26:00 +01:00
Author
Owner

@JohnEstropia commented on GitHub (Sep 5, 2017):

Hi, can you show your import code?

@JohnEstropia commented on GitHub (Sep 5, 2017): Hi, can you show your import code?
Author
Owner

@JakeSteam commented on GitHub (Sep 5, 2017):

Replied before I could even edit post to include it!

Just calling transaction.importObjects(Into<Website>(), sourceArray: jsonArray), where jsonArray is a JSON array containing something similar to https://pastebin.com/4707LPKk

@JakeSteam commented on GitHub (Sep 5, 2017): Replied before I could even edit post to include it! Just calling `transaction.importObjects(Into<Website>(), sourceArray: jsonArray)`, where `jsonArray` is a JSON array containing something similar to https://pastebin.com/4707LPKk
Author
Owner

@JohnEstropia commented on GitHub (Sep 5, 2017):

Ah, try to use importUniqueObjects() instead

@JohnEstropia commented on GitHub (Sep 5, 2017): Ah, try to use `importUniqueObjects()` instead
Author
Owner

@JakeSteam commented on GitHub (Sep 5, 2017):

Perfect! Knew it would be something super simple. Might want to update the documentation to mention it, thanks so much for your extremely swift help!

@JakeSteam commented on GitHub (Sep 5, 2017): Perfect! Knew it would be something super simple. Might want to update the documentation to mention it, thanks so much for your extremely swift help!
Author
Owner

@JohnEstropia commented on GitHub (Sep 5, 2017):

Thanks, will mention in the docs (and maybe dump a runtime warning)

@JohnEstropia commented on GitHub (Sep 5, 2017): Thanks, will mention in the docs (and maybe dump a runtime warning)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/CoreStore#163