WIP
This commit is contained in:
@@ -2,6 +2,10 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>NSHealthShareUsageDescription</key>
|
||||||
|
<string>Read your heart reate</string>
|
||||||
|
<key>NSHealthUpdateUsageDescription</key>
|
||||||
|
<string>Read your heart reate</string>
|
||||||
<key>NSAppTransportSecurity</key>
|
<key>NSAppTransportSecurity</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSAllowsArbitraryLoads</key>
|
<key>NSAllowsArbitraryLoads</key>
|
||||||
|
|||||||
12
Werkout-watch-Watch-App-Info.plist
Normal file
12
Werkout-watch-Watch-App-Info.plist
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>UIBackgroundModes</key>
|
||||||
|
<array/>
|
||||||
|
<key>WKBackgroundModes</key>
|
||||||
|
<array>
|
||||||
|
<string>workout-processing</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -43,8 +43,53 @@
|
|||||||
1CF65A852A43E8060042FFBD /* CompletedWorkout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A842A43E8060042FFBD /* CompletedWorkout.swift */; };
|
1CF65A852A43E8060042FFBD /* CompletedWorkout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A842A43E8060042FFBD /* CompletedWorkout.swift */; };
|
||||||
1CF65A872A4400E10042FFBD /* ToDo in Resources */ = {isa = PBXBuildFile; fileRef = 1CF65A862A4400E10042FFBD /* ToDo */; };
|
1CF65A872A4400E10042FFBD /* ToDo in Resources */ = {isa = PBXBuildFile; fileRef = 1CF65A862A4400E10042FFBD /* ToDo */; };
|
||||||
1CF65A8E2A44B78B0042FFBD /* CompletedWorkoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A8D2A44B78B0042FFBD /* CompletedWorkoutView.swift */; };
|
1CF65A8E2A44B78B0042FFBD /* CompletedWorkoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A8D2A44B78B0042FFBD /* CompletedWorkoutView.swift */; };
|
||||||
|
1CF65A962A452D270042FFBD /* Werkout_watchApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A952A452D270042FFBD /* Werkout_watchApp.swift */; };
|
||||||
|
1CF65A982A452D270042FFBD /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A972A452D270042FFBD /* ContentView.swift */; };
|
||||||
|
1CF65A9A2A452D290042FFBD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1CF65A992A452D290042FFBD /* Assets.xcassets */; };
|
||||||
|
1CF65A9D2A452D290042FFBD /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1CF65A9C2A452D290042FFBD /* Preview Assets.xcassets */; };
|
||||||
|
1CF65AA12A452D290042FFBD /* Werkout_watch Watch App.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 1CF65A932A452D270042FFBD /* Werkout_watch Watch App.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||||
|
1CF65AA52A452D9C0042FFBD /* CompletedWorkout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A842A43E8060042FFBD /* CompletedWorkout.swift */; };
|
||||||
|
1CF65AA62A452D9C0042FFBD /* Equipment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A5A2A3BF4BE0042FFBD /* Equipment.swift */; };
|
||||||
|
1CF65AA72A452D9C0042FFBD /* Muscle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A582A3BF4B60042FFBD /* Muscle.swift */; };
|
||||||
|
1CF65AA82A452D9C0042FFBD /* Exercise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A442A39FB550042FFBD /* Exercise.swift */; };
|
||||||
|
1CF65AA92A452D9C0042FFBD /* Workout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A422A39FB410042FFBD /* Workout.swift */; };
|
||||||
|
1CF65AAA2A452D9C0042FFBD /* RegisteredUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A462A39FB6C0042FFBD /* RegisteredUser.swift */; };
|
||||||
|
1CF65AAB2A452DAC0042FFBD /* PreviewWorkout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A512A3A90A00042FFBD /* PreviewWorkout.swift */; };
|
||||||
|
1CF65AAC2A452DF50042FFBD /* WorkoutOne.json in Resources */ = {isa = PBXBuildFile; fileRef = 1CF65A492A39FBB10042FFBD /* WorkoutOne.json */; };
|
||||||
|
1CF65AAD2A452DF50042FFBD /* Exercises.json in Resources */ = {isa = PBXBuildFile; fileRef = 1CF65A662A3BFF840042FFBD /* Exercises.json */; };
|
||||||
|
1CF65AAE2A452DF50042FFBD /* AllWorkouts.json in Resources */ = {isa = PBXBuildFile; fileRef = 1CF65A642A3BF6BE0042FFBD /* AllWorkouts.json */; };
|
||||||
|
1CF65AAF2A452DF50042FFBD /* AllMuscles.json in Resources */ = {isa = PBXBuildFile; fileRef = 1CF65A562A3BF3830042FFBD /* AllMuscles.json */; };
|
||||||
|
1CF65AB02A452DF50042FFBD /* Equipment.json in Resources */ = {isa = PBXBuildFile; fileRef = 1CF65A5E2A3BF5A60042FFBD /* Equipment.json */; };
|
||||||
|
1CF65AB12A452E1A0042FFBD /* BridgeModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A4F2A3A1EA90042FFBD /* BridgeModule.swift */; };
|
||||||
|
1CF65AB32A452F360042FFBD /* WatchPackageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65AB22A452F360042FFBD /* WatchPackageModel.swift */; };
|
||||||
|
1CF65AB42A4530200042FFBD /* WatchPackageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65AB22A452F360042FFBD /* WatchPackageModel.swift */; };
|
||||||
|
1CF65AB62A4532940042FFBD /* WatchMainViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65AB52A4532940042FFBD /* WatchMainViewModel.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
1CF65A9E2A452D290042FFBD /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 1CF65A1A2A3972840042FFBD /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 1CF65A922A452D270042FFBD;
|
||||||
|
remoteInfo = "Werkout_watch Watch App";
|
||||||
|
};
|
||||||
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
1CF65AA02A452D290042FFBD /* Embed Watch Content */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = "$(CONTENTS_FOLDER_PATH)/Watch";
|
||||||
|
dstSubfolderSpec = 16;
|
||||||
|
files = (
|
||||||
|
1CF65AA12A452D290042FFBD /* Werkout_watch Watch App.app in Embed Watch Content */,
|
||||||
|
);
|
||||||
|
name = "Embed Watch Content";
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
1CF65A222A3972840042FFBD /* Werkout_ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Werkout_ios.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
1CF65A222A3972840042FFBD /* Werkout_ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Werkout_ios.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
1CF65A252A3972840042FFBD /* Werkout_iosApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Werkout_iosApp.swift; sourceTree = "<group>"; };
|
1CF65A252A3972840042FFBD /* Werkout_iosApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Werkout_iosApp.swift; sourceTree = "<group>"; };
|
||||||
@@ -85,6 +130,15 @@
|
|||||||
1CF65A842A43E8060042FFBD /* CompletedWorkout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletedWorkout.swift; sourceTree = "<group>"; };
|
1CF65A842A43E8060042FFBD /* CompletedWorkout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletedWorkout.swift; sourceTree = "<group>"; };
|
||||||
1CF65A862A4400E10042FFBD /* ToDo */ = {isa = PBXFileReference; lastKnownFileType = text; path = ToDo; sourceTree = "<group>"; };
|
1CF65A862A4400E10042FFBD /* ToDo */ = {isa = PBXFileReference; lastKnownFileType = text; path = ToDo; sourceTree = "<group>"; };
|
||||||
1CF65A8D2A44B78B0042FFBD /* CompletedWorkoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletedWorkoutView.swift; sourceTree = "<group>"; };
|
1CF65A8D2A44B78B0042FFBD /* CompletedWorkoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletedWorkoutView.swift; sourceTree = "<group>"; };
|
||||||
|
1CF65A932A452D270042FFBD /* Werkout_watch Watch App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Werkout_watch Watch App.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
1CF65A952A452D270042FFBD /* Werkout_watchApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Werkout_watchApp.swift; sourceTree = "<group>"; };
|
||||||
|
1CF65A972A452D270042FFBD /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||||
|
1CF65A992A452D290042FFBD /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
|
1CF65A9C2A452D290042FFBD /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
||||||
|
1CF65AB22A452F360042FFBD /* WatchPackageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchPackageModel.swift; sourceTree = "<group>"; };
|
||||||
|
1CF65AB52A4532940042FFBD /* WatchMainViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchMainViewModel.swift; sourceTree = "<group>"; };
|
||||||
|
1CF65AB72A4534DC0042FFBD /* Werkout_watch Watch App.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Werkout_watch Watch App.entitlements"; sourceTree = "<group>"; };
|
||||||
|
1CF65AB82A45387B0042FFBD /* Werkout-watch-Watch-App-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "Werkout-watch-Watch-App-Info.plist"; sourceTree = SOURCE_ROOT; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@@ -95,6 +149,13 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
1CF65A902A452D270042FFBD /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
@@ -102,6 +163,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
1CF65A242A3972840042FFBD /* Werkout_ios */,
|
1CF65A242A3972840042FFBD /* Werkout_ios */,
|
||||||
|
1CF65A942A452D270042FFBD /* Werkout_watch Watch App */,
|
||||||
1CF65A232A3972840042FFBD /* Products */,
|
1CF65A232A3972840042FFBD /* Products */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -110,6 +172,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
1CF65A222A3972840042FFBD /* Werkout_ios.app */,
|
1CF65A222A3972840042FFBD /* Werkout_ios.app */,
|
||||||
|
1CF65A932A452D270042FFBD /* Werkout_watch Watch App.app */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -120,6 +183,7 @@
|
|||||||
1CF65A552A3AA6800042FFBD /* Werkout-ios-Info.plist */,
|
1CF65A552A3AA6800042FFBD /* Werkout-ios-Info.plist */,
|
||||||
1CF65A482A39FB910042FFBD /* JSON */,
|
1CF65A482A39FB910042FFBD /* JSON */,
|
||||||
1CF65A252A3972840042FFBD /* Werkout_iosApp.swift */,
|
1CF65A252A3972840042FFBD /* Werkout_iosApp.swift */,
|
||||||
|
1CF65AB22A452F360042FFBD /* WatchPackageModel.swift */,
|
||||||
1CF65A822A42347D0042FFBD /* Extensions.swift */,
|
1CF65A822A42347D0042FFBD /* Extensions.swift */,
|
||||||
1CF65A272A3972840042FFBD /* Persistence.swift */,
|
1CF65A272A3972840042FFBD /* Persistence.swift */,
|
||||||
1CF65A4F2A3A1EA90042FFBD /* BridgeModule.swift */,
|
1CF65A4F2A3A1EA90042FFBD /* BridgeModule.swift */,
|
||||||
@@ -247,6 +311,28 @@
|
|||||||
path = CompletedWorkout;
|
path = CompletedWorkout;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
1CF65A942A452D270042FFBD /* Werkout_watch Watch App */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
1CF65AB82A45387B0042FFBD /* Werkout-watch-Watch-App-Info.plist */,
|
||||||
|
1CF65AB72A4534DC0042FFBD /* Werkout_watch Watch App.entitlements */,
|
||||||
|
1CF65A952A452D270042FFBD /* Werkout_watchApp.swift */,
|
||||||
|
1CF65A972A452D270042FFBD /* ContentView.swift */,
|
||||||
|
1CF65AB52A4532940042FFBD /* WatchMainViewModel.swift */,
|
||||||
|
1CF65A992A452D290042FFBD /* Assets.xcassets */,
|
||||||
|
1CF65A9B2A452D290042FFBD /* Preview Content */,
|
||||||
|
);
|
||||||
|
path = "Werkout_watch Watch App";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
1CF65A9B2A452D290042FFBD /* Preview Content */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
1CF65A9C2A452D290042FFBD /* Preview Assets.xcassets */,
|
||||||
|
);
|
||||||
|
path = "Preview Content";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
@@ -257,14 +343,33 @@
|
|||||||
1CF65A1E2A3972840042FFBD /* Sources */,
|
1CF65A1E2A3972840042FFBD /* Sources */,
|
||||||
1CF65A1F2A3972840042FFBD /* Frameworks */,
|
1CF65A1F2A3972840042FFBD /* Frameworks */,
|
||||||
1CF65A202A3972840042FFBD /* Resources */,
|
1CF65A202A3972840042FFBD /* Resources */,
|
||||||
|
1CF65AA02A452D290042FFBD /* Embed Watch Content */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
1CF65A9F2A452D290042FFBD /* PBXTargetDependency */,
|
||||||
|
);
|
||||||
|
name = Werkout_ios;
|
||||||
|
productName = Werkout_ios;
|
||||||
|
productReference = 1CF65A222A3972840042FFBD /* Werkout_ios.app */;
|
||||||
|
productType = "com.apple.product-type.application";
|
||||||
|
};
|
||||||
|
1CF65A922A452D270042FFBD /* Werkout_watch Watch App */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 1CF65AA22A452D290042FFBD /* Build configuration list for PBXNativeTarget "Werkout_watch Watch App" */;
|
||||||
|
buildPhases = (
|
||||||
|
1CF65A8F2A452D270042FFBD /* Sources */,
|
||||||
|
1CF65A902A452D270042FFBD /* Frameworks */,
|
||||||
|
1CF65A912A452D270042FFBD /* Resources */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
);
|
);
|
||||||
name = Werkout_ios;
|
name = "Werkout_watch Watch App";
|
||||||
productName = Werkout_ios;
|
productName = "Werkout_watch Watch App";
|
||||||
productReference = 1CF65A222A3972840042FFBD /* Werkout_ios.app */;
|
productReference = 1CF65A932A452D270042FFBD /* Werkout_watch Watch App.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
};
|
};
|
||||||
/* End PBXNativeTarget section */
|
/* End PBXNativeTarget section */
|
||||||
@@ -280,6 +385,9 @@
|
|||||||
1CF65A212A3972840042FFBD = {
|
1CF65A212A3972840042FFBD = {
|
||||||
CreatedOnToolsVersion = 14.3;
|
CreatedOnToolsVersion = 14.3;
|
||||||
};
|
};
|
||||||
|
1CF65A922A452D270042FFBD = {
|
||||||
|
CreatedOnToolsVersion = 14.3;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
buildConfigurationList = 1CF65A1D2A3972840042FFBD /* Build configuration list for PBXProject "Werkout_ios" */;
|
buildConfigurationList = 1CF65A1D2A3972840042FFBD /* Build configuration list for PBXProject "Werkout_ios" */;
|
||||||
@@ -296,6 +404,7 @@
|
|||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
1CF65A212A3972840042FFBD /* Werkout_ios */,
|
1CF65A212A3972840042FFBD /* Werkout_ios */,
|
||||||
|
1CF65A922A452D270042FFBD /* Werkout_watch Watch App */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
@@ -317,6 +426,20 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
1CF65A912A452D270042FFBD /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
1CF65AAF2A452DF50042FFBD /* AllMuscles.json in Resources */,
|
||||||
|
1CF65AAC2A452DF50042FFBD /* WorkoutOne.json in Resources */,
|
||||||
|
1CF65AAD2A452DF50042FFBD /* Exercises.json in Resources */,
|
||||||
|
1CF65AB02A452DF50042FFBD /* Equipment.json in Resources */,
|
||||||
|
1CF65A9D2A452D290042FFBD /* Preview Assets.xcassets in Resources */,
|
||||||
|
1CF65A9A2A452D290042FFBD /* Assets.xcassets in Resources */,
|
||||||
|
1CF65AAE2A452DF50042FFBD /* AllWorkouts.json in Resources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
@@ -334,6 +457,7 @@
|
|||||||
1CF65A692A3C018F0042FFBD /* AccountView.swift in Sources */,
|
1CF65A692A3C018F0042FFBD /* AccountView.swift in Sources */,
|
||||||
1CF65A4E2A39FF200042FFBD /* WorkoutDetailViewModel.swift in Sources */,
|
1CF65A4E2A39FF200042FFBD /* WorkoutDetailViewModel.swift in Sources */,
|
||||||
1CF65A472A39FB6C0042FFBD /* RegisteredUser.swift in Sources */,
|
1CF65A472A39FB6C0042FFBD /* RegisteredUser.swift in Sources */,
|
||||||
|
1CF65AB32A452F360042FFBD /* WatchPackageModel.swift in Sources */,
|
||||||
1CF65A522A3A90A00042FFBD /* PreviewWorkout.swift in Sources */,
|
1CF65A522A3A90A00042FFBD /* PreviewWorkout.swift in Sources */,
|
||||||
1CF65A852A43E8060042FFBD /* CompletedWorkout.swift in Sources */,
|
1CF65A852A43E8060042FFBD /* CompletedWorkout.swift in Sources */,
|
||||||
1CF65A6E2A3F60480042FFBD /* CreateViewModels.swift in Sources */,
|
1CF65A6E2A3F60480042FFBD /* CreateViewModels.swift in Sources */,
|
||||||
@@ -354,8 +478,35 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
1CF65A8F2A452D270042FFBD /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
1CF65A982A452D270042FFBD /* ContentView.swift in Sources */,
|
||||||
|
1CF65A962A452D270042FFBD /* Werkout_watchApp.swift in Sources */,
|
||||||
|
1CF65AA92A452D9C0042FFBD /* Workout.swift in Sources */,
|
||||||
|
1CF65AA62A452D9C0042FFBD /* Equipment.swift in Sources */,
|
||||||
|
1CF65AB12A452E1A0042FFBD /* BridgeModule.swift in Sources */,
|
||||||
|
1CF65AAA2A452D9C0042FFBD /* RegisteredUser.swift in Sources */,
|
||||||
|
1CF65AB62A4532940042FFBD /* WatchMainViewModel.swift in Sources */,
|
||||||
|
1CF65AA72A452D9C0042FFBD /* Muscle.swift in Sources */,
|
||||||
|
1CF65AAB2A452DAC0042FFBD /* PreviewWorkout.swift in Sources */,
|
||||||
|
1CF65AA52A452D9C0042FFBD /* CompletedWorkout.swift in Sources */,
|
||||||
|
1CF65AA82A452D9C0042FFBD /* Exercise.swift in Sources */,
|
||||||
|
1CF65AB42A4530200042FFBD /* WatchPackageModel.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXTargetDependency section */
|
||||||
|
1CF65A9F2A452D290042FFBD /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = 1CF65A922A452D270042FFBD /* Werkout_watch Watch App */;
|
||||||
|
targetProxy = 1CF65A9E2A452D290042FFBD /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
1CF65A342A3972850042FFBD /* Debug */ = {
|
1CF65A342A3972850042FFBD /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
@@ -469,6 +620,7 @@
|
|||||||
1CF65A372A3972850042FFBD /* Debug */ = {
|
1CF65A372A3972850042FFBD /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_ENTITLEMENTS = Werkout_ios/Werkout_ios.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Werkout_ios/Werkout_ios.entitlements;
|
||||||
@@ -508,6 +660,7 @@
|
|||||||
1CF65A382A3972850042FFBD /* Release */ = {
|
1CF65A382A3972850042FFBD /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_ENTITLEMENTS = Werkout_ios/Werkout_ios.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Werkout_ios/Werkout_ios.entitlements;
|
||||||
@@ -544,6 +697,75 @@
|
|||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
1CF65AA32A452D290042FFBD /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = "Werkout_watch Watch App/Werkout_watch Watch App.entitlements";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_ASSET_PATHS = "\"Werkout_watch Watch App/Preview Content\"";
|
||||||
|
DEVELOPMENT_TEAM = V3PF3M6B6U;
|
||||||
|
ENABLE_PREVIEWS = YES;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = "Werkout-watch-Watch-App-Info.plist";
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = Werkout_watch;
|
||||||
|
INFOPLIST_KEY_NSHealthShareUsageDescription = "Read your heart reate";
|
||||||
|
INFOPLIST_KEY_NSHealthUpdateUsageDescription = "Read your heart reate";
|
||||||
|
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
||||||
|
INFOPLIST_KEY_WKCompanionAppBundleIdentifier = "com.t-t.Werkout-ios";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = "com.t-t.Werkout-ios.watchkitapp";
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SDKROOT = watchos;
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = 4;
|
||||||
|
WATCHOS_DEPLOYMENT_TARGET = 9.4;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
1CF65AA42A452D290042FFBD /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = "Werkout_watch Watch App/Werkout_watch Watch App.entitlements";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_ASSET_PATHS = "\"Werkout_watch Watch App/Preview Content\"";
|
||||||
|
DEVELOPMENT_TEAM = V3PF3M6B6U;
|
||||||
|
ENABLE_PREVIEWS = YES;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = "Werkout-watch-Watch-App-Info.plist";
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = Werkout_watch;
|
||||||
|
INFOPLIST_KEY_NSHealthShareUsageDescription = "Read your heart reate";
|
||||||
|
INFOPLIST_KEY_NSHealthUpdateUsageDescription = "Read your heart reate";
|
||||||
|
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
||||||
|
INFOPLIST_KEY_WKCompanionAppBundleIdentifier = "com.t-t.Werkout-ios";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = "com.t-t.Werkout-ios.watchkitapp";
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SDKROOT = watchos;
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = 4;
|
||||||
|
VALIDATE_PRODUCT = YES;
|
||||||
|
WATCHOS_DEPLOYMENT_TARGET = 9.4;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
/* Begin XCConfigurationList section */
|
||||||
@@ -565,6 +787,15 @@
|
|||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
|
1CF65AA22A452D290042FFBD /* Build configuration list for PBXNativeTarget "Werkout_watch Watch App" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
1CF65AA32A452D290042FFBD /* Debug */,
|
||||||
|
1CF65AA42A452D290042FFBD /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
/* Begin XCVersionGroup section */
|
/* Begin XCVersionGroup section */
|
||||||
|
|||||||
@@ -9,6 +9,11 @@
|
|||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
</dict>
|
</dict>
|
||||||
|
<key>Werkout_watch Watch App.xcscheme_^#shared#^_</key>
|
||||||
|
<dict>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -6,8 +6,15 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import WatchConnectivity
|
||||||
|
|
||||||
|
enum WatchActions: String, Codable {
|
||||||
|
case nextExercise
|
||||||
|
}
|
||||||
|
|
||||||
|
class BridgeModule: NSObject, ObservableObject {
|
||||||
|
private let kMessageKey = "message"
|
||||||
|
|
||||||
class BridgeModule: ObservableObject {
|
|
||||||
static let shared = BridgeModule()
|
static let shared = BridgeModule()
|
||||||
@Published var isShowingOnExternalDisplay = false
|
@Published var isShowingOnExternalDisplay = false
|
||||||
|
|
||||||
@@ -19,6 +26,7 @@ class BridgeModule: ObservableObject {
|
|||||||
var currentExerciseIdx: Int = -1
|
var currentExerciseIdx: Int = -1
|
||||||
|
|
||||||
var workoutStartDate: Date?
|
var workoutStartDate: Date?
|
||||||
|
var workoutEndDate: Date?
|
||||||
@Published var currentWorkoutRunTimeInSeconds: Int = -1
|
@Published var currentWorkoutRunTimeInSeconds: Int = -1
|
||||||
private var currentWorkoutRunTimer: Timer?
|
private var currentWorkoutRunTimer: Timer?
|
||||||
|
|
||||||
@@ -36,6 +44,11 @@ class BridgeModule: ObservableObject {
|
|||||||
startWorkoutTimer()
|
startWorkoutTimer()
|
||||||
workoutStartDate = Date()
|
workoutStartDate = Date()
|
||||||
isInWorkout = true
|
isInWorkout = true
|
||||||
|
|
||||||
|
if WCSession.isSupported() {
|
||||||
|
WCSession.default.delegate = self
|
||||||
|
WCSession.default.activate()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func resetCurrentWorkout() {
|
func resetCurrentWorkout() {
|
||||||
@@ -52,8 +65,14 @@ class BridgeModule: ObservableObject {
|
|||||||
currentExercise = nil
|
currentExercise = nil
|
||||||
currentWorkout = nil
|
currentWorkout = nil
|
||||||
|
|
||||||
|
if isInWorkout {
|
||||||
|
let watchModel = WatchPackageModel(currentExerciseName: currentExercise?.exercise.name ?? "-", currentTimeLeft: timeLeft, workoutStartDate: workoutStartDate ?? Date(), workoutEndDate: Date())
|
||||||
|
let data = try! JSONEncoder().encode(watchModel)
|
||||||
|
send(data)
|
||||||
|
}
|
||||||
isInWorkout = false
|
isInWorkout = false
|
||||||
workoutStartDate = nil
|
workoutStartDate = nil
|
||||||
|
workoutEndDate = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
private func startWorkoutTimer() {
|
private func startWorkoutTimer() {
|
||||||
@@ -82,6 +101,11 @@ class BridgeModule: ObservableObject {
|
|||||||
@objc func updateCounter() {
|
@objc func updateCounter() {
|
||||||
if timeLeft > 0 {
|
if timeLeft > 0 {
|
||||||
timeLeft -= 1
|
timeLeft -= 1
|
||||||
|
|
||||||
|
let watchModel = WatchPackageModel(currentExerciseName: currentExercise?.exercise.name ?? "-", currentTimeLeft: timeLeft, workoutStartDate: workoutStartDate ?? Date())
|
||||||
|
let data = try! JSONEncoder().encode(watchModel)
|
||||||
|
send(data)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
timer?.invalidate()
|
timer?.invalidate()
|
||||||
timer = nil
|
timer = nil
|
||||||
@@ -114,3 +138,46 @@ class BridgeModule: ObservableObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension BridgeModule: WCSessionDelegate {
|
||||||
|
func session(_ session: WCSession, didReceiveMessageData messageData: Data) {
|
||||||
|
if let model = try? JSONDecoder().decode(WatchActions.self, from: messageData) {
|
||||||
|
switch model {
|
||||||
|
case .nextExercise:
|
||||||
|
nextExercise()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func session(_ session: WCSession,
|
||||||
|
activationDidCompleteWith activationState: WCSessionActivationState,
|
||||||
|
error: Error?) {}
|
||||||
|
|
||||||
|
#if os(iOS)
|
||||||
|
func sessionDidBecomeInactive(_ session: WCSession) {}
|
||||||
|
func sessionDidDeactivate(_ session: WCSession) {
|
||||||
|
session.activate()
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
func send(_ data: Data) {
|
||||||
|
guard WCSession.default.activationState == .activated else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
#if os(iOS)
|
||||||
|
guard WCSession.default.isWatchAppInstalled else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
guard WCSession.default.isCompanionAppInstalled else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
WCSession.default.sendMessageData(data, replyHandler: nil)
|
||||||
|
{ error in
|
||||||
|
print("Cannot send message: \(String(describing: error))")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,11 +33,11 @@ struct WorkoutDetailView: View {
|
|||||||
CountdownView()
|
CountdownView()
|
||||||
ExerciseListView(workout: workout)
|
ExerciseListView(workout: workout)
|
||||||
ActionsView(completedWorkout: {
|
ActionsView(completedWorkout: {
|
||||||
|
bridgeModule.workoutEndDate = Date()
|
||||||
if let workoutData = createWorkoutData() {
|
if let workoutData = createWorkoutData() {
|
||||||
presentedSheet = .completedWorkout(workoutData)
|
presentedSheet = .completedWorkout(workoutData)
|
||||||
bridgeModule.resetCurrentWorkout()
|
bridgeModule.resetCurrentWorkout()
|
||||||
}
|
}
|
||||||
|
|
||||||
}, workout: workout)
|
}, workout: workout)
|
||||||
.frame(height: 44)
|
.frame(height: 44)
|
||||||
|
|
||||||
@@ -59,12 +59,14 @@ struct WorkoutDetailView: View {
|
|||||||
|
|
||||||
func createWorkoutData() -> [String:Any]? {
|
func createWorkoutData() -> [String:Any]? {
|
||||||
guard let workoutid = bridgeModule.currentWorkout?.id,
|
guard let workoutid = bridgeModule.currentWorkout?.id,
|
||||||
let startTime = bridgeModule.workoutStartDate?.timeFormatForUpload else {
|
let startTime = bridgeModule.workoutStartDate?.timeFormatForUpload,
|
||||||
|
let endTime = bridgeModule.workoutEndDate?.timeFormatForUpload else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
let postBody = [
|
let postBody = [
|
||||||
"difficulty": 1,
|
"difficulty": 1,
|
||||||
"workout_start_time": startTime,
|
"workout_start_time": startTime,
|
||||||
|
"workout_end_time": endTime,
|
||||||
"workout": workoutid,
|
"workout": workoutid,
|
||||||
"total_time": bridgeModule.currentWorkoutRunTimeInSeconds
|
"total_time": bridgeModule.currentWorkoutRunTimeInSeconds
|
||||||
] as [String : Any]
|
] as [String : Any]
|
||||||
|
|||||||
15
Werkout_ios/WatchPackageModel.swift
Normal file
15
Werkout_ios/WatchPackageModel.swift
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// WatchPackageModel.swift
|
||||||
|
// Werkout_ios
|
||||||
|
//
|
||||||
|
// Created by Trey Tartt on 6/22/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct WatchPackageModel: Codable {
|
||||||
|
var currentExerciseName: String
|
||||||
|
var currentTimeLeft: Int
|
||||||
|
var workoutStartDate: Date
|
||||||
|
var workoutEndDate: Date?
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"platform" : "watchos",
|
||||||
|
"size" : "1024x1024"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
6
Werkout_watch Watch App/Assets.xcassets/Contents.json
Normal file
6
Werkout_watch Watch App/Assets.xcassets/Contents.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
44
Werkout_watch Watch App/ContentView.swift
Normal file
44
Werkout_watch Watch App/ContentView.swift
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
//
|
||||||
|
// ContentView.swift
|
||||||
|
// Werkout_watch Watch App
|
||||||
|
//
|
||||||
|
// Created by Trey Tartt on 6/22/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct ContentView: View {
|
||||||
|
let exercise = PreviewWorkout.parseEquipment()[2]
|
||||||
|
@StateObject var vm = WatchMainViewModel()
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
if let model = vm.watchPackageModel {
|
||||||
|
Text(model.currentExerciseName)
|
||||||
|
|
||||||
|
Text("\(model.currentTimeLeft )")
|
||||||
|
}
|
||||||
|
|
||||||
|
if let heartValue = vm.heartValue {
|
||||||
|
HStack {
|
||||||
|
Image(systemName: "heart.fill")
|
||||||
|
Text("\(heartValue)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button(action: {
|
||||||
|
vm.nextExercise()
|
||||||
|
}, label: {
|
||||||
|
Image(systemName: "arrow.forward")
|
||||||
|
.font(.title)
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ContentView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
ContentView()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
195
Werkout_watch Watch App/WatchMainViewModel.swift
Normal file
195
Werkout_watch Watch App/WatchMainViewModel.swift
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
//
|
||||||
|
// WatchMainViewMoel.swift
|
||||||
|
// Werkout_watch Watch App
|
||||||
|
//
|
||||||
|
// Created by Trey Tartt on 6/22/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import WatchConnectivity
|
||||||
|
import SwiftUI
|
||||||
|
import HealthKit
|
||||||
|
|
||||||
|
class WatchMainViewModel: NSObject, ObservableObject {
|
||||||
|
var session: WCSession
|
||||||
|
@Published var watchPackageModel: WatchPackageModel?
|
||||||
|
@Published var heartValue: Int?
|
||||||
|
|
||||||
|
let healthStore = HKHealthStore()
|
||||||
|
var hkWorkoutSession: HKWorkoutSession? {
|
||||||
|
didSet {
|
||||||
|
print("here")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var hkBuilder: HKLiveWorkoutBuilder?
|
||||||
|
|
||||||
|
override init() {
|
||||||
|
session = WCSession.default
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
session.delegate = self
|
||||||
|
session.activate()
|
||||||
|
autorizeHealthKit()
|
||||||
|
}
|
||||||
|
|
||||||
|
func autorizeHealthKit() {
|
||||||
|
let healthKitTypes: Set = [
|
||||||
|
HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.heartRate)!,
|
||||||
|
HKObjectType.quantityType(forIdentifier: .activeEnergyBurned)!,
|
||||||
|
HKQuantityType.workoutType()
|
||||||
|
]
|
||||||
|
healthStore.requestAuthorization(toShare: healthKitTypes, read: healthKitTypes) { (succ, error) in
|
||||||
|
if !succ {
|
||||||
|
fatalError("Error requesting authorization from health store: \(String(describing: error)))")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func startHeartRateQuery(quantityTypeIdentifier: HKQuantityTypeIdentifier) {
|
||||||
|
let devicePredicate = HKQuery.predicateForObjects(from: [HKDevice.local()])
|
||||||
|
let updateHandler: (HKAnchoredObjectQuery, [HKSample]?, [HKDeletedObject]?, HKQueryAnchor?, Error?) -> Void = {
|
||||||
|
query, samples, deletedObjects, queryAnchor, error in
|
||||||
|
guard let samples = samples as? [HKQuantitySample] else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let query = HKAnchoredObjectQuery(type: HKObjectType.quantityType(forIdentifier: quantityTypeIdentifier)!, predicate: devicePredicate, anchor: nil, limit: HKObjectQueryNoLimit, resultsHandler: updateHandler)
|
||||||
|
|
||||||
|
query.updateHandler = updateHandler
|
||||||
|
healthStore.execute(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
func nextExercise() {
|
||||||
|
let nextExerciseAction = WatchActions.nextExercise
|
||||||
|
let data = try! JSONEncoder().encode(nextExerciseAction)
|
||||||
|
send(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension WatchMainViewModel: WCSessionDelegate {
|
||||||
|
func session(_ session: WCSession, didReceiveMessageData messageData: Data) {
|
||||||
|
if let model = try? JSONDecoder().decode(WatchPackageModel.self, from: messageData) {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
if self.watchPackageModel?.workoutEndDate != nil {
|
||||||
|
self.watchPackageModel = nil
|
||||||
|
self.stopWorkout()
|
||||||
|
} else if self.watchPackageModel == nil {
|
||||||
|
self.startWorkout()
|
||||||
|
}
|
||||||
|
self.watchPackageModel = model
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func send(_ data: Data) {
|
||||||
|
guard WCSession.default.activationState == .activated else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
#if os(iOS)
|
||||||
|
guard WCSession.default.isWatchAppInstalled else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
guard WCSession.default.isCompanionAppInstalled else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
WCSession.default.sendMessageData(data, replyHandler: nil)
|
||||||
|
{ error in
|
||||||
|
print("Cannot send message: \(String(describing: error))")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension WatchMainViewModel: HKWorkoutSessionDelegate, HKLiveWorkoutBuilderDelegate {
|
||||||
|
func initWorkout() {
|
||||||
|
let configuration = HKWorkoutConfiguration()
|
||||||
|
configuration.activityType = .functionalStrengthTraining
|
||||||
|
|
||||||
|
do {
|
||||||
|
hkWorkoutSession = try HKWorkoutSession(healthStore: healthStore, configuration: configuration)
|
||||||
|
hkBuilder = hkWorkoutSession?.associatedWorkoutBuilder()
|
||||||
|
} catch {
|
||||||
|
fatalError("Unable to create the workout session!")
|
||||||
|
}
|
||||||
|
guard let hkWorkoutSession = hkWorkoutSession, let hkBuilder = hkBuilder else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Setup session and builder.
|
||||||
|
hkWorkoutSession.delegate = self
|
||||||
|
hkBuilder.delegate = self
|
||||||
|
|
||||||
|
/// Set the workout builder's data source.
|
||||||
|
hkBuilder.dataSource = HKLiveWorkoutDataSource(healthStore: healthStore,
|
||||||
|
workoutConfiguration: configuration)
|
||||||
|
}
|
||||||
|
|
||||||
|
func startWorkout() {
|
||||||
|
// Initialize our workout
|
||||||
|
initWorkout()
|
||||||
|
|
||||||
|
guard let hkWorkoutSession = hkWorkoutSession, let hkBuilder = hkBuilder else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the workout session and begin data collection
|
||||||
|
hkWorkoutSession.startActivity(with: Date())
|
||||||
|
hkBuilder.beginCollection(withStart: Date()) { (succ, error) in
|
||||||
|
if !succ {
|
||||||
|
fatalError("Error beginning collection from builder: \(String(describing: error)))")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func stopWorkout() {
|
||||||
|
guard let hkWorkoutSession = hkWorkoutSession, let hkBuilder = hkBuilder else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
hkWorkoutSession.end()
|
||||||
|
hkBuilder.endCollection(withEnd: Date()) { (success, error) in
|
||||||
|
hkBuilder.finishWorkout { (workout, error) in
|
||||||
|
DispatchQueue.main.async() {
|
||||||
|
self.hkWorkoutSession = nil
|
||||||
|
self.hkBuilder = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func workoutSession(_ workoutSession: HKWorkoutSession, didChangeTo toState: HKWorkoutSessionState, from fromState: HKWorkoutSessionState, date: Date) {
|
||||||
|
print("[workoutSession] Changed State: \(toState.rawValue)")
|
||||||
|
}
|
||||||
|
|
||||||
|
func workoutSession(_ workoutSession: HKWorkoutSession, didFailWithError error: Error) {
|
||||||
|
print("[workoutSession] Encountered an error: \(error)")
|
||||||
|
}
|
||||||
|
|
||||||
|
func workoutBuilder(_ workoutBuilder: HKLiveWorkoutBuilder, didCollectDataOf collectedTypes: Set<HKSampleType>) {
|
||||||
|
for type in collectedTypes {
|
||||||
|
guard let quantityType = type as? HKQuantityType else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch quantityType {
|
||||||
|
case HKQuantityType.quantityType(forIdentifier: .heartRate):
|
||||||
|
let statistics = workoutBuilder.statistics(for: quantityType)
|
||||||
|
let heartRateUnit = HKUnit.count().unitDivided(by: HKUnit.minute())
|
||||||
|
let value = statistics!.mostRecentQuantity()?.doubleValue(for: heartRateUnit)
|
||||||
|
heartValue = Int(Double(round(1 * value!) / 1))
|
||||||
|
print("[workoutBuilder] Heart Rate: \(String(describing: heartValue))")
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func workoutBuilderDidCollectEvent(_ workoutBuilder: HKLiveWorkoutBuilder) {
|
||||||
|
guard let workoutEventType = workoutBuilder.workoutEvents.last?.type else { return }
|
||||||
|
print("[workoutBuilderDidCollectEvent] Workout Builder changed event: \(workoutEventType.rawValue)")
|
||||||
|
}
|
||||||
|
}
|
||||||
10
Werkout_watch Watch App/Werkout_watch Watch App.entitlements
Normal file
10
Werkout_watch Watch App/Werkout_watch Watch App.entitlements
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>com.apple.developer.healthkit</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.developer.healthkit.access</key>
|
||||||
|
<array/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
17
Werkout_watch Watch App/Werkout_watchApp.swift
Normal file
17
Werkout_watch Watch App/Werkout_watchApp.swift
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// Werkout_watchApp.swift
|
||||||
|
// Werkout_watch Watch App
|
||||||
|
//
|
||||||
|
// Created by Trey Tartt on 6/22/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
@main
|
||||||
|
struct Werkout_watch_Watch_AppApp: App {
|
||||||
|
var body: some Scene {
|
||||||
|
WindowGroup {
|
||||||
|
ContentView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user