wip
This commit is contained in:
165
Workouts/Schema/InitialData.swift
Normal file
165
Workouts/Schema/InitialData.swift
Normal file
@ -0,0 +1,165 @@
|
||||
import Foundation
|
||||
import SwiftData
|
||||
|
||||
struct InitialData {
|
||||
static let logger = AppLogger(subsystem: "Workouts", category: "InitialData")
|
||||
|
||||
// Data structures for JSON decoding
|
||||
private struct ExerciseTypeData: Codable {
|
||||
let name: String
|
||||
let descr: String
|
||||
}
|
||||
|
||||
private struct MuscleGroupData: Codable {
|
||||
let name: String
|
||||
let descr: String
|
||||
}
|
||||
|
||||
private struct MuscleData: Codable {
|
||||
let name: String
|
||||
let descr: String
|
||||
let muscleGroup: String
|
||||
}
|
||||
|
||||
private struct ExerciseData: Codable {
|
||||
let name: String
|
||||
let setup: String
|
||||
let descr: String
|
||||
let sets: Int
|
||||
let reps: Int
|
||||
let weight: Int
|
||||
let type: String
|
||||
let muscles: [String]
|
||||
}
|
||||
|
||||
private struct SplitExerciseAssignmentData: Codable {
|
||||
let exercise: String
|
||||
let weight: Int
|
||||
let sets: Int
|
||||
let reps: Int
|
||||
}
|
||||
|
||||
private struct SplitData: Codable {
|
||||
let name: String
|
||||
let intro: String
|
||||
let splitExerciseAssignments: [SplitExerciseAssignmentData]
|
||||
}
|
||||
|
||||
@MainActor
|
||||
static func create(modelContext: ModelContext) {
|
||||
logger.info("Creating initial data from JSON files")
|
||||
|
||||
// Load and insert data
|
||||
do {
|
||||
// Dictionaries to store references
|
||||
var exerciseTypes: [String: ExerciseType] = [:]
|
||||
var muscleGroups: [String: MuscleGroup] = [:]
|
||||
var muscles: [String: Muscle] = [:]
|
||||
var exercises: [String: Exercise] = [:]
|
||||
|
||||
// 1. Load Exercise Types
|
||||
let exerciseTypeData = try loadJSON(forResource: "exercise-types", type: [ExerciseTypeData].self)
|
||||
for typeData in exerciseTypeData {
|
||||
let exerciseType = ExerciseType(name: typeData.name, descr: typeData.descr)
|
||||
exerciseTypes[typeData.name] = exerciseType
|
||||
modelContext.insert(exerciseType)
|
||||
}
|
||||
|
||||
// 2. Load Muscle Groups
|
||||
let muscleGroupData = try loadJSON(forResource: "muscle-groups", type: [MuscleGroupData].self)
|
||||
for groupData in muscleGroupData {
|
||||
let muscleGroup = MuscleGroup(name: groupData.name, descr: groupData.descr)
|
||||
muscleGroups[groupData.name] = muscleGroup
|
||||
modelContext.insert(muscleGroup)
|
||||
}
|
||||
|
||||
// 3. Load Muscles
|
||||
let muscleData = try loadJSON(forResource: "muscles", type: [MuscleData].self)
|
||||
for data in muscleData {
|
||||
// Find the muscle group for this muscle
|
||||
if let muscleGroup = muscleGroups[data.muscleGroup] {
|
||||
let muscle = Muscle(name: data.name, descr: data.descr, muscleGroup: muscleGroup)
|
||||
muscles[data.name] = muscle
|
||||
modelContext.insert(muscle)
|
||||
} else {
|
||||
logger.warning("Muscle group not found for muscle: \(data.name)")
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Load Exercises
|
||||
let exerciseData = try loadJSON(forResource: "exercises", type: [ExerciseData].self)
|
||||
for data in exerciseData {
|
||||
let exercise = Exercise(name: data.name, setup: data.setup, descr: data.descr,
|
||||
sets: data.sets, reps: data.reps, weight: data.weight)
|
||||
|
||||
// Set exercise type
|
||||
if let type = exerciseTypes[data.type] {
|
||||
exercise.type = type
|
||||
} else {
|
||||
logger.warning("Exercise type not found: \(data.type) for exercise: \(data.name)")
|
||||
}
|
||||
|
||||
// Set muscles
|
||||
var exerciseMuscles: [Muscle] = []
|
||||
for muscleName in data.muscles {
|
||||
if let muscle = muscles[muscleName] {
|
||||
exerciseMuscles.append(muscle)
|
||||
} else {
|
||||
logger.warning("Muscle not found: \(muscleName) for exercise: \(data.name)")
|
||||
}
|
||||
}
|
||||
exercise.muscles = exerciseMuscles
|
||||
|
||||
exercises[data.name] = exercise
|
||||
modelContext.insert(exercise)
|
||||
}
|
||||
|
||||
// 5. Load Splits and Exercise Assignments
|
||||
let splitData = try loadJSON(forResource: "splits", type: [SplitData].self)
|
||||
for data in splitData {
|
||||
let split = Split(name: data.name, intro: data.intro)
|
||||
modelContext.insert(split)
|
||||
|
||||
// Create exercise assignments for this split
|
||||
for (index, assignment) in data.splitExerciseAssignments.enumerated() {
|
||||
if let exercise = exercises[assignment.exercise] {
|
||||
let splitAssignment = SplitExerciseAssignment(
|
||||
order: index + 1, // 1-based ordering
|
||||
sets: assignment.sets,
|
||||
reps: assignment.reps,
|
||||
weight: assignment.weight,
|
||||
split: split,
|
||||
exercise: exercise
|
||||
)
|
||||
modelContext.insert(splitAssignment)
|
||||
} else {
|
||||
logger.warning("Exercise not found: \(assignment.exercise) for split: \(data.name)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save all the inserted data
|
||||
try modelContext.save()
|
||||
logger.info("Initial data loaded successfully from JSON files")
|
||||
} catch {
|
||||
logger.error("Failed to load initial data from JSON files: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
|
||||
// Helper method to load and decode JSON from a file
|
||||
private static func loadJSON<T: Decodable>(forResource name: String, type: T.Type) throws -> T {
|
||||
guard let url = Bundle.main.url(forResource: name, withExtension: "json") else {
|
||||
logger.error("Could not find JSON file: \(name).json")
|
||||
throw NSError(domain: "InitialData", code: 1, userInfo: [NSLocalizedDescriptionKey: "Could not find JSON file: \(name).json"])
|
||||
}
|
||||
|
||||
do {
|
||||
let data = try Data(contentsOf: url)
|
||||
let decoder = JSONDecoder()
|
||||
return try decoder.decode(T.self, from: data)
|
||||
} catch {
|
||||
logger.error("Failed to decode JSON file \(name).json: \(error.localizedDescription)")
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user