【问题标题】:Swift3 - Insert Relation In Core DataSwift3 - 在核心数据中插入关系
【发布时间】:2017-06-03 17:55:00
【问题描述】:

我有两个实体,即

  1. 诊所
  2. 部门

它们之间的关系是多对多的。即一个诊所有很多科室,一个科室有很多相关联的诊所。

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

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

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

但是 ClinicEntity 行向我抛出以下错误

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

这里有什么问题?如何设置关系?

更新:

这是从核心数据(NSManagedObject 子类)自动生成的类

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

}

【问题讨论】:

    标签: core-data swift3


    【解决方案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
    

    【讨论】:

    • 这行得通,谢谢。我想知道核心数据(NSManagedObject)生成的类中可用的方法@NSManaged public func addToDepartments(_ value: Department)有什么用处
    • 我没有注意到这些方法是自动生成的。完美,用它们代替mutableSetValueForKey
    • 就是这样,我不能。它抛出了错误,我已经用它自动生成的两个类更新了我的问题。
    • PS:既然你使用NSManagedObject子类,为什么不写clinic.name = jsonData["name"].string而不是clinic.setValue(jsonData["name"].string, forKey: "name")
    • 如果我能做到,那就太棒了,但是因为诊所是 NSEntityDescription 的一个实例,我该如何让它工作?你能帮我举个例子吗?
    猜你喜欢
    • 2014-01-02
    • 1970-01-01
    • 2013-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多