WIP
This commit is contained in:
@@ -36,6 +36,9 @@
|
|||||||
1CF65A6E2A3F60480042FFBD /* CreateViewModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A6D2A3F60480042FFBD /* CreateViewModels.swift */; };
|
1CF65A6E2A3F60480042FFBD /* CreateViewModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A6D2A3F60480042FFBD /* CreateViewModels.swift */; };
|
||||||
1CF65A732A3F60D20042FFBD /* CreateExerciseActionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A722A3F60D20042FFBD /* CreateExerciseActionsView.swift */; };
|
1CF65A732A3F60D20042FFBD /* CreateExerciseActionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A722A3F60D20042FFBD /* CreateExerciseActionsView.swift */; };
|
||||||
1CF65A7B2A3F83440042FFBD /* CreateWorkoutSupersetActionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A7A2A3F83440042FFBD /* CreateWorkoutSupersetActionsView.swift */; };
|
1CF65A7B2A3F83440042FFBD /* CreateWorkoutSupersetActionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A7A2A3F83440042FFBD /* CreateWorkoutSupersetActionsView.swift */; };
|
||||||
|
1CF65A7D2A41275D0042FFBD /* Network.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A7C2A41275D0042FFBD /* Network.swift */; };
|
||||||
|
1CF65A7F2A4129320042FFBD /* Fetchables.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A7E2A4129320042FFBD /* Fetchables.swift */; };
|
||||||
|
1CF65A812A412AA30042FFBD /* DataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A802A412AA30042FFBD /* DataStore.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
@@ -71,6 +74,9 @@
|
|||||||
1CF65A6D2A3F60480042FFBD /* CreateViewModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateViewModels.swift; sourceTree = "<group>"; };
|
1CF65A6D2A3F60480042FFBD /* CreateViewModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateViewModels.swift; sourceTree = "<group>"; };
|
||||||
1CF65A722A3F60D20042FFBD /* CreateExerciseActionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateExerciseActionsView.swift; sourceTree = "<group>"; };
|
1CF65A722A3F60D20042FFBD /* CreateExerciseActionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateExerciseActionsView.swift; sourceTree = "<group>"; };
|
||||||
1CF65A7A2A3F83440042FFBD /* CreateWorkoutSupersetActionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateWorkoutSupersetActionsView.swift; sourceTree = "<group>"; };
|
1CF65A7A2A3F83440042FFBD /* CreateWorkoutSupersetActionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateWorkoutSupersetActionsView.swift; sourceTree = "<group>"; };
|
||||||
|
1CF65A7C2A41275D0042FFBD /* Network.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Network.swift; sourceTree = "<group>"; };
|
||||||
|
1CF65A7E2A4129320042FFBD /* Fetchables.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fetchables.swift; sourceTree = "<group>"; };
|
||||||
|
1CF65A802A412AA30042FFBD /* DataStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataStore.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@@ -115,6 +121,7 @@
|
|||||||
1CF65A302A3972850042FFBD /* Werkout_ios.entitlements */,
|
1CF65A302A3972850042FFBD /* Werkout_ios.entitlements */,
|
||||||
1CF65A292A3972840042FFBD /* Werkout_ios.xcdatamodeld */,
|
1CF65A292A3972840042FFBD /* Werkout_ios.xcdatamodeld */,
|
||||||
1CF65A312A3972850042FFBD /* Preview Content */,
|
1CF65A312A3972850042FFBD /* Preview Content */,
|
||||||
|
1CF65A802A412AA30042FFBD /* DataStore.swift */,
|
||||||
);
|
);
|
||||||
path = Werkout_ios;
|
path = Werkout_ios;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -132,6 +139,8 @@
|
|||||||
1CF65A3D2A3973760042FFBD /* Network */ = {
|
1CF65A3D2A3973760042FFBD /* Network */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
1CF65A7C2A41275D0042FFBD /* Network.swift */,
|
||||||
|
1CF65A7E2A4129320042FFBD /* Fetchables.swift */,
|
||||||
);
|
);
|
||||||
path = Network;
|
path = Network;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -262,6 +271,8 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
1CF65A7F2A4129320042FFBD /* Fetchables.swift in Sources */,
|
||||||
|
1CF65A812A412AA30042FFBD /* DataStore.swift in Sources */,
|
||||||
1CF65A6B2A3C1EAC0042FFBD /* CreateWorkoutMainView.swift in Sources */,
|
1CF65A6B2A3C1EAC0042FFBD /* CreateWorkoutMainView.swift in Sources */,
|
||||||
1CF65A7B2A3F83440042FFBD /* CreateWorkoutSupersetActionsView.swift in Sources */,
|
1CF65A7B2A3F83440042FFBD /* CreateWorkoutSupersetActionsView.swift in Sources */,
|
||||||
1CF65A262A3972840042FFBD /* Werkout_iosApp.swift in Sources */,
|
1CF65A262A3972840042FFBD /* Werkout_iosApp.swift in Sources */,
|
||||||
@@ -278,6 +289,7 @@
|
|||||||
1CF65A592A3BF4B60042FFBD /* Muscle.swift in Sources */,
|
1CF65A592A3BF4B60042FFBD /* Muscle.swift in Sources */,
|
||||||
1CF65A2B2A3972840042FFBD /* Werkout_ios.xcdatamodeld in Sources */,
|
1CF65A2B2A3972840042FFBD /* Werkout_ios.xcdatamodeld in Sources */,
|
||||||
1CF65A2D2A3972840042FFBD /* MainView.swift in Sources */,
|
1CF65A2D2A3972840042FFBD /* MainView.swift in Sources */,
|
||||||
|
1CF65A7D2A41275D0042FFBD /* Network.swift in Sources */,
|
||||||
1CF65A732A3F60D20042FFBD /* CreateExerciseActionsView.swift in Sources */,
|
1CF65A732A3F60D20042FFBD /* CreateExerciseActionsView.swift in Sources */,
|
||||||
1CF65A282A3972840042FFBD /* Persistence.swift in Sources */,
|
1CF65A282A3972840042FFBD /* Persistence.swift in Sources */,
|
||||||
1CF65A5B2A3BF4BE0042FFBD /* Equipment.swift in Sources */,
|
1CF65A5B2A3BF4BE0042FFBD /* Equipment.swift in Sources */,
|
||||||
|
|||||||
79
Werkout_ios/DataStore.swift
Normal file
79
Werkout_ios/DataStore.swift
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
//
|
||||||
|
// DataStore.swift
|
||||||
|
// Werkout_ios
|
||||||
|
//
|
||||||
|
// Created by Trey Tartt on 6/19/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class DataStore {
|
||||||
|
enum DataStoreStatus {
|
||||||
|
case loading
|
||||||
|
case idle
|
||||||
|
}
|
||||||
|
|
||||||
|
static let shared = DataStore()
|
||||||
|
|
||||||
|
public private(set) var allWorkouts: [Workout]?
|
||||||
|
public private(set) var allMuscles: [Muscle]?
|
||||||
|
public private(set) var allEquipment: [Equipment]?
|
||||||
|
public private(set) var allExercise: [ExerciseExercise]?
|
||||||
|
|
||||||
|
public private(set) var status = DataStoreStatus.idle
|
||||||
|
|
||||||
|
private let fetchAllDataQueue = DispatchGroup()
|
||||||
|
|
||||||
|
public func fetchAllData() {
|
||||||
|
status = .loading
|
||||||
|
|
||||||
|
fetchAllDataQueue.enter()
|
||||||
|
fetchAllDataQueue.enter()
|
||||||
|
fetchAllDataQueue.enter()
|
||||||
|
fetchAllDataQueue.enter()
|
||||||
|
|
||||||
|
fetchAllDataQueue.notify(queue: .main) {
|
||||||
|
self.status = .idle
|
||||||
|
}
|
||||||
|
|
||||||
|
AllWorkoutFetchable().fetch(completion: { result in
|
||||||
|
switch result {
|
||||||
|
case .success(let model):
|
||||||
|
self.allWorkouts = model
|
||||||
|
case .failure(let error):
|
||||||
|
print(error)
|
||||||
|
}
|
||||||
|
self.fetchAllDataQueue.leave()
|
||||||
|
})
|
||||||
|
|
||||||
|
AllMusclesFetchable().fetch(completion: { result in
|
||||||
|
switch result {
|
||||||
|
case .success(let model):
|
||||||
|
self.allMuscles = model
|
||||||
|
case .failure(let error):
|
||||||
|
print(error)
|
||||||
|
}
|
||||||
|
self.fetchAllDataQueue.leave()
|
||||||
|
})
|
||||||
|
|
||||||
|
AllEquipmentFetchable().fetch(completion: { result in
|
||||||
|
switch result {
|
||||||
|
case .success(let model):
|
||||||
|
self.allEquipment = model
|
||||||
|
case .failure(let error):
|
||||||
|
print(error)
|
||||||
|
}
|
||||||
|
self.fetchAllDataQueue.leave()
|
||||||
|
})
|
||||||
|
|
||||||
|
AllExerciseFetchable().fetch(completion: { result in
|
||||||
|
switch result {
|
||||||
|
case .success(let model):
|
||||||
|
self.allExercise = model
|
||||||
|
case .failure(let error):
|
||||||
|
print(error)
|
||||||
|
}
|
||||||
|
self.fetchAllDataQueue.leave()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
37
Werkout_ios/Network/Fetchables.swift
Normal file
37
Werkout_ios/Network/Fetchables.swift
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// AllWorkoutFetchable.swift
|
||||||
|
// Werkout_ios
|
||||||
|
//
|
||||||
|
// Created by Trey Tartt on 6/19/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class AllWorkoutFetchable: Fetchable {
|
||||||
|
typealias Response = [Workout]
|
||||||
|
var endPoint: String = "workout/all/"
|
||||||
|
}
|
||||||
|
|
||||||
|
class WorkoutDetailFetchable: Fetchable {
|
||||||
|
typealias Response = Workout
|
||||||
|
var endPoint: String
|
||||||
|
|
||||||
|
init(workoutID: String) {
|
||||||
|
self.endPoint = "/workout/"+workoutID+"/details/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AllMusclesFetchable: Fetchable {
|
||||||
|
typealias Response = [Muscle]
|
||||||
|
var endPoint: String = "muscle/all/"
|
||||||
|
}
|
||||||
|
|
||||||
|
class AllEquipmentFetchable: Fetchable {
|
||||||
|
typealias Response = [Equipment]
|
||||||
|
var endPoint: String = "equipment/all/"
|
||||||
|
}
|
||||||
|
|
||||||
|
class AllExerciseFetchable: Fetchable {
|
||||||
|
typealias Response = [ExerciseExercise]
|
||||||
|
var endPoint: String = "exercise/all/"
|
||||||
|
}
|
||||||
57
Werkout_ios/Network/Network.swift
Normal file
57
Werkout_ios/Network/Network.swift
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
//
|
||||||
|
// Network.swift
|
||||||
|
// Werkout_ios
|
||||||
|
//
|
||||||
|
// Created by Trey Tartt on 6/19/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
enum FetchableError: Error {
|
||||||
|
case apiError(Error)
|
||||||
|
case noData
|
||||||
|
case decodeError(Error)
|
||||||
|
case endOfFileError
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol Fetchable {
|
||||||
|
associatedtype Response: Codable
|
||||||
|
|
||||||
|
var baseURL: String { get }
|
||||||
|
var endPoint: String { get }
|
||||||
|
|
||||||
|
func fetch(completion: @escaping (Result<Response, FetchableError>) -> Void)
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Fetchable {
|
||||||
|
var baseURL: String {
|
||||||
|
"http://127.0.0.1:8000/"
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetch(completion: @escaping (Result<Response, FetchableError>) -> Void) {
|
||||||
|
let url = URL(string: baseURL+endPoint)!
|
||||||
|
|
||||||
|
let task = URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
|
||||||
|
if let error = error {
|
||||||
|
completion(.failure(.apiError(error)))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
guard let data = data else {
|
||||||
|
completion(.failure(.noData))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
let model = try JSONDecoder().decode(Response.self, from: data)
|
||||||
|
completion(.success(model))
|
||||||
|
return
|
||||||
|
} catch {
|
||||||
|
completion(.failure(.decodeError(error)))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
completion(.failure(.endOfFileError))
|
||||||
|
})
|
||||||
|
|
||||||
|
task.resume()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,10 +10,6 @@ import SwiftUI
|
|||||||
import Combine
|
import Combine
|
||||||
|
|
||||||
struct AddExerciseView: View {
|
struct AddExerciseView: View {
|
||||||
@State var exercises: [ExerciseExercise]?
|
|
||||||
@State var equipment: [Equipment]?
|
|
||||||
@State var muscles: [Muscle]?
|
|
||||||
|
|
||||||
@State var selectedMuscles = [Muscle]()
|
@State var selectedMuscles = [Muscle]()
|
||||||
@State var selectedEquipment = [Equipment]()
|
@State var selectedEquipment = [Equipment]()
|
||||||
@State var filteredExercises = [ExerciseExercise]()
|
@State var filteredExercises = [ExerciseExercise]()
|
||||||
@@ -27,7 +23,7 @@ struct AddExerciseView: View {
|
|||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
VStack {
|
||||||
if let muscles = muscles {
|
if let muscles = DataStore.shared.allMuscles {
|
||||||
Button("toggle all", action: {
|
Button("toggle all", action: {
|
||||||
if self.selectedMuscles.count > 0 {
|
if self.selectedMuscles.count > 0 {
|
||||||
self.selectedMuscles.removeAll()
|
self.selectedMuscles.removeAll()
|
||||||
@@ -66,7 +62,7 @@ struct AddExerciseView: View {
|
|||||||
}.frame(height: 100)
|
}.frame(height: 100)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let equipment = equipment {
|
if let equipment = DataStore.shared.allEquipment {
|
||||||
Button("toggle all", action: {
|
Button("toggle all", action: {
|
||||||
if self.selectedEquipment.count > 0 {
|
if self.selectedEquipment.count > 0 {
|
||||||
self.selectedEquipment.removeAll()
|
self.selectedEquipment.removeAll()
|
||||||
@@ -137,9 +133,14 @@ struct AddExerciseView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onAppear{
|
.onAppear{
|
||||||
parseMuscle()
|
guard let exercises = DataStore.shared.allExercise,
|
||||||
parseEquipment()
|
let muscles = DataStore.shared.allMuscles,
|
||||||
parseExercises()
|
let equipment = DataStore.shared.allEquipment else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
selectedMuscles = muscles
|
||||||
|
selectedEquipment = equipment
|
||||||
|
filteredExercises = exercises
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,9 +155,9 @@ struct AddExerciseView: View {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let exercises = exercises,
|
guard let exercises = DataStore.shared.allExercise,
|
||||||
let muscles = muscles,
|
let muscles = DataStore.shared.allMuscles,
|
||||||
let equipment = equipment else {
|
let equipment = DataStore.shared.allEquipment else {
|
||||||
filteredExercises = [ExerciseExercise]()
|
filteredExercises = [ExerciseExercise]()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -192,52 +193,52 @@ struct AddExerciseView: View {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseExercises() {
|
// func parseExercises() {
|
||||||
if let filepath = Bundle.main.path(forResource: "Exercises", ofType: "json") {
|
// if let filepath = Bundle.main.path(forResource: "Exercises", ofType: "json") {
|
||||||
do {
|
// do {
|
||||||
let data = try Data(NSData(contentsOfFile: filepath))
|
// let data = try Data(NSData(contentsOfFile: filepath))
|
||||||
let workout = try JSONDecoder().decode([ExerciseExercise].self, from: data)
|
// let workout = try JSONDecoder().decode([ExerciseExercise].self, from: data)
|
||||||
self.filteredExercises.append(contentsOf: workout)
|
// self.filteredExercises.append(contentsOf: workout)
|
||||||
self.exercises = workout
|
// self.exercises = workout
|
||||||
} catch {
|
// } catch {
|
||||||
print(error)
|
// print(error)
|
||||||
fatalError()
|
// fatalError()
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
fatalError()
|
// fatalError()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
func parseEquipment() {
|
// func parseEquipment() {
|
||||||
if let filepath = Bundle.main.path(forResource: "Equipment", ofType: "json") {
|
// if let filepath = Bundle.main.path(forResource: "Equipment", ofType: "json") {
|
||||||
do {
|
// do {
|
||||||
let data = try Data(NSData(contentsOfFile: filepath))
|
// let data = try Data(NSData(contentsOfFile: filepath))
|
||||||
let workout = try JSONDecoder().decode([Equipment].self, from: data)
|
// let workout = try JSONDecoder().decode([Equipment].self, from: data)
|
||||||
self.equipment = workout
|
// self.equipment = workout
|
||||||
self.selectedEquipment.append(contentsOf: workout)
|
// self.selectedEquipment.append(contentsOf: workout)
|
||||||
} catch {
|
// } catch {
|
||||||
print(error)
|
// print(error)
|
||||||
fatalError()
|
// fatalError()
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
fatalError()
|
// fatalError()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
func parseMuscle() {
|
// func parseMuscle() {
|
||||||
if let filepath = Bundle.main.path(forResource: "AllMuscles", ofType: "json") {
|
// if let filepath = Bundle.main.path(forResource: "AllMuscles", ofType: "json") {
|
||||||
do {
|
// do {
|
||||||
let data = try Data(NSData(contentsOfFile: filepath))
|
// let data = try Data(NSData(contentsOfFile: filepath))
|
||||||
let workout = try JSONDecoder().decode([Muscle].self, from: data)
|
// let workout = try JSONDecoder().decode([Muscle].self, from: data)
|
||||||
self.muscles = workout
|
// self.muscles = workout
|
||||||
self.selectedMuscles.append(contentsOf: workout)
|
// self.selectedMuscles.append(contentsOf: workout)
|
||||||
} catch {
|
// } catch {
|
||||||
print(error)
|
// print(error)
|
||||||
fatalError()
|
// fatalError()
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
fatalError()
|
// fatalError()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,9 @@ struct Werkout_iosApp: App {
|
|||||||
Label("Accounts", systemImage: "person.fill.turn.down")
|
Label("Accounts", systemImage: "person.fill.turn.down")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.onAppear{
|
||||||
|
DataStore.shared.fetchAllData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user