英文:
Why is this creating duplicates instead of the unique CoreData entries?
问题
以下是您要翻译的代码部分:
import SwiftUI
import CoreData
struct AchievementView: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(entity: Achievements.entity(), sortDescriptors: [
NSSortDescriptor(key: "id", ascending: true)])
private var achievements: FetchedResults<Achievements>
var body: some View {
NavigationView {
ZStack {
Color("Background")
.ignoresSafeArea(.all)
VStack {
HStack {
let completedCount = achievements.filter(\.completed).count
let totalCount = achievements.count
let pctComp: Double = (Double(completedCount) / Double(totalCount)) * 100
Image(systemName: "star.circle").padding(.leading, 5)
.foregroundColor(.secondary)
Text("Achievements".uppercased())
.fontWeight(.heavy)
.foregroundColor(.secondary)
Spacer()
Text("\(completedCount) OF \(totalCount) (\(pctComp, specifier: "%.f")%)")
.font(.system(size:16))
.fontWeight(.heavy)
.foregroundColor(.secondary)
.padding(.trailing, 10)
}
ScrollView(showsIndicators: false) {
VStack {
ForEach(achievements) { achievement in
HStack {
VStack {
if achievement.completed == false {
Text(achievement.image ?? "")
.padding()
.grayscale(0.99)
.overlay (
Circle()
.stroke(Color(.systemGray6), lineWidth: 2)
).padding()
} else {
Text(achievement.image ?? "")
.padding()
.overlay (
Circle()
.stroke(Color.green, lineWidth: 2)
).padding()
}
}
VStack{
if achievement.completed == false {
HStack {
Text(achievement.name ?? "")
.fontWeight(.heavy)
.foregroundColor(Color(.systemGray2))
Spacer()
}
HStack {
Text(achievement.desc ?? "")
.fontWeight(.light)
.font(.system(size:10))
.foregroundColor(Color(.systemGray2))
Spacer()
}
} else {
HStack {
Text(achievement.name ?? "")
.fontWeight(.heavy)
Spacer()
}
HStack {
Text(achievement.desc ?? "")
.fontWeight(.light)
.font(.system(size:10))
Spacer()
}
}
}
Spacer()
} .background(Color("WeekShowBack"))
.cornerRadius(15)
}
}
}
}.padding()
}
}.navigationViewStyle(StackNavigationViewStyle())
.onAppear(perform: loadAchievements)
}
private func loadAchievements() {
print("Number of Times Called")
let achievementNames = ["First Entry", "Movie Starter"]
let achievemnetDesc = ["Enter your first movie or show", "Track 10 Movies"]
let achievementComp = [false, false]
let achievementImage = ["🎇","🌇"]
if achievements.count == 0 {
for index in 0..<achievementNames.count {
let newAchievement = Achievements(context: self.viewContext)
newAchievement.name = achievementNames[index]
newAchievement.desc = achievemnetDesc[index]
newAchievement.completed = achievementComp[index]
newAchievement.image = achievementImage[index]
do {
try viewContext.save()
print("Achievement Loaded!!!!!!")
} catch let error {
print(error)
}
}
}
}
}
请注意,代码中已经去掉了HTML转义字符,以便更好地理解代码。如果您需要更多关于代码的信息或有其他问题,请随时提出。
英文:
I'm trying to preload some data into CoreData when the view loads for the first time and there are no entries yet and its created the correct number of entires, but then it's making them all the same values (duplicates of the same item). The idea is to create a CoreData entity with preloaded Achievements which the user can then earn throughout the app, which will just update the 'completed' attribute of that entry. Problem is, it's creating the correct number of entries, but it's creating them all the same. Here is what I currently have:
import SwiftUI
import CoreData
struct AchievementView: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(entity: Achievements.entity(), sortDescriptors: [
NSSortDescriptor(key: "id", ascending: true)])
private var achievements: FetchedResults<Achievements>
var body: some View {
NavigationView {
ZStack {
Color("Background")
.ignoresSafeArea(.all)
VStack {
HStack {
let completedCount = achievements.filter(\.completed).count
let totalCount = achievements.count
let pctComp: Double = (Double(completedCount) / Double(totalCount)) * 100
Image(systemName: "star.circle").padding(.leading, 5)
.foregroundColor(.secondary)
Text("Achievements".uppercased())
.fontWeight(.heavy)
.foregroundColor(.secondary)
Spacer()
Text("\(completedCount) OF \(totalCount) (\(pctComp, specifier: "%.f")%)")
.font(.system(size:16))
.fontWeight(.heavy)
.foregroundColor(.secondary)
.padding(.trailing, 10)
}
ScrollView(showsIndicators: false) {
VStack {
ForEach(achievements) { achievement in
HStack {
VStack {
if achievement.completed == false {
Text(achievement.image ?? "")
.padding()
.grayscale(0.99)
.overlay (
Circle()
.stroke(Color(.systemGray6), lineWidth: 2)
).padding()
} else {
Text(achievement.image ?? "")
.padding()
.overlay (
Circle()
.stroke(Color.green, lineWidth: 2)
).padding()
}
}
VStack{
if achievement.completed == false {
HStack {
Text(achievement.name ?? "")
.fontWeight(.heavy)
.foregroundColor(Color(.systemGray2))
Spacer()
}
HStack {
Text(achievement.desc ?? "")
.fontWeight(.light)
.font(.system(size:10))
.foregroundColor(Color(.systemGray2))
Spacer()
}
} else {
HStack {
Text(achievement.name ?? "")
.fontWeight(.heavy)
Spacer()
}
HStack {
Text(achievement.desc ?? "")
.fontWeight(.light)
.font(.system(size:10))
Spacer()
}
}
}
Spacer()
} .background(Color("WeekShowBack"))
.cornerRadius(15)
}
}
}
}.padding()
}
}.navigationViewStyle(StackNavigationViewStyle())
.onAppear(perform: loadAchievements)
}
private func loadAchievements() {
print("Number of Times Called")
let achievementNames = ["First Entry", "Movie Starter"]
let achievemnetDesc = ["Enter your first movie or show", "Track 10 Movies"]
let achievementComp = [false, false]
let achievementImage = ["🥇","🔟"]
if achievements.count == 0 {
for index in 0..<achievementNames.count {
let newAchievement = Achievements(context: self.viewContext)
newAchievement.name = achievementNames[index]
newAchievement.desc = achievemnetDesc[index]
newAchievement.completed = achievementComp[index]
newAchievement.image = achievementImage[index]
do {
try viewContext.save()
print("Achievement Loaded!!!!!!")
} catch let error {
print(error)
}
}
}
}
}
答案1
得分: 1
我刚刚弄清楚了...太感激了!这让我疯狂,但我不确定为什么这很重要,因为我以为CoreData会自动分配一个。无论如何,我在函数的do语句中添加了这行代码:
newAchievement.id = UUID()
现在它正在在CoreData中创建正确的成就,现在我可以开始编写每个成就的代码了。感谢大家的帮助!
英文:
I just figured it out...thank goodness! This was driving me insane but I'm not sure why this matters as I thought CoreData automatically assigns one. Anyways, I added this line to the do statement in the function:
newAchievement.id = UUID()
Now it's creating the correct achievements in CoreData and now I can get on to actually coding each achievement. Thank you everyone for the assistance!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论