Moved to Ascently
All checks were successful
Ascently Docker Deploy / build-and-push (push) Successful in 2m31s

This commit is contained in:
2025-10-13 14:54:54 -06:00
parent 30d2b3938e
commit 09b4055985
137 changed files with 788 additions and 483 deletions

View File

@@ -20,7 +20,7 @@
containerPortal = D24C19602E75002A0045894C /* Project object */;
proxyType = 1;
remoteGlobalIDString = D24C19672E75002A0045894C;
remoteInfo = OpenClimb;
remoteInfo = Ascently;
};
D2FE949E2E78FEE1008CDB25 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
@@ -46,9 +46,9 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
D24C19682E75002A0045894C /* OpenClimb.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OpenClimb.app; sourceTree = BUILT_PRODUCTS_DIR; };
D24C19682E75002A0045894C /* Ascently.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Ascently.app; sourceTree = BUILT_PRODUCTS_DIR; };
D268B79E2E83894A003AA641 /* SessionStatusLiveExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SessionStatusLiveExtension.entitlements; sourceTree = "<group>"; };
D2F32FAD2E90B26500B1BC56 /* OpenClimbTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OpenClimbTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
D2F32FAD2E90B26500B1BC56 /* AscentlyTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AscentlyTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
D2FE94802E78E958008CDB25 /* ActivityKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ActivityKit.framework; path = System/Library/Frameworks/ActivityKit.framework; sourceTree = SDKROOT; };
D2FE948B2E78FEE0008CDB25 /* SessionStatusLiveExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = SessionStatusLiveExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
D2FE948C2E78FEE0008CDB25 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
@@ -56,12 +56,12 @@
/* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
D28C3C8B2E75111D00F7AEE9 /* Exceptions for "OpenClimb" folder in "OpenClimb" target */ = {
D28C3C8B2E75111D00F7AEE9 /* Exceptions for "Ascently" folder in "Ascently" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
Info.plist,
);
target = D24C19672E75002A0045894C /* OpenClimb */;
target = D24C19672E75002A0045894C /* Ascently */;
};
D2FE94A42E78FEE1008CDB25 /* Exceptions for "SessionStatusLive" folder in "SessionStatusLiveExtension" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
@@ -73,17 +73,17 @@
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
/* Begin PBXFileSystemSynchronizedRootGroup section */
D24C196A2E75002A0045894C /* OpenClimb */ = {
D24C196A2E75002A0045894C /* Ascently */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
D28C3C8B2E75111D00F7AEE9 /* Exceptions for "OpenClimb" folder in "OpenClimb" target */,
D28C3C8B2E75111D00F7AEE9 /* Exceptions for "Ascently" folder in "Ascently" target */,
);
path = OpenClimb;
path = Ascently;
sourceTree = "<group>";
};
D2F32FAE2E90B26500B1BC56 /* OpenClimbTests */ = {
D2F32FAE2E90B26500B1BC56 /* AscentlyTests */ = {
isa = PBXFileSystemSynchronizedRootGroup;
path = OpenClimbTests;
path = AscentlyTests;
sourceTree = "<group>";
};
D2FE94902E78FEE0008CDB25 /* SessionStatusLive */ = {
@@ -129,9 +129,9 @@
isa = PBXGroup;
children = (
D268B79E2E83894A003AA641 /* SessionStatusLiveExtension.entitlements */,
D24C196A2E75002A0045894C /* OpenClimb */,
D24C196A2E75002A0045894C /* Ascently */,
D2FE94902E78FEE0008CDB25 /* SessionStatusLive */,
D2F32FAE2E90B26500B1BC56 /* OpenClimbTests */,
D2F32FAE2E90B26500B1BC56 /* AscentlyTests */,
D2FE947F2E78E958008CDB25 /* Frameworks */,
D24C19692E75002A0045894C /* Products */,
);
@@ -140,9 +140,9 @@
D24C19692E75002A0045894C /* Products */ = {
isa = PBXGroup;
children = (
D24C19682E75002A0045894C /* OpenClimb.app */,
D24C19682E75002A0045894C /* Ascently.app */,
D2FE948B2E78FEE0008CDB25 /* SessionStatusLiveExtension.appex */,
D2F32FAD2E90B26500B1BC56 /* OpenClimbTests.xctest */,
D2F32FAD2E90B26500B1BC56 /* AscentlyTests.xctest */,
);
name = Products;
sourceTree = "<group>";
@@ -160,9 +160,9 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
D24C19672E75002A0045894C /* OpenClimb */ = {
D24C19672E75002A0045894C /* Ascently */ = {
isa = PBXNativeTarget;
buildConfigurationList = D24C19732E75002A0045894C /* Build configuration list for PBXNativeTarget "OpenClimb" */;
buildConfigurationList = D24C19732E75002A0045894C /* Build configuration list for PBXNativeTarget "Ascently" */;
buildPhases = (
D24C19642E75002A0045894C /* Sources */,
D24C19652E75002A0045894C /* Frameworks */,
@@ -175,18 +175,18 @@
D2FE949F2E78FEE1008CDB25 /* PBXTargetDependency */,
);
fileSystemSynchronizedGroups = (
D24C196A2E75002A0045894C /* OpenClimb */,
D24C196A2E75002A0045894C /* Ascently */,
);
name = OpenClimb;
name = Ascently;
packageProductDependencies = (
);
productName = OpenClimb;
productReference = D24C19682E75002A0045894C /* OpenClimb.app */;
productName = Ascently;
productReference = D24C19682E75002A0045894C /* Ascently.app */;
productType = "com.apple.product-type.application";
};
D2F32FAC2E90B26500B1BC56 /* OpenClimbTests */ = {
D2F32FAC2E90B26500B1BC56 /* AscentlyTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = D2F32FB52E90B26500B1BC56 /* Build configuration list for PBXNativeTarget "OpenClimbTests" */;
buildConfigurationList = D2F32FB52E90B26500B1BC56 /* Build configuration list for PBXNativeTarget "AscentlyTests" */;
buildPhases = (
D2F32FA92E90B26500B1BC56 /* Sources */,
D2F32FAA2E90B26500B1BC56 /* Frameworks */,
@@ -198,13 +198,13 @@
D2F32FB22E90B26500B1BC56 /* PBXTargetDependency */,
);
fileSystemSynchronizedGroups = (
D2F32FAE2E90B26500B1BC56 /* OpenClimbTests */,
D2F32FAE2E90B26500B1BC56 /* AscentlyTests */,
);
name = OpenClimbTests;
name = AscentlyTests;
packageProductDependencies = (
);
productName = OpenClimbTests;
productReference = D2F32FAD2E90B26500B1BC56 /* OpenClimbTests.xctest */;
productName = AscentlyTests;
productReference = D2F32FAD2E90B26500B1BC56 /* AscentlyTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
D2FE948A2E78FEE0008CDB25 /* SessionStatusLiveExtension */ = {
@@ -251,7 +251,7 @@
};
};
};
buildConfigurationList = D24C19632E75002A0045894C /* Build configuration list for PBXProject "OpenClimb" */;
buildConfigurationList = D24C19632E75002A0045894C /* Build configuration list for PBXProject "Ascently" */;
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
@@ -265,9 +265,9 @@
projectDirPath = "";
projectRoot = "";
targets = (
D24C19672E75002A0045894C /* OpenClimb */,
D24C19672E75002A0045894C /* Ascently */,
D2FE948A2E78FEE0008CDB25 /* SessionStatusLiveExtension */,
D2F32FAC2E90B26500B1BC56 /* OpenClimbTests */,
D2F32FAC2E90B26500B1BC56 /* AscentlyTests */,
);
};
/* End PBXProject section */
@@ -323,7 +323,7 @@
/* Begin PBXTargetDependency section */
D2F32FB22E90B26500B1BC56 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = D24C19672E75002A0045894C /* OpenClimb */;
target = D24C19672E75002A0045894C /* Ascently */;
targetProxy = D2F32FB12E90B26500B1BC56 /* PBXContainerItemProxy */;
};
D2FE949F2E78FEE1008CDB25 /* PBXTargetDependency */ = {
@@ -462,7 +462,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = OpenClimb/OpenClimb.entitlements;
CODE_SIGN_ENTITLEMENTS = Ascently/Ascently.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 25;
@@ -470,12 +470,12 @@
DRIVERKIT_DEPLOYMENT_TARGET = 24.6;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = OpenClimb/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = OpenClimb;
INFOPLIST_FILE = Ascently/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Ascently;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.sports";
INFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES;
INFOPLIST_KEY_NSCameraUsageDescription = "OpenClimb needs camera access to take photos of climbing problems.";
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "OpenClimb needs access to your photo library to save and display climbing problem images.";
INFOPLIST_KEY_NSCameraUsageDescription = "Ascently needs camera access to take photos of climbing problems.";
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Ascently needs access to your photo library to save and display climbing problem images.";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
@@ -487,8 +487,8 @@
"@executable_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 15.6;
MARKETING_VERSION = 1.4.0;
PRODUCT_BUNDLE_IDENTIFIER = com.atridad.OpenClimb;
MARKETING_VERSION = 2.0.0;
PRODUCT_BUNDLE_IDENTIFIER = com.atridad.Ascently;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
STRING_CATALOG_GENERATE_SYMBOLS = YES;
@@ -510,7 +510,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = OpenClimb/OpenClimb.entitlements;
CODE_SIGN_ENTITLEMENTS = Ascently/Ascently.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 25;
@@ -518,12 +518,12 @@
DRIVERKIT_DEPLOYMENT_TARGET = 24.6;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = OpenClimb/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = OpenClimb;
INFOPLIST_FILE = Ascently/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Ascently;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.sports";
INFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES;
INFOPLIST_KEY_NSCameraUsageDescription = "OpenClimb needs camera access to take photos of climbing problems.";
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "OpenClimb needs access to your photo library to save and display climbing problem images.";
INFOPLIST_KEY_NSCameraUsageDescription = "Ascently needs camera access to take photos of climbing problems.";
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Ascently needs access to your photo library to save and display climbing problem images.";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
@@ -535,8 +535,8 @@
"@executable_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 15.6;
MARKETING_VERSION = 1.4.0;
PRODUCT_BUNDLE_IDENTIFIER = com.atridad.OpenClimb;
MARKETING_VERSION = 2.0.0;
PRODUCT_BUNDLE_IDENTIFIER = com.atridad.Ascently;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
STRING_CATALOG_GENERATE_SYMBOLS = YES;
@@ -562,7 +562,7 @@
DEVELOPMENT_TEAM = 4BC9Y2LL4B;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.atri.dad.OpenClimb.Watch.OpenClimbTests;
PRODUCT_BUNDLE_IDENTIFIER = com.atri.dad.OpenClimb.Watch.AscentlyTests;
PRODUCT_NAME = "$(TARGET_NAME)";
STRING_CATALOG_GENERATE_SYMBOLS = NO;
SWIFT_APPROACHABLE_CONCURRENCY = YES;
@@ -570,7 +570,7 @@
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/OpenClimb.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/OpenClimb";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Ascently.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/OpenClimb";
};
name = Debug;
};
@@ -583,7 +583,7 @@
DEVELOPMENT_TEAM = 4BC9Y2LL4B;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.atri.dad.OpenClimb.Watch.OpenClimbTests;
PRODUCT_BUNDLE_IDENTIFIER = com.atri.dad.OpenClimb.Watch.AscentlyTests;
PRODUCT_NAME = "$(TARGET_NAME)";
STRING_CATALOG_GENERATE_SYMBOLS = NO;
SWIFT_APPROACHABLE_CONCURRENCY = YES;
@@ -591,7 +591,7 @@
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/OpenClimb.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/OpenClimb";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Ascently.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/OpenClimb";
};
name = Release;
};
@@ -602,7 +602,7 @@
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CODE_SIGN_ENTITLEMENTS = SessionStatusLiveExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 25;
CURRENT_PROJECT_VERSION = 26;
DEVELOPMENT_TEAM = 4BC9Y2LL4B;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = SessionStatusLive/Info.plist;
@@ -613,8 +613,8 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.4.0;
PRODUCT_BUNDLE_IDENTIFIER = com.atridad.OpenClimb.SessionStatusLive;
MARKETING_VERSION = 2.0.0;
PRODUCT_BUNDLE_IDENTIFIER = com.atridad.Ascently.SessionStatusLive;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
@@ -632,7 +632,7 @@
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CODE_SIGN_ENTITLEMENTS = SessionStatusLiveExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 25;
CURRENT_PROJECT_VERSION = 26;
DEVELOPMENT_TEAM = 4BC9Y2LL4B;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = SessionStatusLive/Info.plist;
@@ -643,8 +643,8 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.4.0;
PRODUCT_BUNDLE_IDENTIFIER = com.atridad.OpenClimb.SessionStatusLive;
MARKETING_VERSION = 2.0.0;
PRODUCT_BUNDLE_IDENTIFIER = com.atridad.Ascently.SessionStatusLive;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
@@ -658,7 +658,7 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
D24C19632E75002A0045894C /* Build configuration list for PBXProject "OpenClimb" */ = {
D24C19632E75002A0045894C /* Build configuration list for PBXProject "Ascently" */ = {
isa = XCConfigurationList;
buildConfigurations = (
D24C19712E75002A0045894C /* Debug */,
@@ -667,7 +667,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
D24C19732E75002A0045894C /* Build configuration list for PBXNativeTarget "OpenClimb" */ = {
D24C19732E75002A0045894C /* Build configuration list for PBXNativeTarget "Ascently" */ = {
isa = XCConfigurationList;
buildConfigurations = (
D24C19742E75002A0045894C /* Debug */,
@@ -676,7 +676,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
D2F32FB52E90B26500B1BC56 /* Build configuration list for PBXNativeTarget "OpenClimbTests" */ = {
D2F32FB52E90B26500B1BC56 /* Build configuration list for PBXNativeTarget "AscentlyTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
D2F32FB32E90B26500B1BC56 /* Debug */,

View File

@@ -15,9 +15,9 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D24C19672E75002A0045894C"
BuildableName = "OpenClimb.app"
BlueprintName = "OpenClimb"
ReferencedContainer = "container:OpenClimb.xcodeproj">
BuildableName = "Ascently.app"
BlueprintName = "Ascently"
ReferencedContainer = "container:Ascently.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
@@ -34,9 +34,9 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D2F32FAC2E90B26500B1BC56"
BuildableName = "OpenClimbTests.xctest"
BlueprintName = "OpenClimbTests"
ReferencedContainer = "container:OpenClimb.xcodeproj">
BuildableName = "AscentlyTests.xctest"
BlueprintName = "AscentlyTests"
ReferencedContainer = "container:Ascently.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
@@ -56,9 +56,9 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D24C19672E75002A0045894C"
BuildableName = "OpenClimb.app"
BlueprintName = "OpenClimb"
ReferencedContainer = "container:OpenClimb.xcodeproj">
BuildableName = "Ascently.app"
BlueprintName = "Ascently"
ReferencedContainer = "container:Ascently.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
@@ -73,9 +73,9 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D24C19672E75002A0045894C"
BuildableName = "OpenClimb.app"
BlueprintName = "OpenClimb"
ReferencedContainer = "container:OpenClimb.xcodeproj">
BuildableName = "Ascently.app"
BlueprintName = "Ascently"
ReferencedContainer = "container:Ascently.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>

View File

@@ -19,7 +19,7 @@
BlueprintIdentifier = "D2FE948A2E78FEE0008CDB25"
BuildableName = "SessionStatusLiveExtension.appex"
BlueprintName = "SessionStatusLiveExtension"
ReferencedContainer = "container:OpenClimb.xcodeproj">
ReferencedContainer = "container:Ascently.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
@@ -31,9 +31,9 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D24C19672E75002A0045894C"
BuildableName = "OpenClimb.app"
BlueprintName = "OpenClimb"
ReferencedContainer = "container:OpenClimb.xcodeproj">
BuildableName = "Ascently.app"
BlueprintName = "Ascently"
ReferencedContainer = "container:Ascently.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
@@ -51,9 +51,9 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D2F32FAC2E90B26500B1BC56"
BuildableName = "OpenClimbTests.xctest"
BlueprintName = "OpenClimbTests"
ReferencedContainer = "container:OpenClimb.xcodeproj">
BuildableName = "AscentlyTests.xctest"
BlueprintName = "AscentlyTests"
ReferencedContainer = "container:Ascently.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
@@ -75,9 +75,9 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D24C19672E75002A0045894C"
BuildableName = "OpenClimb.app"
BlueprintName = "OpenClimb"
ReferencedContainer = "container:OpenClimb.xcodeproj">
BuildableName = "Ascently.app"
BlueprintName = "Ascently"
ReferencedContainer = "container:Ascently.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<EnvironmentVariables>
@@ -111,9 +111,9 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D24C19672E75002A0045894C"
BuildableName = "OpenClimb.app"
BlueprintName = "OpenClimb"
ReferencedContainer = "container:OpenClimb.xcodeproj">
BuildableName = "Ascently.app"
BlueprintName = "Ascently"
ReferencedContainer = "container:Ascently.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>

View File

@@ -4,7 +4,12 @@
<dict>
<key>SchemeUserState</key>
<dict>
<key>OpenClimb.xcscheme_^#shared#^_</key>
<key>AscentlyTests.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
</dict>
<key>Ascently.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>1</integer>

View File

@@ -4,7 +4,7 @@
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.atridad.OpenClimb</string>
<string>group.com.atridad.Ascently</string>
</array>
<key>com.apple.developer.healthkit</key>
<true/>

View File

@@ -1,8 +1,7 @@
import SwiftUI
@main
struct OpenClimbApp: App {
struct AscentlyApp: App {
var body: some Scene {
WindowGroup {
ContentView()

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -5,7 +5,7 @@ import Foundation
// MARK: - Backup Format Specification v2.0
/// Root structure for OpenClimb backup data
/// Root structure for Ascently backup data
struct DeletedItem: Codable, Hashable {
let id: String
let type: String // "gym", "problem", "session", "attempt"

View File

@@ -501,7 +501,7 @@ class SyncService: ObservableObject {
// Update local deletions with merged list
dataManager.clearDeletedItems()
if let data = try? JSONEncoder().encode(uniqueDeletions) {
UserDefaults.standard.set(data, forKey: "openclimb_deleted_items")
UserDefaults.standard.set(data, forKey: "ascently_deleted_items")
}
// Upload merged data back to server
@@ -648,7 +648,7 @@ class SyncService: ObservableObject {
// Import deletion records to prevent future resurrections
dataManager.clearDeletedItems()
if let data = try? JSONEncoder().encode(backup.deletedItems) {
UserDefaults.standard.set(data, forKey: "openclimb_deleted_items")
UserDefaults.standard.set(data, forKey: "ascently_deleted_items")
print("iOS IMPORT: Imported \(backup.deletedItems.count) deletion records")
}

View File

@@ -9,8 +9,8 @@ class DataStateManager {
private let userDefaults = UserDefaults.standard
private enum Keys {
static let lastModified = "openclimb_data_last_modified"
static let initialized = "openclimb_data_state_initialized"
static let lastModified = "ascently_data_last_modified"
static let initialized = "ascently_data_state_initialized"
}
static let shared = DataStateManager()

View File

@@ -8,13 +8,17 @@ class ImageManager {
private let thumbnailCache = NSCache<NSString, UIImage>()
private let fileManager = FileManager.default
private let appSupportDirectoryName = "OpenClimb"
private let appSupportDirectoryName = "Ascently"
private let imagesDirectoryName = "Images"
private let backupDirectoryName = "ImageBackups"
private let migrationStateFile = "migration_state.json"
private let migrationLockFile = "migration.lock"
// Legacy directory name for migration
private let legacyAppSupportDirectoryName = "OpenClimb"
private init() {
migrateFromOpenClimbDirectoryIfNeeded()
createDirectoriesIfNeeded()
// Debug-safe initialization with extra checks
@@ -58,6 +62,52 @@ class ImageManager {
legacyDocumentsDirectory.appendingPathComponent("OpenClimbImages")
}
/// Legacy OpenClimb app support directory for migration
private var legacyOpenClimbAppSupportDirectory: URL? {
guard
let appSupportBase = fileManager.urls(
for: .applicationSupportDirectory, in: .userDomainMask
).first
else {
return nil
}
return appSupportBase.appendingPathComponent(legacyAppSupportDirectoryName)
}
/// Migrate images from OpenClimb directory to Ascently directory
private func migrateFromOpenClimbDirectoryIfNeeded() {
guard let legacyDir = legacyOpenClimbAppSupportDirectory,
fileManager.fileExists(atPath: legacyDir.path),
!fileManager.fileExists(atPath: appSupportDirectory.path)
else {
return
}
print("🔄 Migrating images from OpenClimb to Ascently directory...")
do {
// Create parent directory if needed
try fileManager.createDirectory(
at: appSupportDirectory.deletingLastPathComponent(),
withIntermediateDirectories: true,
attributes: nil)
// Move the entire directory
try fileManager.moveItem(at: legacyDir, to: appSupportDirectory)
print("Successfully migrated image directory from OpenClimb to Ascently")
} catch {
print("❌ Failed to migrate image directory: \(error)")
// If move fails, try to copy instead
do {
try fileManager.copyItem(at: legacyDir, to: appSupportDirectory)
print("Successfully copied image directory from OpenClimb to Ascently")
// Don't remove the old directory in case of issues
} catch {
print("❌ Failed to copy image directory: \(error)")
}
}
}
var legacyImportImagesDirectory: URL {
legacyDocumentsDirectory.appendingPathComponent("images")
}
@@ -671,7 +721,7 @@ class ImageManager {
let previousDir = findPreviousAppSupportImages()
print(
"""
OpenClimb Image Storage:
Ascently Image Storage:
- App Support: \(appSupportDirectory.path)
- Images: \(imagesDirectory.path) (\(info.primaryCount) files)
- Backups: \(backupDirectory.path) (\(info.backupCount) files)
@@ -842,8 +892,9 @@ class ImageManager {
continue
}
// Check if it's an OpenClimb directory but not the current one
if url.lastPathComponent.contains("OpenClimb")
// Check if it's an OpenClimb or Ascently directory but not the current one
if (url.lastPathComponent.contains("OpenClimb")
|| url.lastPathComponent.contains("Ascently"))
&& url.path != appSupportDirectory.path
{
let imagesDir = url.appendingPathComponent(imagesDirectoryName)

View File

@@ -199,8 +199,8 @@ struct ZipUtils {
referencedImagePaths: Set<String>
) -> String {
return """
OpenClimb Export Metadata
=======================
Ascently Export Metadata
========================
Export Date: \(exportData.exportedAt)
Gyms: \(exportData.gyms.count)
Problems: \(exportData.problems.count)

View File

@@ -25,9 +25,12 @@ class ClimbingDataManager: ObservableObject {
@Published var successMessage: String?
private let userDefaults = UserDefaults.standard
private let sharedUserDefaults = UserDefaults(suiteName: "group.com.atridad.OpenClimb")
private let sharedUserDefaults = UserDefaults(suiteName: "group.com.atridad.Ascently")
private let encoder = JSONEncoder()
private let decoder = JSONDecoder()
// Flag to track if migration has been performed
private let migrationKey = "ascently_data_migrated_from_openclimb"
nonisolated(unsafe) private var liveActivityObserver: NSObjectProtocol?
nonisolated(unsafe) private var migrationObserver: NSObjectProtocol?
@@ -37,6 +40,16 @@ class ClimbingDataManager: ObservableObject {
@Published var isSyncing = false
private enum Keys {
static let gyms = "ascently_gyms"
static let problems = "ascently_problems"
static let sessions = "ascently_sessions"
static let attempts = "ascently_attempts"
static let activeSession = "ascently_active_session"
static let deletedItems = "ascently_deleted_items"
}
// Legacy keys for migration
private enum LegacyKeys {
static let gyms = "openclimb_gyms"
static let problems = "openclimb_problems"
static let sessions = "openclimb_sessions"
@@ -68,6 +81,7 @@ class ClimbingDataManager: ObservableObject {
init() {
_ = ImageManager.shared
migrateFromOpenClimbIfNeeded()
loadAllData()
setupLiveActivityNotifications()
setupMigrationNotifications()
@@ -94,6 +108,74 @@ class ClimbingDataManager: ObservableObject {
}
}
/// Migrate data from OpenClimb keys to Ascently keys
private func migrateFromOpenClimbIfNeeded() {
// Check if migration has already been performed
if userDefaults.bool(forKey: migrationKey) {
return
}
print("Starting migration from OpenClimb to Ascently keys...")
var migrationCount = 0
// Migrate each data type if it exists in old format but not in new format
let migrations = [
(LegacyKeys.gyms, Keys.gyms),
(LegacyKeys.problems, Keys.problems),
(LegacyKeys.sessions, Keys.sessions),
(LegacyKeys.attempts, Keys.attempts),
(LegacyKeys.activeSession, Keys.activeSession),
(LegacyKeys.deletedItems, Keys.deletedItems),
]
for (oldKey, newKey) in migrations {
if let oldData = userDefaults.data(forKey: oldKey),
userDefaults.data(forKey: newKey) == nil
{
userDefaults.set(oldData, forKey: newKey)
userDefaults.removeObject(forKey: oldKey)
migrationCount += 1
print("✅ Migrated: \(oldKey)\(newKey)")
}
}
// Also migrate shared UserDefaults for widgets
if let sharedDefaults = sharedUserDefaults {
for (oldKey, newKey) in migrations {
if let oldData = sharedDefaults.data(forKey: oldKey),
sharedDefaults.data(forKey: newKey) == nil
{
sharedDefaults.set(oldData, forKey: newKey)
sharedDefaults.removeObject(forKey: oldKey)
print("✅ Migrated shared: \(oldKey)\(newKey)")
}
}
}
// Migrate DataStateManager keys
let legacyDataStateKey = "openclimb_data_last_modified"
let newDataStateKey = "ascently_data_last_modified"
if let lastModified = userDefaults.string(forKey: legacyDataStateKey),
userDefaults.string(forKey: newDataStateKey) == nil
{
userDefaults.set(lastModified, forKey: newDataStateKey)
userDefaults.removeObject(forKey: legacyDataStateKey)
migrationCount += 1
print("✅ Migrated data state timestamp")
}
// Mark migration as completed
userDefaults.set(true, forKey: migrationKey)
if migrationCount > 0 {
print(
"Migration completed! Migrated \(migrationCount) data items from OpenClimb to Ascently"
)
} else {
print("No OpenClimb data found to migrate")
}
}
private func loadAllData() {
loadGyms()
loadProblems()

View File

@@ -263,7 +263,7 @@ struct AppInfoSection: View {
.resizable()
.frame(width: 24, height: 24)
VStack(alignment: .leading) {
Text("OpenClimb")
Text("Ascently")
.font(.headline)
Text("Track your climbing progress")
.font(.caption)
@@ -332,7 +332,7 @@ struct ExportDataView: View {
ShareLink(
item: fileURL,
preview: SharePreview(
"OpenClimb Data Export",
"Ascently Data Export",
image: Image("AppLogo"))
) {
Label("Share Data", systemImage: "square.and.arrow.up")
@@ -385,7 +385,7 @@ struct ExportDataView: View {
let isoString = formatter.string(from: Date())
let timestamp = isoString.replacingOccurrences(of: ":", with: "-")
.replacingOccurrences(of: ".", with: "-")
let filename = "openclimb_export_\(timestamp).zip"
let filename = "ascently_export_\(timestamp).zip"
guard
let documentsURL = FileManager.default.urls(

View File

@@ -1,6 +1,6 @@
import XCTest
final class OpenClimbTests: XCTestCase {
final class AscentlyTests: XCTestCase {
override func setUpWithError() throws {
}

View File

@@ -1,10 +1,10 @@
# OpenClimb for iOS
# Ascently for iOS
The native iOS, watchOS, and widget client for OpenClimb, built with Swift and SwiftUI.
The native iOS, watchOS, and widget client for Ascently, built with Swift and SwiftUI.
## Project Structure
This is a standard Xcode project. The main app code is in the `OpenClimb/` directory.
This is a standard Xcode project. The main app code is in the `Ascently/` directory.
- `Models/`: Swift `Codable` models (`Problem`, `Gym`, `ClimbSession`) that match the Android app.
- `ViewModels/`: App state and logic. `ClimbingDataManager` is the core here, handling data with SwiftData.
@@ -16,8 +16,7 @@ This is a standard Xcode project. The main app code is in the `OpenClimb/` direc
## Other Targets
- `OpenClimbWatch/`: The watchOS app for tracking sessions.
- `ClimbingActivityWidget/`: A home screen widget.
- `SessionStatusLive/`: A Live Activity for the lock screen.
The app is built to be offline-first. All data is stored locally on your device and works without an internet connection.
The app is built to be offline-first. All data is stored locally on your device and works without an internet connection.

View File

@@ -49,10 +49,10 @@ struct ClimbingStatsProvider: TimelineProvider {
}
private func loadClimbingStats() -> ClimbingStats {
let userDefaults = UserDefaults(suiteName: "group.com.atridad.OpenClimb")
let userDefaults = UserDefaults(suiteName: "group.com.atridad.Ascently")
// Load attempts from UserDefaults
guard let attemptsData = userDefaults?.data(forKey: "openclimb_attempts"),
guard let attemptsData = userDefaults?.data(forKey: "ascently_attempts"),
let attempts = try? JSONDecoder().decode([WidgetAttempt].self, from: attemptsData)
else {
return ClimbingStats(
@@ -60,11 +60,11 @@ struct ClimbingStatsProvider: TimelineProvider {
}
// Load sessions for streak calculation
let sessionsData = (userDefaults?.data(forKey: "openclimb_sessions"))!
let sessionsData = (userDefaults?.data(forKey: "ascently_sessions"))!
let sessions = (try? JSONDecoder().decode([WidgetSession].self, from: sessionsData)) ?? []
// Load gyms for favorite gym name
let gymsData = (userDefaults?.data(forKey: "openclimb_gyms"))!
let gymsData = (userDefaults?.data(forKey: "ascently_gyms"))!
let gyms = (try? JSONDecoder().decode([WidgetGym].self, from: gymsData)) ?? []
let calendar = Calendar.current

View File

@@ -6,7 +6,7 @@ import SwiftUI
import WidgetKit
struct SessionStatusLiveControl: ControlWidget {
static let kind: String = "com.atridad.OpenClimb.SessionStatusLive"
static let kind: String = "com.atridad.Ascently.SessionStatusLive"
var body: some ControlWidgetConfiguration {
AppIntentControlConfiguration(

View File

@@ -4,7 +4,7 @@
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.atridad.OpenClimb</string>
<string>group.com.atridad.Ascently</string>
</array>
</dict>
</plist>