Swift3 - 在核心数据中插入关系

时间:2017-06-03 17:55:01

标签: core-data swift3

我有两个实体,即

  1. 诊所
  2. 他们之间的关系是多对多的。一个诊所有很多科室,一个科室有很多诊所。

    我在coredata.xcdatamodeld中设置了实体并生成了NSManagedObject个类。 PFA图表

    enter image description here

    我有以下代码,负责插入部门和诊所

    import Foundation
    import CoreData
    import SwiftyJSON
    import Kingfisher
    
    class InstallManager {
    
        let moc = NetworkManager.managedObjectContext
        let data: JSON!
    
        init(withData data: JSON) {
            self.data = data
        }
    
        // Install Department
        private func installDepartment() {
            for(_,jsonData):(String, JSON) in self.data["deparment"]["list"] {
                let department = NSEntityDescription.insertNewObject(forEntityName: "Department", into: moc)
                department.setValue(jsonData["id"].int32, forKey: "id")
                department.setValue(jsonData["name"].string, forKey: "name")
                department.setValue(jsonData["icon"].string, forKey: "icon")
                department.setValue(jsonData["slug"].string, forKey: "slug")
                department.setValue(jsonData["revision"].int32, forKey: "revision")
                do {
                    try moc.save()
                } catch {
                    fatalError("\(error)")
                }
            }
        }
    
        // Install Clinic
        private func installClinic() {
            let departmentList = fetchDepartmentList()
            for (_,jsonData):(String, JSON) in self.data["clinic"]["list"] {
                let coverPictureAbsolute = "\(jsonData["cover_picture"].string!)"
                let coverPictureRelative = (coverPictureAbsolute as NSString).lastPathComponent
                let clinic = NSEntityDescription.insertNewObject(forEntityName: "Clinic", into: moc)
                clinic.setValue(jsonData["id"].int32, forKey: "id")
                clinic.setValue(jsonData["name"].string, forKey: "name")
                clinic.setValue(jsonData["slogan"].string, forKey: "slogan")
                clinic.setValue(jsonData["profile"].string, forKey: "profile")
                clinic.setValue(jsonData["address"].string, forKey: "address")
                clinic.setValue(jsonData["telephone"].string, forKey: "telephone")
                clinic.setValue(jsonData["email"].string, forKey: "email")
                clinic.setValue(jsonData["website"].string, forKey: "website")
                clinic.setValue(coverPictureRelative, forKey: "cover_picture")
                clinic.setValue(jsonData["latitude"].string, forKey: "latitude")
                clinic.setValue(jsonData["longitude"].string, forKey: "longitude")
                clinic.setValue(jsonData["slug"].string, forKey: "slug")
                clinic.setValue(jsonData["revision"].int32, forKey: "revision")
    
                let clinicEntity = clinic.value(forKeyPath: "departments") as! Clinic
                for department in departmentList {
                    clinicEntity.addToDepartments(department)
                    print(department.name!)
                }
    
                do {
                    try moc.save()
                } catch {
                    fatalError("\(error)")
                }
            }
        }
    
        private func fetchDepartmentList() -> [Department] {
            var departmentList:[Department]!
            let request: NSFetchRequest<Department> = Department.fetchRequest()
            do {
                departmentList = try moc.fetch(request)
            } catch {
                fatalError("Cannot fetch clinics list \(error)")
            }
            return departmentList
        }
    
        public func install() {
            self.installDepartment()
            self.installClinic()
        }
    }
    

    我的问题是在临床和部门之间插入关系时,我有一个部门ID列表,我想与诊所建立关系。正如您在上面的代码中看到的,我尝试了以下代码

    let departmentList = fetchDepartmentList()
    let clinicEntity = clinic.value(forKeyPath: "departments") as! Clinic
    for department in departmentList {
        clinicEntity.addToDepartments(department)
        print(department.name!)
    }
    

    但是线路诊所实施了以下错误

    Could not cast value of type '_NSFaultingMutableSet' to 'APP.Clinic'
    

    这是什么问题?我该如何设置关系?

    更新

    以下是核心数据(NSManagedObject SubClass)

    中自动生成的类
    // filename: Clinic.swift
    import Foundation
    import CoreData
    
    @objc(Clinic)
    public class Clinic: NSManagedObject {
    
    }
    
    // filename: Clinic+CoreDataProperties
    import Foundation
    import CoreData
    
    extension Clinic {
    
        @nonobjc public class func fetchRequest() -> NSFetchRequest<Clinic> {
            return NSFetchRequest<Clinic>(entityName: "Clinic");
        }
    
        @NSManaged public var address: String?
        @NSManaged public var cover_picture: String?
        @NSManaged public var email: String?
        @NSManaged public var id: Int32
        @NSManaged public var latitude: NSDecimalNumber?
        @NSManaged public var longitude: NSDecimalNumber?
        @NSManaged public var name: String?
        @NSManaged public var profile: String?
        @NSManaged public var revision: Int32
        @NSManaged public var slogan: String?
        @NSManaged public var slug: String?
        @NSManaged public var telephone: String?
        @NSManaged public var website: String?
        @NSManaged public var departments: NSSet?
    
    }
    
    // MARK: Generated accessors for departments
    extension Clinic {
    
        @objc(addDepartmentsObject:)
        @NSManaged public func addToDepartments(_ value: Department)
    
        @objc(removeDepartmentsObject:)
        @NSManaged public func removeFromDepartments(_ value: Department)
    
        @objc(addDepartments:)
        @NSManaged public func addToDepartments(_ values: NSSet)
    
        @objc(removeDepartments:)
        @NSManaged public func removeFromDepartments(_ values: NSSet)
    
    }
    

1 个答案:

答案 0 :(得分:1)

对于to-many关系,您需要获取mutableSetValueForKey,因为类型为NSSet而不是Clinic

let clinicEntity = clinic.mutableSetValue(forKey: "departments")
for department in departmentList {
    clinicEntity.add(department)
    print(department.name!)
}

或更简单

let clinicEntity = clinic.mutableSetValue(forKey: "departments")
clinicEntity.addObjects(from: departmentList)

要使用自动生成的方法,您可以替换

let clinicEntity = clinic.value(forKeyPath: "departments") as! Clinic
   for department in departmentList {
   clinicEntity.addToDepartments(department)
      print(department.name!)
   }

clinic.addToDepartments(NSSet(array: departmentList))

PS:我建议使用更方便的点表示法,例如

department.id = jsonData["id"].int32
department.name = jsonData["name"].string
department.icon = jsonData["icon"].string
department.slug = jsonData["slug"].string
department.revision = jsonData["revision"].int32