Swift3 - 在核心数据中插入关系
Posted
技术标签:
【中文标题】Swift3 - 在核心数据中插入关系【英文标题】:Swift3 - Insert Relation In Core Data 【发布时间】:2017-06-03 17:55:00 【问题描述】:我有两个实体,即
-
诊所
部门
它们之间的关系是多对多的。即一个诊所有很多科室,一个科室有很多相关联的诊所。
我已经在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)
【问题讨论】:
【参考方案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 的一个实例,我该如何让它工作?你能帮我举个例子吗?以上是关于Swift3 - 在核心数据中插入关系的主要内容,如果未能解决你的问题,请参考以下文章