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">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSHealthShareUsageDescription</key>
|
||||
<string>Read your heart reate</string>
|
||||
<key>NSHealthUpdateUsageDescription</key>
|
||||
<string>Read your heart reate</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<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 */; };
|
||||
1CF65A872A4400E10042FFBD /* ToDo in Resources */ = {isa = PBXBuildFile; fileRef = 1CF65A862A4400E10042FFBD /* ToDo */; };
|
||||
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 */
|
||||
|
||||
/* 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 */
|
||||
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>"; };
|
||||
@@ -85,6 +130,15 @@
|
||||
1CF65A842A43E8060042FFBD /* CompletedWorkout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletedWorkout.swift; 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>"; };
|
||||
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 */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -95,6 +149,13 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
1CF65A902A452D270042FFBD /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
@@ -102,6 +163,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1CF65A242A3972840042FFBD /* Werkout_ios */,
|
||||
1CF65A942A452D270042FFBD /* Werkout_watch Watch App */,
|
||||
1CF65A232A3972840042FFBD /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
@@ -110,6 +172,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1CF65A222A3972840042FFBD /* Werkout_ios.app */,
|
||||
1CF65A932A452D270042FFBD /* Werkout_watch Watch App.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -120,6 +183,7 @@
|
||||
1CF65A552A3AA6800042FFBD /* Werkout-ios-Info.plist */,
|
||||
1CF65A482A39FB910042FFBD /* JSON */,
|
||||
1CF65A252A3972840042FFBD /* Werkout_iosApp.swift */,
|
||||
1CF65AB22A452F360042FFBD /* WatchPackageModel.swift */,
|
||||
1CF65A822A42347D0042FFBD /* Extensions.swift */,
|
||||
1CF65A272A3972840042FFBD /* Persistence.swift */,
|
||||
1CF65A4F2A3A1EA90042FFBD /* BridgeModule.swift */,
|
||||
@@ -247,6 +311,28 @@
|
||||
path = CompletedWorkout;
|
||||
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 */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@@ -257,14 +343,33 @@
|
||||
1CF65A1E2A3972840042FFBD /* Sources */,
|
||||
1CF65A1F2A3972840042FFBD /* Frameworks */,
|
||||
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 = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = Werkout_ios;
|
||||
productName = Werkout_ios;
|
||||
productReference = 1CF65A222A3972840042FFBD /* Werkout_ios.app */;
|
||||
name = "Werkout_watch Watch App";
|
||||
productName = "Werkout_watch Watch App";
|
||||
productReference = 1CF65A932A452D270042FFBD /* Werkout_watch Watch App.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
@@ -280,6 +385,9 @@
|
||||
1CF65A212A3972840042FFBD = {
|
||||
CreatedOnToolsVersion = 14.3;
|
||||
};
|
||||
1CF65A922A452D270042FFBD = {
|
||||
CreatedOnToolsVersion = 14.3;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 1CF65A1D2A3972840042FFBD /* Build configuration list for PBXProject "Werkout_ios" */;
|
||||
@@ -296,6 +404,7 @@
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
1CF65A212A3972840042FFBD /* Werkout_ios */,
|
||||
1CF65A922A452D270042FFBD /* Werkout_watch Watch App */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@@ -317,6 +426,20 @@
|
||||
);
|
||||
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 */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
@@ -334,6 +457,7 @@
|
||||
1CF65A692A3C018F0042FFBD /* AccountView.swift in Sources */,
|
||||
1CF65A4E2A39FF200042FFBD /* WorkoutDetailViewModel.swift in Sources */,
|
||||
1CF65A472A39FB6C0042FFBD /* RegisteredUser.swift in Sources */,
|
||||
1CF65AB32A452F360042FFBD /* WatchPackageModel.swift in Sources */,
|
||||
1CF65A522A3A90A00042FFBD /* PreviewWorkout.swift in Sources */,
|
||||
1CF65A852A43E8060042FFBD /* CompletedWorkout.swift in Sources */,
|
||||
1CF65A6E2A3F60480042FFBD /* CreateViewModels.swift in Sources */,
|
||||
@@ -354,8 +478,35 @@
|
||||
);
|
||||
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 */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
1CF65A9F2A452D290042FFBD /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 1CF65A922A452D270042FFBD /* Werkout_watch Watch App */;
|
||||
targetProxy = 1CF65A9E2A452D290042FFBD /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
1CF65A342A3972850042FFBD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
@@ -469,6 +620,7 @@
|
||||
1CF65A372A3972850042FFBD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = Werkout_ios/Werkout_ios.entitlements;
|
||||
@@ -508,6 +660,7 @@
|
||||
1CF65A382A3972850042FFBD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = Werkout_ios/Werkout_ios.entitlements;
|
||||
@@ -544,6 +697,75 @@
|
||||
};
|
||||
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 */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
@@ -565,6 +787,15 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
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 */
|
||||
|
||||
/* Begin XCVersionGroup section */
|
||||
|
||||
@@ -9,6 +9,11 @@
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>Werkout_watch Watch App.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -6,8 +6,15 @@
|
||||
//
|
||||
|
||||
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()
|
||||
@Published var isShowingOnExternalDisplay = false
|
||||
|
||||
@@ -19,6 +26,7 @@ class BridgeModule: ObservableObject {
|
||||
var currentExerciseIdx: Int = -1
|
||||
|
||||
var workoutStartDate: Date?
|
||||
var workoutEndDate: Date?
|
||||
@Published var currentWorkoutRunTimeInSeconds: Int = -1
|
||||
private var currentWorkoutRunTimer: Timer?
|
||||
|
||||
@@ -36,6 +44,11 @@ class BridgeModule: ObservableObject {
|
||||
startWorkoutTimer()
|
||||
workoutStartDate = Date()
|
||||
isInWorkout = true
|
||||
|
||||
if WCSession.isSupported() {
|
||||
WCSession.default.delegate = self
|
||||
WCSession.default.activate()
|
||||
}
|
||||
}
|
||||
|
||||
func resetCurrentWorkout() {
|
||||
@@ -52,8 +65,14 @@ class BridgeModule: ObservableObject {
|
||||
currentExercise = 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
|
||||
workoutStartDate = nil
|
||||
workoutEndDate = nil
|
||||
}
|
||||
|
||||
private func startWorkoutTimer() {
|
||||
@@ -82,6 +101,11 @@ class BridgeModule: ObservableObject {
|
||||
@objc func updateCounter() {
|
||||
if timeLeft > 0 {
|
||||
timeLeft -= 1
|
||||
|
||||
let watchModel = WatchPackageModel(currentExerciseName: currentExercise?.exercise.name ?? "-", currentTimeLeft: timeLeft, workoutStartDate: workoutStartDate ?? Date())
|
||||
let data = try! JSONEncoder().encode(watchModel)
|
||||
send(data)
|
||||
|
||||
} else {
|
||||
timer?.invalidate()
|
||||
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()
|
||||
ExerciseListView(workout: workout)
|
||||
ActionsView(completedWorkout: {
|
||||
bridgeModule.workoutEndDate = Date()
|
||||
if let workoutData = createWorkoutData() {
|
||||
presentedSheet = .completedWorkout(workoutData)
|
||||
bridgeModule.resetCurrentWorkout()
|
||||
}
|
||||
|
||||
}, workout: workout)
|
||||
.frame(height: 44)
|
||||
|
||||
@@ -59,12 +59,14 @@ struct WorkoutDetailView: View {
|
||||
|
||||
func createWorkoutData() -> [String:Any]? {
|
||||
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
|
||||
}
|
||||
let postBody = [
|
||||
"difficulty": 1,
|
||||
"workout_start_time": startTime,
|
||||
"workout_end_time": endTime,
|
||||
"workout": workoutid,
|
||||
"total_time": bridgeModule.currentWorkoutRunTimeInSeconds
|
||||
] 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