我在核心数据中有两个实体。我的月份和我的页面。 每个月都有很多页,所以它们之间是一对多的关系。当我保存、更新、删除时,它工作正常。如果我尝试在循环中保存,它只会保存一次(或者可能会覆盖)。 这里的数据模型:
我从 firebase 获取页面,它获取完美。获取所有页面后,我运行代码将它们保存到 Core Data,如下所示:
func saveBackupPages(firebasePages : [PageModel], savingHandler: @escaping (_ success : Bool) -> Void){
guard let context = appDelegate?.persistentContainer.viewContext else {
print("error")
return
}
for singlePage in firebasePages {
let selectedMonth = MyMonth(context: context)
let selectedPage = MyPage(context: context)
selectedMonth.name = singlePage.date.getFormattedDate(format: "MMyyyy")
selectedMonth.userID = FirebaseAuthService.instance.storedUserId
selectedPage.id = singlePage.id
selectedPage.body = singlePage.body
selectedPage.date = singlePage.date
selectedPage.isFull = singlePage.isFull
selectedPage.isMarked = singlePage.isMarked
selectedPage.pic1URL = singlePage.picURL1
selectedPage.pic2URL = singlePage.picURL2
selectedPage.pic3URL = singlePage.picURL3
selectedPage.version = singlePage.version
selectedMonth.addToPages(selectedPage)
}
do {
try context.save()
savingHandler(true)
print("New page created in core data")
} catch let error {
print(error)
savingHandler(false)
}
}
当我这样做时,它每月只保存一页。例如,如果我尝试将 4 页保存到两个月,每个月 2 页,它每个月只保存 1 页。如果我一个月保存 20 页,它再次只保存一页。所以关系有效,但我认为它会在一个月内覆盖页面。
我也从循环中得到这些行:
let selectedMonth = MyMonth(context: context)
let selectedPage = MyPage(context: context)
没有修好任何东西。我对核心数据关系非常陌生。我应该怎么做才能解决它?
编辑:首先,感谢@Joakim Danielson 的建议。我做到了:
func saveBackupPages(firebasePases : [PageModel], savingHandler: @escaping (_ success : Bool) -> Void){
guard let context = appDelegate?.persistentContainer.viewContext else {
print("error")
return
}
let months = [String: MyMonth]()
for singlePage in firebasePases {
let month = singlePage.date.getFormattedDate(format: "MMyyyy")
let selectedMonth: MyMonth
if let existingMonth = months[month] {
selectedMonth = existingMonth
} else {
selectedMonth = MyMonth(context: context)
selectedMonth.name = month
selectedMonth.userID = FirebaseAuthService.instance.storedUserId
}
let selectedPage = MyPage(context: context)
selectedPage.id = singlePage.id
selectedPage.body = singlePage.body
selectedPage.date = singlePage.date
selectedPage.isFull = singlePage.isFull
selectedPage.isMarked = singlePage.isMarked
selectedPage.pic1URL = singlePage.picURL1
selectedPage.pic2URL = singlePage.picURL2
selectedPage.pic3URL = singlePage.picURL3
selectedPage.version = singlePage.version
selectedMonth.addToPages(selectedPage)
}
do {
try context.save()
savingHandler(true)
print("New page created in core data")
} catch let error {
print(error)
}
}
不幸的是没有奏效,或者我误解了该怎么做。我用了同月的 4 页。我只保存了一页。所以我改变了我的功能。现在对于每个页面和月份,我的函数首先获取结果并确定页面/月份是否存在,如果页面不存在于核心数据中则保存它。它有效,但效率不高。
这里的问题是您正在为每个
MyMonth
对象创建一个新的 singlePage
实例,并向该月添加一个 MyPage
对象。
你需要做的是维护一个本地缓存,这样当它们存在一个月(“MMyyyy”)时,你可以查找和重用现有的
MyMonth
对象。
我们通过创建一个本地字典来保存
MyMonth
对象来做到这一点。
var months = [String: MyMonth]()
然后在
for
循环的顶部,我们提取当前月份并将其用作键来检查我们是否有一个 MyMonth
对象或者我们是否需要创建一个新的对象
for singlePage in firebasePages {
let month = singlePage.date.getFormattedDate(format: "MMyyyy")
let selectedMonth: MyMonth
if let existingMonth = months[month] {
selectedMonth = existingMonth
} else {
selectedMonth = MyMonth(context: context)
selectedMonth.name = month
selectedMonth.userID = FirebaseAuthService.instance.storedUserId
}
// rest of the code in the loop is the same
}
您可以通过在函数中创建一个新对象来稍微清理一下代码
func make(month: String) -> MyMonth {
let newMonth = MyMonth(context: context)
newMonth.name = month
newMonth.userID = FirebaseAuthService.instance.storedUserId
return newMonth
}
那么上面循环中的代码可以写得更短
for singlePage in firebasePages {
let month = singlePage.date.getFormattedDate(format: "MMyyyy")
let selectedMonth = months[month, default: make(month: month)]
// rest of the code in the loop is the same
}