I'm struggling to get my CoreData objects into JSON so that I can use it to send to a web server.
This is how I currently fetch my objects from CoreData:
func fetchRecord() -> [Record] {
do {
records = try context.fetch(Record.fetchRequest())
} catch {
print("Error fetching data from CoreData")
}
return records
}
I am able to display this on to my tableView this way:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "recordCell", for: indexPath) as! RecordCell
cell.nameLbl.text = records[indexPath.row].name
cell.quantityLbl.text = "Quantity: \(String(records[indexPath.row].quantity))"
cell.dateLbl.text = dateString(date: records[indexPath.row].date)
return cell
}
I have attempted to loop inside my request like this:
for rec in records {
print(rec)
}
that gives out this:
I have read a lot about ways to achieve this but none of them seem to really be of beneficial to me. Most of the examples out there shows how to get JSON to CoreData and not the other way. Does anyone know any good tutorials or documentation that can help me achieve this?
In Swift 4+ you can take advantage of the Encodable
protocol and add the functionality directly to your Core Data object.
Assuming your NSManagedObject
subclass extension looks like
extension Record {
@NSManaged public var date: Date
@NSManaged public var name: String
@NSManaged public var quantity: Int32
@NSManaged public var synched: Bool
@NSManaged public var uuid: String
...
Adopt Encodable
extension Record : Encodable {
and add
private enum CodingKeys: String, CodingKey { case date, name, quantity, synched, uuid }
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(date, forKey: .date)
try container.encode(name, forKey: .name)
try container.encode(quantity, forKey: .quantity)
try container.encode(synched, forKey: .synched)
try container.encode(uuid, forKey: .uuid)
}
Then you can easily encode the records to JSON
do {
records = try context.fetch(Record.fetchRequest())
let jsonData = try JSONEncoder().encode(records)
} catch {
print("Error fetching data from CoreData", error)
}
Here the code as an extension. Based on KavyaKavita's answer.
extension NSManagedObject {
func toJSON() -> String? {
let keys = Array(self.entity.attributesByName.keys)
let dict = self.dictionaryWithValues(forKeys: keys)
do {
let jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
let reqJSONStr = String(data: jsonData, encoding: .utf8)
return reqJSONStr
}
catch{}
return nil
}
}
Usage:
let jsonString = YourCoreDataObject.toJSON()
print(jsonString)
You can convert your NSManageObject subclass object into dictionary by using following code
let record = recArray[index]
let keys = Array(record.entity.attributesByName.keys)
let dict = record.dictionaryWithValues(forKeys: keys)
After that you can use jsonserialization to convert that dictionary into json object
do{
let jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
let reqJSONStr = String(data: jsonData, encoding: .utf8)
print(reqJSONStr!)
}catch{
}
Hope this will help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With