结构,与Core Data对象类型同名?

时间:2017-07-14 01:36:10

标签: swift

我可以拥有与Core Data对象类型同名的结构吗?如果是这样,我如何区分代码中的两个?

编辑:例如,我有一个Track核心数据对象,当我从外部读取“track”信息时,它通过json进入。而不是使用核心数据对象,因为它是一个托管对象,我正在使用另一种结构。我也计划命名这个Track,但这可能会导致我不确定的冲突,所以目前我称之为TrackStruct。另外,这是正确的方法吗?

谢谢!

2 个答案:

答案 0 :(得分:1)

在遇到很多困难之后,我已经为你做了一个示例项目。但我在这里发布了主要概念。

  

您可以拥有示例项目here。虽然我已从本地.plist文件加载数据。您可以查看loadPersonWithJSON(fromPath:)功能的工作。只需按照我的代码评论即可。

假设我的Core-Data中有一个实体,其中有两个String属性namelocation。从json我得到类型为[[String:Any]]的数组。现在我想将我的json数据映射到核心数据对象模型。

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()
    }
}

附加资源

您可以使用下表查看数据源方法来检查是否有效:

// 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
}

答案 1 :(得分:1)

您有一个很好的方法,将CoreData与业务模型分开。只有这个命名问题。所以,我将分享我的经验,是CoreData实体的前缀是Managed,商业模式就像它们一样导致你的情况: ManagedTrack< - > Track