[iOS & Android] iOS 1.2.3 and Android 1.7.2
All checks were successful
OpenClimb Docker Deploy / build-and-push (push) Successful in 2m32s

This commit is contained in:
2025-10-05 23:47:48 -06:00
parent cb20efd58d
commit 3b6c3b5ca2
17 changed files with 302 additions and 125 deletions

View File

@@ -465,7 +465,7 @@
CODE_SIGN_ENTITLEMENTS = OpenClimb/OpenClimb.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 13;
CURRENT_PROJECT_VERSION = 14;
DEVELOPMENT_TEAM = 4BC9Y2LL4B;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
@@ -485,7 +485,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.2.2;
MARKETING_VERSION = 1.2.3;
PRODUCT_BUNDLE_IDENTIFIER = com.atridad.OpenClimb;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -508,7 +508,7 @@
CODE_SIGN_ENTITLEMENTS = OpenClimb/OpenClimb.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 13;
CURRENT_PROJECT_VERSION = 14;
DEVELOPMENT_TEAM = 4BC9Y2LL4B;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
@@ -528,7 +528,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.2.2;
MARKETING_VERSION = 1.2.3;
PRODUCT_BUNDLE_IDENTIFIER = com.atridad.OpenClimb;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -592,7 +592,7 @@
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CODE_SIGN_ENTITLEMENTS = SessionStatusLiveExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 13;
CURRENT_PROJECT_VERSION = 14;
DEVELOPMENT_TEAM = 4BC9Y2LL4B;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = SessionStatusLive/Info.plist;
@@ -603,7 +603,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.2.2;
MARKETING_VERSION = 1.2.3;
PRODUCT_BUNDLE_IDENTIFIER = com.atridad.OpenClimb.SessionStatusLive;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@@ -622,7 +622,7 @@
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CODE_SIGN_ENTITLEMENTS = SessionStatusLiveExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 13;
CURRENT_PROJECT_VERSION = 14;
DEVELOPMENT_TEAM = 4BC9Y2LL4B;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = SessionStatusLive/Info.plist;
@@ -633,7 +633,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.2.2;
MARKETING_VERSION = 1.2.3;
PRODUCT_BUNDLE_IDENTIFIER = com.atridad.OpenClimb.SessionStatusLive;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;

View File

@@ -336,6 +336,7 @@ struct BackupAttempt: Codable {
let restTime: Int64? // Rest time in seconds
let timestamp: String
let createdAt: String
let updatedAt: String?
/// Initialize from native iOS Attempt model
init(from attempt: Attempt) {
@@ -352,6 +353,7 @@ struct BackupAttempt: Codable {
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
self.timestamp = formatter.string(from: attempt.timestamp)
self.createdAt = formatter.string(from: attempt.createdAt)
self.updatedAt = formatter.string(from: attempt.updatedAt)
}
/// Initialize with explicit parameters for import
@@ -365,7 +367,8 @@ struct BackupAttempt: Codable {
duration: Int64?,
restTime: Int64?,
timestamp: String,
createdAt: String
createdAt: String,
updatedAt: String?
) {
self.id = id
self.sessionId = sessionId
@@ -377,6 +380,7 @@ struct BackupAttempt: Codable {
self.restTime = restTime
self.timestamp = timestamp
self.createdAt = createdAt
self.updatedAt = updatedAt
}
/// Convert to native iOS Attempt model
@@ -385,13 +389,15 @@ struct BackupAttempt: Codable {
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
guard let uuid = UUID(uuidString: id),
let sessionUuid = UUID(uuidString: sessionId),
let problemUuid = UUID(uuidString: problemId),
let timestampDate = formatter.date(from: timestamp),
let createdDate = formatter.date(from: createdAt)
let sessionUuid = UUID(uuidString: sessionId),
let problemUuid = UUID(uuidString: problemId),
let timestampDate = formatter.date(from: timestamp),
let createdDate = formatter.date(from: createdAt)
else {
throw BackupError.invalidDateFormat
}
let updatedDateParsed = updatedAt.flatMap { formatter.date(from: $0) }
let updatedDate = updatedDateParsed ?? createdDate
let durationValue = duration.map { Int($0) }
let restTimeValue = restTime.map { Int($0) }
@@ -406,7 +412,8 @@ struct BackupAttempt: Codable {
duration: durationValue,
restTime: restTimeValue,
timestamp: timestampDate,
createdAt: createdDate
createdAt: createdDate,
updatedAt: updatedDate
)
}
}

View File

@@ -474,11 +474,13 @@ struct Attempt: Identifiable, Codable, Hashable {
let restTime: Int?
let timestamp: Date
let createdAt: Date
let updatedAt: Date
init(
sessionId: UUID, problemId: UUID, result: AttemptResult, highestHold: String? = nil,
notes: String? = nil, duration: Int? = nil, restTime: Int? = nil, timestamp: Date = Date()
) {
let now = Date()
self.id = UUID()
self.sessionId = sessionId
self.problemId = problemId
@@ -488,7 +490,8 @@ struct Attempt: Identifiable, Codable, Hashable {
self.duration = duration
self.restTime = restTime
self.timestamp = timestamp
self.createdAt = Date()
self.createdAt = now
self.updatedAt = now
}
func updated(
@@ -506,13 +509,15 @@ struct Attempt: Identifiable, Codable, Hashable {
duration: duration ?? self.duration,
restTime: restTime ?? self.restTime,
timestamp: self.timestamp,
createdAt: self.createdAt
createdAt: self.createdAt,
updatedAt: Date()
)
}
private init(
id: UUID, sessionId: UUID, problemId: UUID, result: AttemptResult, highestHold: String?,
notes: String?, duration: Int?, restTime: Int?, timestamp: Date, createdAt: Date
notes: String?, duration: Int?, restTime: Int?, timestamp: Date, createdAt: Date,
updatedAt: Date
) {
self.id = id
self.sessionId = sessionId
@@ -524,11 +529,13 @@ struct Attempt: Identifiable, Codable, Hashable {
self.restTime = restTime
self.timestamp = timestamp
self.createdAt = createdAt
self.updatedAt = updatedAt
}
static func fromImport(
id: UUID, sessionId: UUID, problemId: UUID, result: AttemptResult, highestHold: String?,
notes: String?, duration: Int?, restTime: Int?, timestamp: Date, createdAt: Date
notes: String?, duration: Int?, restTime: Int?, timestamp: Date, createdAt: Date,
updatedAt: Date
) -> Attempt {
return Attempt(
id: id,
@@ -540,7 +547,8 @@ struct Attempt: Identifiable, Codable, Hashable {
duration: duration,
restTime: restTime,
timestamp: timestamp,
createdAt: createdAt
createdAt: createdAt,
updatedAt: updatedAt
)
}
}