- Migrate from SwiftData to CoreData with CloudKit sync - Add core models: Split, Exercise, Workout, WorkoutLog - Implement tab-based UI: Workout Logs, Splits, Settings - Add SF Symbols picker for split icons - Add exercise picker filtered by split with exclusion of added exercises - Integrate IndieAbout for settings/about section - Add Yams for YAML exercise definition parsing - Include starter exercise libraries (bodyweight, Planet Fitness) - Add Date extensions for formatting (formattedTime, isSameDay) - Format workout date ranges to show time-only for same-day end dates - Add build number update script - Add app icons
55 lines
1.5 KiB
Swift
55 lines
1.5 KiB
Swift
import Foundation
|
|
import CoreData
|
|
|
|
@objc(Exercise)
|
|
public class Exercise: NSManagedObject, Identifiable {
|
|
@NSManaged public var name: String
|
|
@NSManaged public var loadType: Int32
|
|
@NSManaged public var order: Int32
|
|
@NSManaged public var sets: Int32
|
|
@NSManaged public var reps: Int32
|
|
@NSManaged public var weight: Int32
|
|
@NSManaged public var duration: Date?
|
|
@NSManaged public var weightLastUpdated: Date?
|
|
@NSManaged public var weightReminderTimeIntervalWeeks: Int32
|
|
|
|
@NSManaged public var split: Split?
|
|
|
|
public var id: NSManagedObjectID { objectID }
|
|
|
|
var loadTypeEnum: LoadType {
|
|
get { LoadType(rawValue: Int(loadType)) ?? .weight }
|
|
set { loadType = Int32(newValue.rawValue) }
|
|
}
|
|
}
|
|
|
|
// MARK: - Fetch Request
|
|
|
|
extension Exercise {
|
|
@nonobjc public class func fetchRequest() -> NSFetchRequest<Exercise> {
|
|
return NSFetchRequest<Exercise>(entityName: "Exercise")
|
|
}
|
|
|
|
static func orderedFetchRequest(for split: Split) -> NSFetchRequest<Exercise> {
|
|
let request = fetchRequest()
|
|
request.predicate = NSPredicate(format: "split == %@", split)
|
|
request.sortDescriptors = [NSSortDescriptor(keyPath: \Exercise.order, ascending: true)]
|
|
return request
|
|
}
|
|
}
|
|
|
|
|
|
enum LoadType: Int, CaseIterable {
|
|
case none = 0
|
|
case weight = 1
|
|
case duration = 2
|
|
|
|
var name: String {
|
|
switch self {
|
|
case .none: "None"
|
|
case .weight: "Weight"
|
|
case .duration: "Duration"
|
|
}
|
|
}
|
|
}
|