Can I have a structure with the same name as a Core Data object type? If so, how do I differentiate between the two in code?
Edit: For example, I have a Track
core data object, and when I read in "track" information externally, it comes in via json. Instead of using the core data object, since its a managed object, I'm using another structure. I was planning on naming this Track
as well, however this may result in conflicts which I'm not sure about, so at present I've called it TrackStruct
instead. Also, is this the right approach?
Thanks!
Well I've made a sample project for you after going through a lot of difficulties. But I'm posting the main concept here.
You can have the sample project here. Though I've loaded data from a local
.plist
file. You can check out theloadPersonWithJSON(fromPath:)
function's job. Just follow my code commenting.
Suppose I've a Person Entity in my Core-Data
with two String
property name
and location
. From the json I'm getting array which is of type [[String:Any]]
. Now I want to map my json data to the core data object model.
enum CoreDataError: String, Error {
case NoEntity = "ERROR: No Entity, Check the Entity Name"
}
enum JSONError: String, Error {
case NoData = "ERROR: no data"
case ConversionFailed = "ERROR: conversion from JSON failed"
}
typealias personJSONObjectType = [[String:String]]
class PersonTableViewController: UITableViewController {
var person: [Person] = []
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.loadPersonWithJSON(fromPath: "your json URL in String format")
}
func loadPersonWithJSON(fromPath jsonURLString:String) {
guard let jsonURL = URL(string: jsonURLString) else {
print("Error creating an URL from \(jsonURLString)")
return
}
URLSession.shared.dataTask(with: jsonURL) { (data, response, error) in
do {
guard let data = data else {
throw JSONError.NoData
}
guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? personJSONObjectType else {
throw JSONError.ConversionFailed
}
// Here you have your json data. Now map this data to your model object.
// First you need to have your shared App Delegate
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
print("No shared AppDelegate")
return
}
// Use shared App Delegate to have the persistent containers view context as managed object context. This will be used to verify whether your Entity exists or not
let managedObjectContext = appDelegate.persistentContainer.viewContext
// Get the Entity in your core data model
guard let entity = NSEntityDescription.entity(forEntityName: "Person", in: managedObjectContext) else {
throw CoreDataError.NoEntity
}
let persons = json.map({ (personInfo) -> Person in
let personName = personInfo["name"] as? String // use appropriate key for "name"
let personLocation = personInfo["location"] as? String // use appropriate key for "location"
// Get your object as Core data Managed object.
let aPerson = NSManagedObject(entity: entity, insertInto: managedObjectContext) as! Person
// Manipulate core data object with json data
aPerson.name = personName
aPerson.location = personLocation
// Manipulation done
return aPerson
})
self.person = persons
self.tableView.reloadData()
} catch let error as JSONError {
print(error.rawValue)
} catch let error as CoreDataError {
print(error.rawValue)
} catch let error as NSError {
print(error.debugDescription)
}
}.resume()
}
}
You can use the following table view data source method to check if that works:
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.person.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let aPerson = self.person[indexPath.row]
cell.textLabel?.text = aPerson.name
cell.detailTextLabel?.text = aPerson.location
return cell
}
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