9

I'm attempting to convert my NSManagedObject into a Dictionary so I can use serialize it for JSON.

func fetchRecord() -> [Record] {

        let fetchRequest = NSFetchRequest<Record>(entityName:"Record")
        let context = PersistenceService.context

        fetchRequest.resultType = .dictionaryResultType

        do {
            records = try context.fetch(Record.fetchRequest())

        } catch {
            print("Error fetching data from CoreData")
        }
        print(records)
        return records
 }

I have loked at this question: How to convert NSManagedObject to NSDictionary but their method appears very different to mine. I have also attempted the methods provided in this question: CoreData object to JSON in Swift 3. However I am receiving this error

Could not cast value of type 'NSKnownKeysDictionary1' (0x108fbcaf8) to 'iOSTest01.Record' (0x1081cd690)$

and I can't seem to find the solution.

The error has been mentioned before here: Core Data: Could not cast value of type 'MyType_MyType_2' to MyType but none of the methods are resolving my issue. Could anyone provide me a Swift solution for this?

Update

To help the comment below I have added the following:

var record: Record!
var records = [Record]()

Record+CoreDataClass:

public class Record: NSManagedObject {

}

Record+CoreDataProperties:

extension Record {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Record> {
        return NSFetchRequest<Record>(entityName: "Record")
    }

    @NSManaged public var name: String?

}

This is where records are defined.

Chace
  • 561
  • 10
  • 28
  • Where is `records` defined and how? – With `resultType = .dictionaryResultType` the fetch request returns an array of *dictionaries,* that is incompatible with your return type `[Record]`. – Martin R Sep 20 '17 at 09:17
  • Please see my update on the question. – Chace Sep 20 '17 at 09:24
  • Do you want an array of Record objects or an array of dictionaries? – Martin R Sep 20 '17 at 09:28
  • I believe I need an array of dictionaries in order to serialize them to JSON? I may be wrong. – Chace Sep 20 '17 at 09:29

1 Answers1

19

In order to get an array of dictionaries from the fetch request you must do two things:

  • Set fetchRequest.resultType = .dictionaryResultType (as you already did), and
  • declare the fetch request as NSFetchRequest<NSDictionary> instead of NSFetchRequest<YourEntity>.

Example:

let fetchRequest = NSFetchRequest<NSDictionary>(entityName:"Event")
fetchRequest.resultType = .dictionaryResultType

// Optionally, to get only specific properties:
fetchRequest.propertiesToFetch = [ "prop1", "prop2" ]

do {
    let records = try context.fetch(fetchRequest)
    print(records)
} catch {
    print("Core Data fetch failed:", error.localizedDescription)
}

Now records has the type [NSDictionary] and will contain an array with dictionary representations of the fetched objects.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • 1
    Thank you for this, my data is now printing out as a Dictionary. However it has altered how I display my data now as it is no longer using the `Record` class instead it's using a `NSDictionary`. What is the best approach to get my data to display as before? – Chace Sep 20 '17 at 10:01
  • 1
    @Chace: I would use separate fetch requests. One (with an NSFetchedResultsController) to display the data in a table view, and another one for exporting the data. – Martin R Sep 20 '17 at 11:01
  • Nice explanation. Saved my day, or should I say "evening". Thank you :) – sugarakis Jan 27 '21 at 02:49