在应用启动时,我正在将数据加载到两个Core Data实体中。加载普通属性没问题,但是我不知道如何在Swift 5中设置关系。
在两个相关实体中,CellData与Selector具有单一的“一对一”关系(每个Selector行可以具有许多CellData行)。
我的单个模型类加载了两个实体的数据...
class LoadData
{
init ()
{
使用for循环,该循环首先为选择器定义选择器实体数据...
for count in 0...3
{
var text = "Value not found"
...
switch count
{
case 0:
text = "Masculine"
case 1:
text = "Neutral"
case 2:
text = "Feminine"
case 3:
text = "Plural"
default:
text = "Value unassigned"
}
...,然后调用以下方法将数据添加到实体“选择器”。
loadSelector(text: text, sortOrder: sortOrder, ...)
}
...在同一init中,还有第二个for循环来定义CellData
for count in 0...51
{
var text = "Cell text not found"
var sortOrder: Int32 = 0
...
sortOrder = Int32(count)
...
switch count
{
case 0:
text = "Blank"
color1 = subject
colorRangeLoc1 = 0
colorRangeLen1 = Int32(text.count)
...
case 8:
text = "Der Mann"
color1 = article
...
case 9:
text = "Die Frau"
color1 = article
color2 = subject
colorRangeLoc1 = 0
colorRangeLoc2 = 4
colorRangeLen1 = 3
colorRangeLen2 = 4
underlineRangeLoc1 = 1
underlineRangeLen1 = 2
...
...还将每个循环中的数据传递到加载方法中。
loadCellData(text: text, ...)
}
}
func loadSelector(text: String, sortOrder: Int32, color1: String?, color2: String?, color3: String?, colorRangeLoc1: Int32?, colorRangeLen1: Int32?, colorRangeLoc2: Int32?, colorRangeLen2: Int32?, colorRangeLoc3: Int32?, colorRangeLen3: Int32?)
{
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let entry: Selector = NSEntityDescription.insertNewObject(forEntityName: "Selector", into: context) as! Selector
entry.text = text
entry.sortOrder = sortOrder
do { try context.save() }
catch let error as NSError
{ print("Could not save. \(error), \(error.userInfo)") }
}
这可能不是最好的方法,但是我正在努力通过plist加载数据。
我不知道的是如何在CellData中创建关系。例如,情况8需要与Selector数据相关联,其中.text ='Masculine',而案例9的CellData应该与Selector条目.text ='Feminine'相关。
我是否应该在第二个for循环之前或之内重新获取Selector条目,然后在每种情况下分配?我已经尝试过了,但是没有成功-如果可能的话,请显示代码以及代码的位置。大多数信息似乎都在Obj-c中。 Swift 5太棒了!
答案 0 :(得分:0)
与普通对象一样对待它们,Core Data为您处理了很多魔术。
我会创建一个方法,该方法创建所有选择器,并将它们作为字典返回,名称作为键(或其他适合您的其他集合)
func createSelectors(text: String) -> [String: Select] {
var result = [String: Selector]()
//loop creating Selector
result[text: entity]
return result
}
您甚至可以跳过loadSelector方法,并以
的形式进行实际实例化let entity = Selector(context: context)
可以在createSelectors方法和try context.save()
中的最后完成操作,而不是对每个对象都完成。请注意,添加这样创建的对象会将其放入NSManagedObjectContext中,这现在足以使用这些对象,实际上可以在加载结束时进行一次保存。
现在,在创建CellData时,您可以做类似的事情
let selectors = createSelectors()
...
let cellData = CellData(context: context)
if let sel = selectors {
cellData.selectorToData = sel
}
....
创建所有CellData实体后,您可以调用try context.save()
context
是您通过这种方式获得的托管对象,`let context = appDelegate.persistentContainer.viewContext,但您可能已经知道了。
“选择器”在Swift中是一个特殊的名称,因为它是内置的结构,因此我会认真考虑更改此实体的名称。
答案 1 :(得分:0)
我发现定义与现有记录的关系的唯一方法是从CoreData单独获取记录。
来自Hacking Swift Project 38,其中“ commit”是实例化的CoreData实体,与Author实体有关系:
var commitAuthor: Author! // instantiate an Author object
let authorRequest = Author.createFetchRequest() // create a fetch request...
authorRequest.predicate = NSPredicate(format: "name == %@", json["commit"]["committer"]["name"].stringValue) // predicating the author's name...
let authors = container.viewContext.fetch(authorRequest)
commitAuthor = authors[0] } // pull the author out of the array
// and assign the author to the commit.author relationship
commit.author = commitAuthor
尽管问题更多是关于分配关系,但以下内容(基于Joachim的回答)是一种更好的方式,以可见的方式加载数据,并可以将其传输到plist或JSON上传。基本上,要遍历字典数组:
let genders: NSArray = [["text": "Masculine", "sortOrder" : Int32(0)], ["text": "Neutral", "sortOrder" : Int32(1)], ["text": "Feminine", "sortOrder" : Int32(2)], ["text": "Plural", "sortOrder" : Int32(3)]]
// loading a gender entity in context with a dictionary of items from array
for eachDicItem in genders
{
let gender = NSEntityDescription.entity(forEntityName: "Gender",
in: context)!
let genderInContext = Gender(entity: gender,
insertInto: context)
let genderDictionary = eachDicItem as! [String : Any]
genderInContext.text = genderDictionary["text"] as? String
genderInContext.sortOrder = genderDictionary["sortOrder"] as? Int32 ?? 99
}
// save the context
do { try context.save() }
catch let error as NSError
{ print("Could not save. \(error), \(error.userInfo)") }