1 Reply
      Latest reply on Nov 6, 2019 5:46 PM by nocsi
      _hs_ Level 1 Level 1 (0 points)

        Hi,

        I am trying to load JSON into Coredata. Something similar to what was presented WWDC 2019.

        There are discrepencies on slide 49 and 51. The Type returned by JSON decoder on 49 is [[String: Any]] and is different than 59 [String: Any]

        Moreover, the code does not seem to work?

         

        Did anyone get it to work? Is it possible to provide example?

         

         

         

        let rawPostsData = // ...
        if let postDicts = try? JSONSerialization.jsonObject(with:rawPostsData) as? [String : Any] {

        moc.perform {
        let insertRequest = NSBatchInsertRequest(entity: Post.entity(), objects: postDicts) let insertResult = try? moc.execute(insertRequest) as! NSBatchInsertRequest
        let success = insertResult.result as! Bool

        } }

         

        • Re: Json Batch insertion: Corrected sample from WWDC19 needed
          nocsi Level 1 Level 1 (0 points)

          Give something like this a try:

           

           

          func syncLocations() {
                  var batchCreate: [[String: Any]] = []
                  for location in remoteLocations {
                      if let objectID = locationDataSource.performFetchObjectID(Location.requestLocationStruct(location)) {
                          let updateObj = locationDataSource.updateContext.object(with: objectID) as! Location
                          let (latitude, longitude) = invalidCoordinates(updateObj.provider, updateObj.slug)
                          updateObj.latitude = latitude
                          updateObj.longitude = longitude
                          locationDataSource.saveUpdateObject()
                      } else {
                          let (latitude, longitude) = invalidCoordinates(location.provider, location.slug!)
                          batchCreate.append(
                              [
                                  "uniqueID": UUID().uuidString,
                                  "title": location.title,
                                  "name": location.name ?? "",
                                  "slug": location.slug ?? "",
                                  "subtitle": location.subtitle ?? "",
                                  "locale": location.locale ?? "",
                                  "provider": location.provider,
                                  "latitude": latitude,
                                  "longitude": longitude
                              ])
                          }
                  }
                  let request = NSBatchInsertRequest(entityName: Location.entityName, objects: batchCreate)
                  locationDataSource.performBatchInsert(request, "location")
              }
          
          ...
          
              func performBatchInsert(_ request: NSBatchInsertRequest, _ author: String = appTransactionAuthorName) {
                  do {
                      createContext.transactionAuthor = author
                      try createContext.executeAndMergeChanges(using: request)
                  } catch {
                      print(error)
                  }
              }
          
          extension NSManagedObjectContext {
              public func executeAndMergeChanges(using batchInsertRequest: NSBatchInsertRequest) throws {
                  batchInsertRequest.resultType = .objectIDs
                  let result = try execute(batchInsertRequest) as! NSBatchInsertResult
                  let changes: [AnyHashable: Any] = [NSInsertedObjectsKey: result.result as? [NSManagedObjectID] ?? []]
                  NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [self])
              }
          }
          
          

          The batch insert request basically wants an array of objects that are themselves an array of property key-values. As such, you'll need to make sure the JSON decodes to [[String: Any]]