如何生成多维核心数据对象的列表

时间:2020-06-15 16:28:33

标签: ios swift xcode swiftui

我希望,这个问题不要太复杂,因为思考它会让我的大脑爆炸,所以我将尽我所能尽力解释它。

我有以下CoreData实体: Core Data entities

代码相同:

extension Exercise {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Exercise> {
        return NSFetchRequest<Exercise>(entityName: "Exercise")
    }

    @NSManaged public var name: String
    @NSManaged public var setgroup: Set<TrainingSession>
    @NSManaged public var workout: Workout

}
extension Training {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Training> {
        return NSFetchRequest<Training>(entityName: "Training")
    }

    @NSManaged public var name: String
    @NSManaged public var workouts: Set<Workout>

}
extension TrainingSession {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<TrainingSession> {
        return NSFetchRequest<TrainingSession>(entityName: "TrainingSession")
    }

    @NSManaged public var date: Date
    @NSManaged public var exercise: Exercise
    @NSManaged public var sessions: Set<Session>
}
extension Workout {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Workout> {
        return NSFetchRequest<Workout>(entityName: "Workout")
    }

    @NSManaged public var name: String
    @NSManaged public var exercises: Set<Exercise>
    @NSManaged public var training: Training

}
extension Session {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Session> {
        return NSFetchRequest<Session>(entityName: "Session")
    }

    @NSManaged public var repeats: Int16
    @NSManaged public var weight: Int16
    @NSManaged public var trainingSession: TrainingSession

}

简而言之,用户可以创建培训。对于任何训练,他都可以进行许多锻炼。对于任何锻炼,他都可以进行许多练习。对于任何练习,他都可以创建一个培训课程(即培训日期),并且对于每个课程,他都可以添加权重和重复次数。

现在,我想展示一个训练乳制品,其中列出了按锻炼分组的每个锻炼(不需要训练),并且在每次选定的训练中都进行了训练。

我从DiaryView开始:

struct DiaryView: View {

    @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \TrainingSession.date, ascending: false)]) var sessions: FetchedResults<TrainingSession>
    @Environment(\.managedObjectContext) var viewContext

    var body: some View {
        NavigationView {
            List (sessions, id: \.self) { session in
                NavigationLink(destination: DiaryExercicesView(session: session)) {
                    List (self.sessions, id: \.self) { session in
                        Text(dateFormatter.string(from: session.date))
                    }
                }
            }
        .navigationBarTitle(Text("Tagebuch"))
        }
    }
}

该视图完美地创建了所有TrainingSession的列表。 现在,当我导航到DiaryView时,我的头脑迷茫了。 我想要像这样的lis:

锻炼名称

  • 运动健身
  • 运动吧

锻炼B名称

  • 运动知识
  • 运动输液器

以此类推。

毫无疑问,我该怎么做。

struct DiaryExercicesView: View {

    var session: TrainingSession

    var body: some View {
        Text("Need help here")
    }
}

应用设计的一些背景知识: 用户可以创建一个培训(相当于一个计划,例如“我的减脂培训”)。然后,他可以创建“全身”,“ Abs”,“推”,“拉” ...等锻炼。每个锻炼都有“卧推”,“下蹲”,... 设置完成后,他可以跟踪他的锻炼。他通过嵌套列表选择计划/培训,锻炼和锻炼。最后,他创建了一个培训课程/日期戳,并开始跟踪重量和重复次数。

1 个答案:

答案 0 :(得分:-1)

好的,我无法发表评论,但我正在尝试澄清一些想法。

  1. 我认为使用@FetchRequest并试图将对象从db弄乱到UI并不完美。您是否考虑通过ViewModel(在DiaryView中使用初始化@ObservedObject(如下所示))获取数据,然后通过@Published显示到UI?

  2. 我认为像上面这样设计的模型并不舒服。我的意思是,像Training -> Workout -> Exercise这样的模型还可以,但我认为您可以将TrainingSessionSession合并,因为这很相似,不是吗?我们通过3-4个培训课程进行一次练习,其中可能有重复,startedTime,endedTime,重量等等。可能我错了。

我想您的代码可能如下所示:

class DiaryExercicesViewModel: ObservableObject {
    let trainingSession: TrainingSession
    @Published workouts: [Workout]
    @Published exercises: [Exercise]

    init(session: TrainingSession) {
        self.trainingSession = session
    }

    // find exercises and workouts. Abstract way
    func show() {
        let tuple = db.search(by: self.trainingSession)

        self.workouts = tuple.0
        self.exercises = tuple.1
    }

}

struct DiaryExercicesView: View {
    @ObservedObject var viewModel: DiaryExercicesViewModel
    var session: TrainingSession // session which has passed from another view

    init(session: TrainingSession) {
        self.session = session
        self.viewModel = DiaryExercicesViewModel(session: session)
    }

    var body: some View {
        Text("Need help here") // I described abstract way
        VStack {
            List(viewModel.workouts)
            List(viewModel.exercises)
        }
    }
}