Decoding for NSBatchInsertRequest

I'm building a macOS application to interact via a web API with a server another company runs. I have no existing users, so I can target an arbitrary version of macOS (currently 10.15; I'm running 10.15.4). This server provides thousands of objects as JSON. Sounds like a perfect match for JSONSerialization and NSBatchInsertRequest, as discussed in the WWDC 2019 session Making Apps with Core Data.


The problem I have is most of the JSON keys have dashes in them, and Core Data does not allow dashes in attribute names. Thus, those attributes don't make it into my Core Data objects. Before trying to move to Core Data, I was using structs with a CodingKeys enum combined with JSONDecoder to pull the data in as Swift objects.


An example of the structs I have been using:


struct objectMetadata: Codable {
  let lock:String
  let lastModifyTime:Date
  let lastModifier:String
  let creationTime:Date
  let creator:String

  enum CodingKeys : String, CodingKey {
  case lock
  case lastModifyTime = "last-modify-time"
  case lastModifier = "last-modifier"
  case creationTime = "creation-time"
  case creator
  }
}


I assume I have to do something similar here. How would I control the exact way a JSON blob is converted to an instance of an entity?

Replies

Right now the Attribute names must match the names in JSON to use batch insert request. You can use regular inserts and batch them though.

That's a shame.


So it sounds like my best bet at this point is to

  1. Set my Core Data entities to manual/none and create the subclass files
  2. Combine the class and extension (as 'init' doesn't seem to like being in extensions, and Xcode won't let a method in the class refer to the attributes in the extension)
  3. Add a CodingKeys enum and 'required convenience public init(from decoder:)' method
  4. Use JSONDecoder to decode the JSON to an array of entities
  5. Issue a context.save() after each array is decoded


Alternatively, I could make some kind of translation layer for the JSON to spot dashes in keys and replace the dash and the next letter with the letter uppercased. Could even be reversible, as long as the server's schema doesn't allow uppercase letters in keys (this one doesn't).


Both options sound interesting, and like good things to learn.