A structure with the same name as the Core Data object type?
Can I create a structure with the same name as the Core Data object type? If so, how can I differentiate between these two codes?
Edit: For example, I have a kernel data object Track
and when I read the "track" information from the outside, it comes in via json. Instead of using the main data object as its a managed object, I use a different structure. I had planned to call this as well Track
, however this could lead to conflicts that I am not sure about, so I currently named it TrackStruct
. Also, is this the correct approach?
Thank!
source to share
Okay, I made a sample project for you, going through a lot of difficulties. But I am posting the basic concept here.
You can get a sample project here . Although I downloaded the data from a local file
.plist
. You can check how the function worksloadPersonWithJSON(fromPath:)
. Just follow my code comments.
Suppose I have a Person Entity in mine Core-Data
with two properties String
name
and location
. From json, I am getting an array that is of type [[String:Any]]
. Now I want to map my json data to the main 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()
}
}
Additional resource
You can use the following table data source method to check if this 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
}
source to share
You have a good approach for this to decouple CoreData from business models. There is only this problem with names. So, I'll just share my experience that CoreData objects are prefixed with c Managed
and business models are as they are, which leads to this in your case:
ManagedTrack
â Track
.
source to share