SwiftUI-从核心数据NSSet中删除-@FetchRequest with.onDelete()



我正在努力完成免费且公开的Swift黑客课程。不幸的是,关于核心数据的章节并没有解释如何在一对多关系中删除NSSet中的对象。我查看了文档,并试图找出如何使用Generated访问器,但收效甚微。如果有人能解释如何做到这一点,我将不胜感激,因为我最感兴趣的是知道
一对多关系

到目前为止,我所尝试的都失败了!!!


func deleteCandy (at offsets: IndexSet) {
for offset in offsets {
let candy = countries[offset].candyArray[offset]
moc.delete(candy)
if self.moc.hasChanges{
try? moc.save()
}
}
}

}

类别:

扩展国家{

@nonobjc public class func fetchRequest() -> NSFetchRequest<Country> {
return NSFetchRequest<Country>(entityName: "Country")
}
@NSManaged public var fullName: String?
public var wrappedFullName: String {
fullName ?? "Unknown Full Name"
}
@NSManaged public var shortName: String?
public var wrappedShortName: String{
shortName ?? "Unknown Short Name"
}
public var candyArray:[Candy] {
let set = candy as? Set<Candy> ?? []
return set.sorted {
$0.wrappedName < $1.wrappedName
}
}

@NSManaged public var candy: NSSet?

}

//MARK:生成的糖果访问者扩展国家{

@objc(addCandyObject:)
@NSManaged public func addToCandy(_ value: Candy)
@objc(removeCandyObject:)
@NSManaged public func removeFromCandy(_ value: Candy)
@objc(addCandy:)
@NSManaged public func addToCandy(_ values: NSSet)
@objc(removeCandy:)
@NSManaged public func removeFromCandy(_ values: NSSet)

}

内容视图@环境(.managedObjectContext(var moc@FetchRequest(entity:Country.entity((,sortDescriptor:[](var countries:FetchedResults

var body: some View {
VStack {
List {
ForEach(countries, id: .self) { country in
Section(header: Text(country.wrappedFullName)) {
ForEach(country.candyArray, id: .self) { candy in
Text(candy.wrappedName)
}
}
}.onDelete(perform: deleteCandy)
}
Button("Add") {
let candy1 = Candy(context: self.moc)
candy1.name = "Mars"
candy1.origin = Country(context: self.moc)
candy1.origin?.shortName = "UK"
candy1.origin?.fullName = "United Kingdom"
let candy2 = Candy(context: self.moc)
candy2.name = "KitKat"
candy2.origin = Country(context: self.moc)
candy2.origin?.shortName = "UK"
candy2.origin?.fullName = "United Kingdom"
let candy3 = Candy(context: self.moc)
candy3.name = "Twix"
candy3.origin = Country(context: self.moc)
candy3.origin?.shortName = "UK"
candy3.origin?.fullName = "United Kingdom"
let candy4 = Candy(context: self.moc)
candy4.name = "Toblerone"
candy4.origin = Country(context: self.moc)
candy4.origin?.shortName = "CH"
candy4.origin?.fullName = "Switzerland"
try? self.moc.save()
}
}
}
func deleteCandy (at offsets: IndexSet) {
for offset in offsets {
let candy = countries[offset].candyArray[offset]
moc.delete(candy)
if self.moc.hasChanges{
try? moc.save()
}
}
}

}UI

最终,这个从DMG传递闭包的解决方案运行得非常好:

这里的解决方案解释得很好。

func deleteCandies(at offsets: IndexSet, from country: Country) {
for offset in offsets.sorted().reversed() {
let candyToDelete = country.candyArray[offset]
country.removeFromCandy(candyToDelete)
moc.delete(candyToDelete)
}
if moc.hasChanges{
try? moc.save()
}
}

VStack {
List {
ForEach(countries, id: .self) { country in
Section(header: Text(country.wrappedFullName)) {
ForEach(country.candyArray, id: .self) { candy in
Text(candy.wrappedName)
}
.onDelete(perform: { offsets in
self.deleteCandies(at: offsets, from: country)
})
}
}
}

我偶然发现了同样的问题,并使用从NSManagedObject子类生成的removeFromCandy(_value:Candy(函数解决了它。

var body: some View {
VStack {
List {
ForEach(countries, id: .self) { country in
Section(header: Text(country.wrappedFullName)) {
ForEach(country.candyArray, id: .self) { candy in
Text(candy.wrappedName)
}.onDelete {indexSet in
let deleteItem = self.country.candyArray[indexSet.first!]
self.country.removeFromCandy(deleteItem)
self.moc.delete(deleteItem)
do {
try self.moc.save()
} catch {
print(error)
}               
}
}
}
}
Button("Add") {
let candy1 = Candy(context: self.moc)
candy1.name = "Mars"
candy1.origin = Country(context: self.moc)
candy1.origin?.shortName = "UK"
candy1.origin?.fullName = "United Kingdom"
try? self.moc.save()
}
}
}

最新更新