【问题标题】:How to add and view data of a core model relationship如何添加和查看核心模型关系的数据
【发布时间】:2020-06-06 14:25:22
【问题描述】:

我是 Core Data 的新手,我知道如何从实体中添加读取数据。 我有两个实体:

  1. 使用属性名称进行训练:字符串
  2. 具有属性名称的锻炼:字符串

关系是

  • 训练 > 锻炼到许多可选的
  • 锻炼 > 训练到一个!可选

我想在我的应用中添加训练和锻炼,它们是训练的子项。

创建实体后(codegen 是手动的),我自动创建了 NSManagedObject 子类并且没有更改它们。

我的ContentView.swift 看起来像这样:

import SwiftUI
import CoreData

struct ContentView: View {

    @State var newTrainingName: String = ""
    @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Training.name, ascending: true)]) var trainings: FetchedResults<Training>
    @Environment(\.managedObjectContext) var viewContext

    var body: some View {
        NavigationView {
            VStack {
                Group {
                    VStack {
                        TextField("Name", text: $newTrainingName)
                            .padding()
                            .background(Color.white)
                            .cornerRadius(15)
                        Button(action: {
                            let training = Training(context: self.viewContext)
                            training.name = self.newTrainingName
                            try! self.viewContext.save()
                        }) {
                            Text("Add")
                                .padding()
                        }
                    }
                    .padding()
                    .background(Color(#colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)))
                    .cornerRadius(15)
                }
                .padding()
                List (trainings, id: \.self) { training in
                    NavigationLink(destination: WorkoutView(training: training)) {
                        Text(training.name!)
                    }
                }
            }
        .navigationBarTitle(Text("Trainings"))
        }
    }
}

struct WorkoutView: View {

    var training: Training
    @State var newWorkoutText: String = ""
    @Environment(\.managedObjectContext) var viewContext

    var body: some View {

        VStack {
            Group {
                VStack {
                    TextField("Name", text: $newWorkoutText)
                        .padding()
                        .background(Color.white)
                        .cornerRadius(15)
                    Button(action: {
                        let workout = Workout(context: self.viewContext)
                        workout.name = self.newWorkoutText
                        self.training.addToWorkouts(workout)
                        try! self.viewContext.save()
                    }) {
                        Text("Add")
                            .padding()
                    }
                }
                .padding()
                .background(Color(#colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)))
                .cornerRadius(15)
            }
            .padding()
            List (training.workouts ?? [], id: \.self) { workout in
                Text(workout.name!)
            }
        }

    }
}

对于ContentView(),一切正常。我迷失了WorkoutView() 部分。 我想在 Core Data 中的训练中添加锻炼并显示它们。

Training+CoreDataProperties.swift内我改了

@NSManaged public var workouts: NSSet?

@NSManaged public var workouts: [Workout]?

因为我认为这是有道理的。但这仍然是迷失自我的一部分。

另外我发现了这个自动生成的代码,看起来不错,但我不知道如何在我的代码中使用它:

// MARK: Generated accessors for workouts
extension Training {

    @objc(addWorkoutsObject:)
    @NSManaged public func addToWorkouts(_ value: Workout)

    @objc(removeWorkoutsObject:)
    @NSManaged public func removeFromWorkouts(_ value: Workout)

    @objc(addWorkouts:)
    @NSManaged public func addToWorkouts(_ values: NSSet)

    @objc(removeWorkouts:)
    @NSManaged public func removeFromWorkouts(_ values: NSSet)
}

【问题讨论】:

    标签: ios swift core-data swiftui


    【解决方案1】:

    确保您已经在 Core Data 中设置了关系,就像在 .xcdatamodelid 中一样,包括反向关系。

    我还建议使用 do catch 而不是 try! 以获得更好的 UI。

    您在核心数据中的关系应如下所示:

    在培训实体中: 关系:锻炼, 目的地:锻炼, 逆向:训练

    在锻炼实体中: 关系:培训, 目的地:培训, 逆:锻炼

    您应该可以在按钮操作中执行此操作:

        let workout = Workout(context: self.viewContext)
        workout.name = self.newWorkoutText
        workout.training = self.training
        do {
          try self.viewContext.save()
        } catch { print(error) }
    

    【讨论】:

    • 当我正确阅读时,这将创建我的训练,而不是锻炼,不是吗?
    • 不,这将创建一个与训练相关的锻炼。
    • 好的。如何列出与培训相关的结果?我的代码不起作用并导致第一个 VStack 上出现Unable to infer complex closure return type; add explicit type to disambiguate。另外 training.workouts 是 NSSet
    【解决方案2】:

    self.training.addToWorkouts(workout) 来自哪里?这看起来不对。

    您想在 WorkoutView 中为您的锻炼添加训练。这种关系就像任何属性一样工作,所以只需使用 =

    为其分配训练

    【讨论】:

    • 新用户无法将 cmets 发布到问题中。而且,仔细阅读还有答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-22
    相关资源
    最近更新 更多