From acb1b1f5321bffbd03a992fd65f72499c0899bf7 Mon Sep 17 00:00:00 2001 From: Atridad Lahiji Date: Tue, 2 Dec 2025 17:07:52 -0700 Subject: [PATCH] 2.4.0 - Updated Sync Architecture (Provider pattern) --- .../UserInterfaceState.xcuserstate | Bin 277975 -> 284309 bytes .../Services/Sync/ServerSyncProvider.swift | 1188 +++++++++++++ ios/Ascently/Services/Sync/SyncMerger.swift | 181 ++ ios/Ascently/Services/Sync/SyncProvider.swift | 73 + ios/Ascently/Services/SyncService.swift | 1489 +---------------- ios/Ascently/Views/SettingsView.swift | 13 + 6 files changed, 1531 insertions(+), 1413 deletions(-) create mode 100644 ios/Ascently/Services/Sync/ServerSyncProvider.swift create mode 100644 ios/Ascently/Services/Sync/SyncMerger.swift create mode 100644 ios/Ascently/Services/Sync/SyncProvider.swift diff --git a/ios/Ascently.xcodeproj/project.xcworkspace/xcuserdata/atridad.xcuserdatad/UserInterfaceState.xcuserstate b/ios/Ascently.xcodeproj/project.xcworkspace/xcuserdata/atridad.xcuserdatad/UserInterfaceState.xcuserstate index cb5508f0b2127eeb5804ecb9610a7202306e3fc6..e4345f61bd45de507ba30a6f21b09c135c9093af 100644 GIT binary patch literal 284309 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

0k#guffTv#N4%(A)ag$)S86zCbZ` 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

LFLM+EvSQBD7!9pe^ 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 literal 277975 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�rXse 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 sAZ&0>gZdjLpk}{sGi;cNJsQ08hNZ#({|t ClimbDataBackup { + guard let url = URL(string: "\(serverURL)/sync") else { + throw SyncError.invalidURL + } + + var request = URLRequest(url: url) + request.httpMethod = "GET" + request.setValue("Bearer \(authToken)", forHTTPHeaderField: "Authorization") + request.setValue("application/json", forHTTPHeaderField: "Accept") + + let (data, response) = try await URLSession.shared.data(for: request) + + guard let httpResponse = response as? HTTPURLResponse else { + throw SyncError.invalidResponse + } + + switch httpResponse.statusCode { + case 200: + break + case 401: + throw SyncError.unauthorized + default: + throw SyncError.serverError(httpResponse.statusCode) + } + + do { + let backup = try JSONDecoder().decode(ClimbDataBackup.self, from: data) + return backup + } catch { + throw SyncError.decodingError(error) + } + } + + private func uploadData(_ backup: ClimbDataBackup) async throws -> ClimbDataBackup { + guard let url = URL(string: "\(serverURL)/sync") else { + throw SyncError.invalidURL + } + + let encoder = JSONEncoder() + encoder.dateEncodingStrategy = .iso8601 + + let jsonData = try encoder.encode(backup) + + var request = URLRequest(url: url) + request.httpMethod = "PUT" + request.setValue("Bearer \(authToken)", forHTTPHeaderField: "Authorization") + request.setValue("application/json", forHTTPHeaderField: "Content-Type") + request.setValue("application/json", forHTTPHeaderField: "Accept") + request.httpBody = jsonData + + let (data, response) = try await URLSession.shared.data(for: request) + + guard let httpResponse = response as? HTTPURLResponse else { + throw SyncError.invalidResponse + } + + switch httpResponse.statusCode { + case 200: + break + case 401: + throw SyncError.unauthorized + case 400: + throw SyncError.badRequest + default: + throw SyncError.serverError(httpResponse.statusCode) + } + + do { + let responseBackup = try JSONDecoder().decode(ClimbDataBackup.self, from: data) + return responseBackup + } catch { + throw SyncError.decodingError(error) + } + } + + private func performDeltaSync(dataManager: ClimbingDataManager) async throws { + guard let url = URL(string: "\(serverURL)/sync/delta") else { + throw SyncError.invalidURL + } + + // Get last sync time, or use epoch if never synced + let lastSync = lastSyncTime ?? Date(timeIntervalSince1970: 0) + let formatter = ISO8601DateFormatter() + let lastSyncString = formatter.string(from: lastSync) + + // Collect items modified since last sync + let modifiedGyms = dataManager.gyms.filter { gym in + gym.updatedAt > lastSync + }.map { BackupGym(from: $0) } + + let modifiedProblems = dataManager.problems.filter { problem in + problem.updatedAt > lastSync + }.map { problem -> BackupProblem in + let backupProblem = BackupProblem(from: problem) + if !problem.imagePaths.isEmpty { + let normalizedPaths = problem.imagePaths.enumerated().map { index, _ in + ImageNamingUtils.generateImageFilename( + problemId: problem.id.uuidString, imageIndex: index) + } + return BackupProblem( + id: backupProblem.id, + gymId: backupProblem.gymId, + name: backupProblem.name, + description: backupProblem.description, + climbType: backupProblem.climbType, + difficulty: backupProblem.difficulty, + tags: backupProblem.tags, + location: backupProblem.location, + imagePaths: normalizedPaths, + isActive: backupProblem.isActive, + dateSet: backupProblem.dateSet, + notes: backupProblem.notes, + createdAt: backupProblem.createdAt, + updatedAt: backupProblem.updatedAt + ) + } + return backupProblem + } + + let modifiedSessions = dataManager.sessions.filter { session in + session.status != .active && session.updatedAt > lastSync + }.map { BackupClimbSession(from: $0) } + + let activeSessionIds = Set( + dataManager.sessions.filter { $0.status == .active }.map { $0.id }) + let modifiedAttempts = dataManager.attempts.filter { attempt in + !activeSessionIds.contains(attempt.sessionId) && attempt.createdAt > lastSync + }.map { BackupAttempt(from: $0) } + + let modifiedDeletions = dataManager.getDeletedItems().filter { item in + if let deletedDate = formatter.date(from: item.deletedAt) { + return deletedDate > lastSync + } + return false + } + + AppLogger.info( + "Delta Sync: Sending gyms=\(modifiedGyms.count), problems=\(modifiedProblems.count), sessions=\(modifiedSessions.count), attempts=\(modifiedAttempts.count), deletions=\(modifiedDeletions.count)", + tag: logTag + ) + + // Create delta request + let deltaRequest = DeltaSyncRequest( + lastSyncTime: lastSyncString, + gyms: modifiedGyms, + problems: modifiedProblems, + sessions: modifiedSessions, + attempts: modifiedAttempts, + deletedItems: modifiedDeletions + ) + + let encoder = JSONEncoder() + encoder.dateEncodingStrategy = .iso8601 + let jsonData = try encoder.encode(deltaRequest) + + var request = URLRequest(url: url) + request.httpMethod = "POST" + request.setValue("Bearer \(authToken)", forHTTPHeaderField: "Authorization") + request.setValue("application/json", forHTTPHeaderField: "Content-Type") + request.setValue("application/json", forHTTPHeaderField: "Accept") + request.httpBody = jsonData + + let (data, response) = try await URLSession.shared.data(for: request) + + guard let httpResponse = response as? HTTPURLResponse else { + throw SyncError.invalidResponse + } + + switch httpResponse.statusCode { + case 200: + break + case 401: + throw SyncError.unauthorized + default: + throw SyncError.serverError(httpResponse.statusCode) + } + + let decoder = JSONDecoder() + let deltaResponse = try decoder.decode(DeltaSyncResponse.self, from: data) + + AppLogger.info( + "Delta Sync: Received gyms=\(deltaResponse.gyms.count), problems=\(deltaResponse.problems.count), sessions=\(deltaResponse.sessions.count), attempts=\(deltaResponse.attempts.count), deletions=\(deltaResponse.deletedItems.count)", + tag: logTag + ) + + // Apply server changes to local data + try await applyDeltaResponse(deltaResponse, dataManager: dataManager) + + // Sync only modified problem images + try await syncModifiedImages(modifiedProblems: modifiedProblems, dataManager: dataManager) + + // Update last sync time to server time + if let serverTime = formatter.date(from: deltaResponse.serverTime) { + lastSyncTime = serverTime + } + } + + private func applyDeltaResponse(_ response: DeltaSyncResponse, dataManager: ClimbingDataManager) async throws { + // Use SyncMerger logic but adapted for DeltaSyncResponse + // Since SyncMerger works with ClimbDataBackup, we might need to adapt or just do it here since it's specific to DeltaSync + + // Actually, DeltaSyncResponse is very similar to ClimbDataBackup but with serverTime + // Let's construct a pseudo-backup for merging or just use the logic here since it handles image downloads too + + let formatter = ISO8601DateFormatter() + + // Merge and apply deletions first to prevent resurrection + let allDeletions = dataManager.getDeletedItems() + response.deletedItems + let uniqueDeletions = Array(Set(allDeletions)) + + AppLogger.info( + "Delta Sync: Applying \(uniqueDeletions.count) deletion records before merging data", + tag: logTag + ) + applyDeletionsToDataManager(deletions: uniqueDeletions, dataManager: dataManager) + + // Build deleted item lookup map + let deletedItemSet = Set(uniqueDeletions.map { $0.type + ":" + $0.id }) + + // Download images for new/modified problems from server + var imagePathMapping: [String: String] = [:] + for problem in response.problems { + if deletedItemSet.contains("problem:" + problem.id) { + continue + } + + guard let imagePaths = problem.imagePaths, !imagePaths.isEmpty else { continue } + + for (index, imagePath) in imagePaths.enumerated() { + let serverFilename = URL(fileURLWithPath: imagePath).lastPathComponent + + do { + let imageData = try await downloadImage(filename: serverFilename) + let consistentFilename = ImageNamingUtils.generateImageFilename( + problemId: problem.id, imageIndex: index) + let imageManager = ImageManager.shared + _ = try imageManager.saveImportedImage(imageData, filename: consistentFilename) + imagePathMapping[serverFilename] = consistentFilename + } catch SyncError.imageNotFound { + AppLogger.info("Image not found on server: \(serverFilename)", tag: logTag) + continue + } catch { + AppLogger.info("Failed to download image \(serverFilename): \(error)", tag: logTag) + continue + } + } + } + + // Now we can use SyncMerger logic if we convert response to Backup format + // But SyncMerger.mergeDataSafely does a full merge. Here we are doing delta merge. + // The logic in SyncService.swift for applyDeltaResponse was: + // 1. Download images + // 2. Merge gyms (check timestamps) + // 3. Merge problems (check timestamps) + // ... + + // This logic is slightly different from full merge because it checks timestamps against existing items specifically for delta. + // Full merge also checks timestamps but assumes full dataset. + // Let's keep the logic here for now as it is specific to the Delta Sync protocol. + + // Merge gyms + for backupGym in response.gyms { + if deletedItemSet.contains("gym:" + backupGym.id) { + continue + } + + if let index = dataManager.gyms.firstIndex(where: { $0.id.uuidString == backupGym.id }) + { + let existing = dataManager.gyms[index] + if backupGym.updatedAt >= formatter.string(from: existing.updatedAt) { + dataManager.gyms[index] = try backupGym.toGym() + } + } else { + dataManager.gyms.append(try backupGym.toGym()) + } + } + + // Merge problems + for backupProblem in response.problems { + if deletedItemSet.contains("problem:" + backupProblem.id) { + continue + } + + var problemToMerge = backupProblem + if !imagePathMapping.isEmpty, let imagePaths = backupProblem.imagePaths { + let updatedPaths = imagePaths.compactMap { imagePathMapping[$0] ?? $0 } + problemToMerge = BackupProblem( + id: backupProblem.id, + gymId: backupProblem.gymId, + name: backupProblem.name, + description: backupProblem.description, + climbType: backupProblem.climbType, + difficulty: backupProblem.difficulty, + tags: backupProblem.tags, + location: backupProblem.location, + imagePaths: updatedPaths, + isActive: backupProblem.isActive, + dateSet: backupProblem.dateSet, + notes: backupProblem.notes, + createdAt: backupProblem.createdAt, + updatedAt: backupProblem.updatedAt + ) + } + + if let index = dataManager.problems.firstIndex(where: { + $0.id.uuidString == problemToMerge.id + }) { + let existing = dataManager.problems[index] + if problemToMerge.updatedAt >= formatter.string(from: existing.updatedAt) { + dataManager.problems[index] = try problemToMerge.toProblem() + } + } else { + dataManager.problems.append(try problemToMerge.toProblem()) + } + } + + // Merge sessions + for backupSession in response.sessions { + if deletedItemSet.contains("session:" + backupSession.id) { + continue + } + + if let index = dataManager.sessions.firstIndex(where: { + $0.id.uuidString == backupSession.id + }) { + let existing = dataManager.sessions[index] + if backupSession.updatedAt >= formatter.string(from: existing.updatedAt) { + dataManager.sessions[index] = try backupSession.toClimbSession() + } + } else { + dataManager.sessions.append(try backupSession.toClimbSession()) + } + } + + // Merge attempts + for backupAttempt in response.attempts { + if deletedItemSet.contains("attempt:" + backupAttempt.id) { + continue + } + + if let index = dataManager.attempts.firstIndex(where: { + $0.id.uuidString == backupAttempt.id + }) { + let existing = dataManager.attempts[index] + if backupAttempt.createdAt >= formatter.string(from: existing.createdAt) { + dataManager.attempts[index] = try backupAttempt.toAttempt() + } + } else { + dataManager.attempts.append(try backupAttempt.toAttempt()) + } + } + + // Apply deletions again for safety + applyDeletionsToDataManager(deletions: uniqueDeletions, dataManager: dataManager) + + // Save all changes + dataManager.saveGyms() + dataManager.saveProblems() + dataManager.saveSessions() + dataManager.saveAttempts() + + // Update deletion records + dataManager.clearDeletedItems() + if let data = try? JSONEncoder().encode(uniqueDeletions) { + UserDefaults.standard.set(data, forKey: "ascently_deleted_items") + } + + DataStateManager.shared.updateDataState() + } + + private func applyDeletionsToDataManager( + deletions: [DeletedItem], dataManager: ClimbingDataManager + ) { + let deletedGymIds = Set(deletions.filter { $0.type == "gym" }.map { $0.id }) + let deletedProblemIds = Set(deletions.filter { $0.type == "problem" }.map { $0.id }) + let deletedSessionIds = Set(deletions.filter { $0.type == "session" }.map { $0.id }) + let deletedAttemptIds = Set(deletions.filter { $0.type == "attempt" }.map { $0.id }) + + dataManager.gyms.removeAll { deletedGymIds.contains($0.id.uuidString) } + dataManager.problems.removeAll { deletedProblemIds.contains($0.id.uuidString) } + dataManager.sessions.removeAll { deletedSessionIds.contains($0.id.uuidString) } + dataManager.attempts.removeAll { deletedAttemptIds.contains($0.id.uuidString) } + } + + private func syncModifiedImages( + modifiedProblems: [BackupProblem], dataManager: ClimbingDataManager + ) async throws { + guard !modifiedProblems.isEmpty else { return } + + AppLogger.info("Delta Sync: Syncing images for \(modifiedProblems.count) modified problems", tag: logTag) + + for backupProblem in modifiedProblems { + guard + let problem = dataManager.problems.first(where: { + $0.id.uuidString == backupProblem.id + }) + else { + continue + } + + for (index, imagePath) in problem.imagePaths.enumerated() { + let filename = URL(fileURLWithPath: imagePath).lastPathComponent + let consistentFilename = ImageNamingUtils.generateImageFilename( + problemId: problem.id.uuidString, imageIndex: index) + + let imageManager = ImageManager.shared + let fullPath = imageManager.imagesDirectory.appendingPathComponent(filename).path + + if let imageData = imageManager.loadImageData(fromPath: fullPath) { + do { + if filename != consistentFilename { + let newPath = imageManager.imagesDirectory.appendingPathComponent( + consistentFilename + ).path + try? FileManager.default.moveItem(atPath: fullPath, toPath: newPath) + } + + try await uploadImage(filename: consistentFilename, imageData: imageData) + AppLogger.info("Uploaded modified problem image: \(consistentFilename)", tag: logTag) + } catch { + AppLogger.info("Failed to upload image \(consistentFilename): \(error)", tag: logTag) + } + } + } + } + } + + private func uploadImage(filename: String, imageData: Data) async throws { + guard let url = URL(string: "\(serverURL)/images/upload?filename=\(filename)") else { + throw SyncError.invalidURL + } + + var request = URLRequest(url: url) + request.httpMethod = "POST" + request.setValue("Bearer \(authToken)", forHTTPHeaderField: "Authorization") + request.setValue("application/octet-stream", forHTTPHeaderField: "Content-Type") + request.httpBody = imageData + + request.timeoutInterval = 60.0 + request.cachePolicy = .reloadIgnoringLocalCacheData + + let (_, response) = try await URLSession.shared.data(for: request) + + guard let httpResponse = response as? HTTPURLResponse else { + throw SyncError.invalidResponse + } + + switch httpResponse.statusCode { + case 200: + break + case 401: + throw SyncError.unauthorized + default: + throw SyncError.serverError(httpResponse.statusCode) + } + } + + private func downloadImage(filename: String) async throws -> Data { + guard let url = URL(string: "\(serverURL)/images/download?filename=\(filename)") else { + throw SyncError.invalidURL + } + + var request = URLRequest(url: url) + request.httpMethod = "GET" + request.setValue("Bearer \(authToken)", forHTTPHeaderField: "Authorization") + + request.timeoutInterval = 45.0 + request.cachePolicy = .returnCacheDataElseLoad + + let (data, response) = try await URLSession.shared.data(for: request) + + guard let httpResponse = response as? HTTPURLResponse else { + throw SyncError.invalidResponse + } + + switch httpResponse.statusCode { + case 200: + return data + case 401: + throw SyncError.unauthorized + case 404: + throw SyncError.imageNotFound + default: + throw SyncError.serverError(httpResponse.statusCode) + } + } + + private func syncImagesFromServer(backup: ClimbDataBackup, dataManager: ClimbingDataManager) + async throws -> [String: String] + { + var imagePathMapping: [String: String] = [:] + + for problem in backup.problems { + guard let imagePaths = problem.imagePaths, !imagePaths.isEmpty else { continue } + + for (index, imagePath) in imagePaths.enumerated() { + let serverFilename = URL(fileURLWithPath: imagePath).lastPathComponent + + do { + let imageData = try await downloadImage(filename: serverFilename) + + let consistentFilename = ImageNamingUtils.generateImageFilename( + problemId: problem.id, imageIndex: index) + + let imageManager = ImageManager.shared + _ = try imageManager.saveImportedImage( + imageData, filename: consistentFilename) + + imagePathMapping[serverFilename] = consistentFilename + AppLogger.info("Downloaded and mapped image: \(serverFilename) -> \(consistentFilename)", tag: logTag) + } catch SyncError.imageNotFound { + AppLogger.info("Image not found on server: \(serverFilename)", tag: logTag) + continue + } catch { + AppLogger.info("Failed to download image \(serverFilename): \(error)", tag: logTag) + continue + } + } + } + + return imagePathMapping + } + + private func syncImagesToServer(dataManager: ClimbingDataManager) async throws { + // Process images by problem to ensure consistent naming + for problem in dataManager.problems { + guard !problem.imagePaths.isEmpty else { continue } + + for (index, imagePath) in problem.imagePaths.enumerated() { + let filename = URL(fileURLWithPath: imagePath).lastPathComponent + + let consistentFilename = ImageNamingUtils.generateImageFilename( + problemId: problem.id.uuidString, imageIndex: index) + + // Load image data + let imageManager = ImageManager.shared + let fullPath = imageManager.imagesDirectory.appendingPathComponent(filename).path + + if let imageData = imageManager.loadImageData(fromPath: fullPath) { + do { + // If filename changed, rename local file + if filename != consistentFilename { + let newPath = imageManager.imagesDirectory.appendingPathComponent( + consistentFilename + ).path + do { + try FileManager.default.moveItem(atPath: fullPath, toPath: newPath) + AppLogger.info("Renamed local image: \(filename) -> \(consistentFilename)", tag: logTag) + + // Update problem's image path in memory for consistency + } catch { + AppLogger.info("Failed to rename local image, using original: \(error)", tag: logTag) + } + } + + try await uploadImage(filename: consistentFilename, imageData: imageData) + AppLogger.info("Successfully uploaded image: \(consistentFilename)", tag: logTag) + } catch { + AppLogger.info("Failed to upload image \(consistentFilename): \(error)", tag: logTag) + // Continue with other images even if one fails + } + } + } + } + } + + private func createBackupFromDataManager(_ dataManager: ClimbingDataManager) -> ClimbDataBackup + { + // Filter out active sessions and their attempts from sync + let completedSessions = dataManager.sessions.filter { $0.status != .active } + let activeSessionIds = Set( + dataManager.sessions.filter { $0.status == .active }.map { $0.id }) + let completedAttempts = dataManager.attempts.filter { + !activeSessionIds.contains($0.sessionId) + } + + AppLogger.info( + "Excluding \(dataManager.sessions.count - completedSessions.count) active sessions and \(dataManager.attempts.count - completedAttempts.count) active session attempts from sync", + tag: logTag + ) + + return ClimbDataBackup( + exportedAt: DataStateManager.shared.getLastModified(), + gyms: dataManager.gyms.map { BackupGym(from: $0) }, + problems: dataManager.problems.map { BackupProblem(from: $0) }, + sessions: completedSessions.map { BackupClimbSession(from: $0) }, + attempts: completedAttempts.map { BackupAttempt(from: $0) }, + deletedItems: dataManager.getDeletedItems() + ) + } + + private func mergeDataSafely( + localBackup: ClimbDataBackup, + serverBackup: ClimbDataBackup, + dataManager: ClimbingDataManager + ) async throws { + // Download server images first + let imagePathMapping = try await syncImagesFromServer( + backup: serverBackup, dataManager: dataManager) + + // Use SyncMerger + let mergedResult = try SyncMerger.mergeDataSafely( + localBackup: localBackup, + serverBackup: serverBackup, + dataManager: dataManager, + imagePathMapping: imagePathMapping + ) + + // Update data manager with merged data + dataManager.gyms = mergedResult.gyms + dataManager.problems = mergedResult.problems + dataManager.sessions = mergedResult.sessions + dataManager.attempts = mergedResult.attempts + + // Save all data + dataManager.saveGyms() + dataManager.saveProblems() + dataManager.saveSessions() + dataManager.saveAttempts() + dataManager.saveActiveSession() + + // Update local deletions with merged list + dataManager.clearDeletedItems() + if let data = try? JSONEncoder().encode(mergedResult.uniqueDeletions) { + UserDefaults.standard.set(data, forKey: "ascently_deleted_items") + } + + // Upload merged data back to server + let mergedBackup = createBackupFromDataManager(dataManager) + _ = try await uploadData(mergedBackup) + try await syncImagesToServer(dataManager: dataManager) + + // Update timestamp + DataStateManager.shared.updateDataState() + } + + private func importBackupToDataManager( + _ backup: ClimbDataBackup, dataManager: ClimbingDataManager, + imagePathMapping: [String: String] = [:] + ) throws { + // This logic is also in SyncService.swift, it's quite complex as it handles active sessions preservation + // I'll copy it here. + + do { + // Store active sessions and their attempts before import (but exclude any that were deleted) + let localDeletedItems = dataManager.getDeletedItems() + let allDeletedSessionIds = Set( + (backup.deletedItems + localDeletedItems) + .filter { $0.type == "session" } + .map { $0.id } + ) + let activeSessions = dataManager.sessions.filter { + $0.status == .active && !allDeletedSessionIds.contains($0.id.uuidString) + } + let activeSessionIds = Set(activeSessions.map { $0.id }) + let allDeletedAttemptIds = Set( + (backup.deletedItems + localDeletedItems) + .filter { $0.type == "attempt" } + .map { $0.id } + ) + let activeAttempts = dataManager.attempts.filter { + activeSessionIds.contains($0.sessionId) + && !allDeletedAttemptIds.contains($0.id.uuidString) + } + + AppLogger.info( + "Preserving \(activeSessions.count) active sessions and \(activeAttempts.count) active attempts during import", + tag: logTag + ) + + // Update problem image paths to point to downloaded images + let updatedBackup: ClimbDataBackup + if !imagePathMapping.isEmpty { + let updatedProblems = backup.problems.map { problem in + let updatedImagePaths = problem.imagePaths?.compactMap { oldPath in + imagePathMapping[oldPath] ?? oldPath + } + return BackupProblem( + id: problem.id, + gymId: problem.gymId, + name: problem.name, + description: problem.description, + climbType: problem.climbType, + difficulty: problem.difficulty, + tags: problem.tags, + location: problem.location, + imagePaths: updatedImagePaths, + isActive: problem.isActive, + dateSet: problem.dateSet, + notes: problem.notes, + createdAt: problem.createdAt, + updatedAt: problem.updatedAt + ) + } + // Filter out deleted items before creating updated backup + let deletedGymIds = Set( + backup.deletedItems.filter { $0.type == "gym" }.map { $0.id }) + let deletedProblemIds = Set( + backup.deletedItems.filter { $0.type == "problem" }.map { $0.id }) + let deletedSessionIds = Set( + backup.deletedItems.filter { $0.type == "session" }.map { $0.id }) + let deletedAttemptIds = Set( + backup.deletedItems.filter { $0.type == "attempt" }.map { $0.id }) + + let filteredGyms = backup.gyms.filter { !deletedGymIds.contains($0.id) } + let filteredProblems = updatedProblems.filter { !deletedProblemIds.contains($0.id) } + let filteredSessions = backup.sessions.filter { !deletedSessionIds.contains($0.id) } + let filteredAttempts = backup.attempts.filter { !deletedAttemptIds.contains($0.id) } + + updatedBackup = ClimbDataBackup( + exportedAt: backup.exportedAt, + version: backup.version, + formatVersion: backup.formatVersion, + gyms: filteredGyms, + problems: filteredProblems, + sessions: filteredSessions, + attempts: filteredAttempts, + deletedItems: backup.deletedItems + ) + + } else { + // Filter out deleted items even when no image path mapping + let deletedGymIds = Set( + backup.deletedItems.filter { $0.type == "gym" }.map { $0.id }) + let deletedProblemIds = Set( + backup.deletedItems.filter { $0.type == "problem" }.map { $0.id }) + let deletedSessionIds = Set( + backup.deletedItems.filter { $0.type == "session" }.map { $0.id }) + let deletedAttemptIds = Set( + backup.deletedItems.filter { $0.type == "attempt" }.map { $0.id }) + + let filteredGyms = backup.gyms.filter { !deletedGymIds.contains($0.id) } + let filteredProblems = backup.problems.filter { !deletedProblemIds.contains($0.id) } + let filteredSessions = backup.sessions.filter { !deletedSessionIds.contains($0.id) } + let filteredAttempts = backup.attempts.filter { !deletedAttemptIds.contains($0.id) } + + updatedBackup = ClimbDataBackup( + exportedAt: backup.exportedAt, + version: backup.version, + formatVersion: backup.formatVersion, + gyms: filteredGyms, + problems: filteredProblems, + sessions: filteredSessions, + attempts: filteredAttempts, + deletedItems: backup.deletedItems + ) + } + + // Create a minimal ZIP with just the JSON data for existing import mechanism + // We need to use ZipUtils or similar. SyncService had createMinimalZipFromBackup. + // I should probably move createMinimalZipFromBackup to ZipUtils or just copy it here. + // Since ZipUtils exists, let's see if we can use it. + // ZipUtils.createExportZip creates a full zip. + // SyncService had a custom implementation for minimal zip. + // I'll copy the implementation here for now to avoid changing ZipUtils too much, or I can add it to ZipUtils. + // For now, I'll copy it to keep this file self-contained regarding the sync logic. + + let zipData = try createMinimalZipFromBackup(updatedBackup) + + // Use existing import method which properly handles data restoration + try dataManager.importData(from: zipData, showSuccessMessage: false) + + // Restore active sessions and their attempts after import + for session in activeSessions { + AppLogger.info("Restoring active session: \(session.id)", tag: logTag) + dataManager.sessions.append(session) + if session.id == dataManager.activeSession?.id { + dataManager.activeSession = session + } + } + + for attempt in activeAttempts { + dataManager.attempts.append(attempt) + } + + // Save restored data + dataManager.saveSessions() + dataManager.saveAttempts() + dataManager.saveActiveSession() + + // Import deletion records to prevent future resurrections + dataManager.clearDeletedItems() + if let data = try? JSONEncoder().encode(backup.deletedItems) { + UserDefaults.standard.set(data, forKey: "ascently_deleted_items") + AppLogger.info("Imported \(backup.deletedItems.count) deletion records", tag: logTag) + } + + // Update local data state to match imported data timestamp + DataStateManager.shared.setLastModified(backup.exportedAt) + AppLogger.info("Data state synchronized to imported timestamp: \(backup.exportedAt)", tag: logTag) + + } catch { + throw SyncError.importFailed(error) + } + } + + // Copied from SyncService.swift + private func createMinimalZipFromBackup(_ backup: ClimbDataBackup) throws -> Data { + // Create JSON data + + let encoder = JSONEncoder() + encoder.outputFormatting = .prettyPrinted + encoder.dateEncodingStrategy = .custom { date, encoder in + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSS" + var container = encoder.singleValueContainer() + try container.encode(formatter.string(from: date)) + } + let jsonData = try encoder.encode(backup) + + // Collect all images from ImageManager + let imageManager = ImageManager.shared + var imageFiles: [(filename: String, data: Data)] = [] + + // Get original problems to access actual image paths on disk + if let problemsData = userDefaults.data(forKey: "ascently_problems"), // Changed key to match ClimbingDataManager + let problems = try? JSONDecoder().decode([Problem].self, from: problemsData) + { + // Create a mapping from normalized paths to actual paths + for problem in problems { + for (index, imagePath) in problem.imagePaths.enumerated() { + // Get the actual filename on disk + let actualFilename = URL(fileURLWithPath: imagePath).lastPathComponent + let fullPath = imageManager.imagesDirectory.appendingPathComponent( + actualFilename + ).path + + // Generate the normalized filename for the ZIP + let normalizedFilename = ImageNamingUtils.generateImageFilename( + problemId: problem.id.uuidString, imageIndex: index) + + if let imageData = imageManager.loadImageData(fromPath: fullPath) { + imageFiles.append((filename: normalizedFilename, data: imageData)) + } + } + } + } + + // Create ZIP with data.json, metadata, and images + var zipData = Data() + var fileEntries: [(name: String, data: Data, offset: UInt32)] = [] + var currentOffset: UInt32 = 0 + + // Add data.json to ZIP + try addFileToMinimalZip( + filename: "data.json", + fileData: jsonData, + zipData: &zipData, + fileEntries: &fileEntries, + currentOffset: ¤tOffset + ) + + // Add metadata with correct image count + let metadata = "export_version=2.0\nformat_version=2.0\nimage_count=\(imageFiles.count)" + let metadataData = metadata.data(using: .utf8) ?? Data() + try addFileToMinimalZip( + filename: "metadata.txt", + fileData: metadataData, + zipData: &zipData, + fileEntries: &fileEntries, + currentOffset: ¤tOffset + ) + + // Add images to ZIP in images/ directory + for imageFile in imageFiles { + try addFileToMinimalZip( + filename: "images/\(imageFile.filename)", + fileData: imageFile.data, + zipData: &zipData, + fileEntries: &fileEntries, + currentOffset: ¤tOffset + ) + } + + // Add central directory + var centralDirectory = Data() + for entry in fileEntries { + centralDirectory.append(createCentralDirectoryHeader(entry: entry)) + } + + // Add end of central directory record + let endOfCentralDir = createEndOfCentralDirectoryRecord( + fileCount: UInt16(fileEntries.count), + centralDirSize: UInt32(centralDirectory.count), + centralDirOffset: currentOffset + ) + + zipData.append(centralDirectory) + zipData.append(endOfCentralDir) + + return zipData + } + + private func addFileToMinimalZip( + filename: String, + fileData: Data, + zipData: inout Data, + fileEntries: inout [(name: String, data: Data, offset: UInt32)], + currentOffset: inout UInt32 + ) throws { + let localFileHeader = createLocalFileHeader( + filename: filename, fileSize: UInt32(fileData.count)) + + fileEntries.append((name: filename, data: fileData, offset: currentOffset)) + + zipData.append(localFileHeader) + zipData.append(fileData) + + currentOffset += UInt32(localFileHeader.count + fileData.count) + } + + private func createLocalFileHeader(filename: String, fileSize: UInt32) -> Data { + var header = Data() + + // Local file header signature + header.append(Data([0x50, 0x4b, 0x03, 0x04])) + + // Version needed to extract (2.0) + header.append(Data([0x14, 0x00])) + + // General purpose bit flag + header.append(Data([0x00, 0x00])) + + // Compression method (no compression) + header.append(Data([0x00, 0x00])) + + // Last mod file time & date (dummy values) + header.append(Data([0x00, 0x00, 0x00, 0x00])) + + // CRC-32 (dummy - we're not compressing) + header.append(Data([0x00, 0x00, 0x00, 0x00])) + + // Compressed size + withUnsafeBytes(of: fileSize.littleEndian) { header.append(Data($0)) } + + // Uncompressed size + withUnsafeBytes(of: fileSize.littleEndian) { header.append(Data($0)) } + + // File name length + let filenameData = filename.data(using: .utf8) ?? Data() + let filenameLength = UInt16(filenameData.count) + withUnsafeBytes(of: filenameLength.littleEndian) { header.append(Data($0)) } + + // Extra field length + header.append(Data([0x00, 0x00])) + + // File name + header.append(filenameData) + + return header + } + + private func createCentralDirectoryHeader(entry: (name: String, data: Data, offset: UInt32)) + -> Data + { + var header = Data() + + // Central directory signature + header.append(Data([0x50, 0x4b, 0x01, 0x02])) + + // Version made by + header.append(Data([0x14, 0x00])) + + // Version needed to extract + header.append(Data([0x14, 0x00])) + + // General purpose bit flag + header.append(Data([0x00, 0x00])) + + // Compression method + header.append(Data([0x00, 0x00])) + + // Last mod file time & date + header.append(Data([0x00, 0x00, 0x00, 0x00])) + + // CRC-32 + header.append(Data([0x00, 0x00, 0x00, 0x00])) + + // Compressed size + let compressedSize = UInt32(entry.data.count) + withUnsafeBytes(of: compressedSize.littleEndian) { header.append(Data($0)) } + + // Uncompressed size + withUnsafeBytes(of: compressedSize.littleEndian) { header.append(Data($0)) } + + // File name length + let filenameData = entry.name.data(using: .utf8) ?? Data() + let filenameLength = UInt16(filenameData.count) + withUnsafeBytes(of: filenameLength.littleEndian) { header.append(Data($0)) } + + // Extra field length + header.append(Data([0x00, 0x00])) + + // File comment length + header.append(Data([0x00, 0x00])) + + // Disk number start + header.append(Data([0x00, 0x00])) + + // Internal file attributes + header.append(Data([0x00, 0x00])) + + // External file attributes + header.append(Data([0x00, 0x00, 0x00, 0x00])) + + // Relative offset of local header + withUnsafeBytes(of: entry.offset.littleEndian) { header.append(Data($0)) } + + // File name + header.append(filenameData) + + return header + } + + private func createEndOfCentralDirectoryRecord( + fileCount: UInt16, centralDirSize: UInt32, centralDirOffset: UInt32 + ) -> Data { + var record = Data() + + // End of central dir signature + record.append(Data([0x50, 0x4b, 0x05, 0x06])) + + // Number of this disk + record.append(Data([0x00, 0x00])) + + // Number of the disk with the start of the central directory + record.append(Data([0x00, 0x00])) + + // Total number of entries in the central directory on this disk + withUnsafeBytes(of: fileCount.littleEndian) { record.append(Data($0)) } + + // Total number of entries in the central directory + withUnsafeBytes(of: fileCount.littleEndian) { record.append(Data($0)) } + + // Size of the central directory + withUnsafeBytes(of: centralDirSize.littleEndian) { record.append(Data($0)) } + + // Offset of start of central directory + withUnsafeBytes(of: centralDirOffset.littleEndian) { record.append(Data($0)) } + + // ZIP file comment length + record.append(Data([0x00, 0x00])) + + return record + } +} diff --git a/ios/Ascently/Services/Sync/SyncMerger.swift b/ios/Ascently/Services/Sync/SyncMerger.swift new file mode 100644 index 0000000..e942748 --- /dev/null +++ b/ios/Ascently/Services/Sync/SyncMerger.swift @@ -0,0 +1,181 @@ +import Foundation + +struct SyncMerger { + private static let logTag = "SyncMerger" + + static func mergeDataSafely( + localBackup: ClimbDataBackup, + serverBackup: ClimbDataBackup, + dataManager: ClimbingDataManager, + imagePathMapping: [String: String] + ) throws -> (gyms: [Gym], problems: [Problem], sessions: [ClimbSession], attempts: [Attempt], uniqueDeletions: [DeletedItem]) { + + // Merge deletion lists first to prevent resurrection of deleted items + let localDeletions = dataManager.getDeletedItems() + let allDeletions = localDeletions + serverBackup.deletedItems + let uniqueDeletions = Array(Set(allDeletions)) + + AppLogger.info("Merging gyms...", tag: logTag) + let mergedGyms = mergeGyms( + local: dataManager.gyms, + server: serverBackup.gyms, + deletedItems: uniqueDeletions) + + AppLogger.info("Merging problems...", tag: logTag) + let mergedProblems = try mergeProblems( + local: dataManager.problems, + server: serverBackup.problems, + imagePathMapping: imagePathMapping, + deletedItems: uniqueDeletions) + + AppLogger.info("Merging sessions...", tag: logTag) + let mergedSessions = try mergeSessions( + local: dataManager.sessions, + server: serverBackup.sessions, + deletedItems: uniqueDeletions) + + AppLogger.info("Merging attempts...", tag: logTag) + let mergedAttempts = try mergeAttempts( + local: dataManager.attempts, + server: serverBackup.attempts, + deletedItems: uniqueDeletions) + + return (mergedGyms, mergedProblems, mergedSessions, mergedAttempts, uniqueDeletions) + } + + private static func mergeGyms(local: [Gym], server: [BackupGym], deletedItems: [DeletedItem]) -> [Gym] { + var merged = local + let deletedGymIds = Set(deletedItems.filter { $0.type == "gym" }.map { $0.id }) + let localGymIds = Set(local.map { $0.id.uuidString }) + + merged.removeAll { deletedGymIds.contains($0.id.uuidString) } + + // Add new items from server (excluding deleted ones) + for serverGym in server { + if let serverGymConverted = try? serverGym.toGym() { + let localHasGym = localGymIds.contains(serverGym.id) + let isDeleted = deletedGymIds.contains(serverGym.id) + + if !localHasGym && !isDeleted { + merged.append(serverGymConverted) + } + } + } + + return merged + } + + private static func mergeProblems( + local: [Problem], + server: [BackupProblem], + imagePathMapping: [String: String], + deletedItems: [DeletedItem] + ) throws -> [Problem] { + var merged = local + let deletedProblemIds = Set(deletedItems.filter { $0.type == "problem" }.map { $0.id }) + let localProblemIds = Set(local.map { $0.id.uuidString }) + + merged.removeAll { deletedProblemIds.contains($0.id.uuidString) } + + for serverProblem in server { + let localHasProblem = localProblemIds.contains(serverProblem.id) + let isDeleted = deletedProblemIds.contains(serverProblem.id) + + if !localHasProblem && !isDeleted { + var problemToAdd = serverProblem + + if !imagePathMapping.isEmpty, let imagePaths = serverProblem.imagePaths, !imagePaths.isEmpty { + let updatedImagePaths = imagePaths.compactMap { oldPath in + imagePathMapping[oldPath] ?? oldPath + } + if updatedImagePaths != imagePaths { + problemToAdd = BackupProblem( + id: serverProblem.id, + gymId: serverProblem.gymId, + name: serverProblem.name, + description: serverProblem.description, + climbType: serverProblem.climbType, + difficulty: serverProblem.difficulty, + tags: serverProblem.tags, + location: serverProblem.location, + imagePaths: updatedImagePaths, + isActive: serverProblem.isActive, + dateSet: serverProblem.dateSet, + notes: serverProblem.notes, + createdAt: serverProblem.createdAt, + updatedAt: serverProblem.updatedAt + ) + } + } + + if let serverProblemConverted = try? problemToAdd.toProblem() { + merged.append(serverProblemConverted) + } + } + } + + return merged + } + + private static func mergeSessions( + local: [ClimbSession], server: [BackupClimbSession], deletedItems: [DeletedItem] + ) throws -> [ClimbSession] { + var merged = local + let deletedSessionIds = Set(deletedItems.filter { $0.type == "session" }.map { $0.id }) + let localSessionIds = Set(local.map { $0.id.uuidString }) + + merged.removeAll { session in + deletedSessionIds.contains(session.id.uuidString) && session.status != .active + } + + for serverSession in server { + let localHasSession = localSessionIds.contains(serverSession.id) + let isDeleted = deletedSessionIds.contains(serverSession.id) + + if !localHasSession && !isDeleted { + if let serverSessionConverted = try? serverSession.toClimbSession() { + merged.append(serverSessionConverted) + } + } + } + + return merged + } + + private static func mergeAttempts( + local: [Attempt], server: [BackupAttempt], deletedItems: [DeletedItem] + ) throws -> [Attempt] { + var merged = local + let deletedAttemptIds = Set(deletedItems.filter { $0.type == "attempt" }.map { $0.id }) + let localAttemptIds = Set(local.map { $0.id.uuidString }) + + // Get active session IDs to protect their attempts + let activeSessionIds = Set( + local.compactMap { attempt in + return attempt.sessionId + }.filter { sessionId in + // Check if this session ID belongs to an active session + // For now, we'll be conservative and not delete attempts during merge + return true + }) + + // Remove items that were deleted on other devices (but be conservative with attempts) + merged.removeAll { attempt in + deletedAttemptIds.contains(attempt.id.uuidString) + && !activeSessionIds.contains(attempt.sessionId) + } + + for serverAttempt in server { + let localHasAttempt = localAttemptIds.contains(serverAttempt.id) + let isDeleted = deletedAttemptIds.contains(serverAttempt.id) + + if !localHasAttempt && !isDeleted { + if let serverAttemptConverted = try? serverAttempt.toAttempt() { + merged.append(serverAttemptConverted) + } + } + } + + return merged + } +} diff --git a/ios/Ascently/Services/Sync/SyncProvider.swift b/ios/Ascently/Services/Sync/SyncProvider.swift new file mode 100644 index 0000000..074fa4f --- /dev/null +++ b/ios/Ascently/Services/Sync/SyncProvider.swift @@ -0,0 +1,73 @@ +import Foundation + +enum SyncProviderType: String, CaseIterable, Identifiable { + case none + case server + case iCloud + + var id: String { rawValue } + var displayName: String { + switch self { + case .none: return "None" + case .server: return "Self-Hosted Server" + case .iCloud: return "iCloud" + } + } +} + +protocol SyncProvider { + var type: SyncProviderType { get } + var isConfigured: Bool { get } + var isConnected: Bool { get } + + func sync(dataManager: ClimbingDataManager) async throws + func testConnection() async throws + func disconnect() +} + +enum SyncError: LocalizedError { + case notConfigured + case notConnected + case invalidURL + case invalidResponse + case unauthorized + case badRequest + case serverError(Int) + case decodingError(Error) + case exportFailed + case importFailed(Error) + case imageNotFound + case imageUploadFailed + case providerError(String) + + var errorDescription: String? { + switch self { + case .notConfigured: + return "Sync server not configured. Please set server URL and auth token." + case .notConnected: + return "Not connected to sync server. Please test connection first." + case .invalidURL: + return "Invalid server URL." + case .invalidResponse: + return "Invalid response from server." + case .unauthorized: + return "Authentication failed. Check your auth token." + case .badRequest: + return "Bad request. Check your data format." + case .serverError(let code): + return "Server error (code \(code))." + case .decodingError(let error): + return "Failed to decode response: \(error.localizedDescription)" + case .exportFailed: + return "Failed to export local data." + case .importFailed(let error): + return "Failed to import data: \(error.localizedDescription)" + case .imageNotFound: + return "Image not found on server." + case .imageUploadFailed: + return "Failed to upload image to server." + case .providerError(let message): + return "Sync provider error: \(message)" + } + } +} diff --git a/ios/Ascently/Services/SyncService.swift b/ios/Ascently/Services/SyncService.swift index 1f71a01..31c9138 100644 --- a/ios/Ascently/Services/SyncService.swift +++ b/ios/Ascently/Services/SyncService.swift @@ -10,6 +10,15 @@ class SyncService: ObservableObject { @Published var isConnected = false @Published var isTesting = false @Published var isOfflineMode = false + + @Published var providerType: SyncProviderType = .server { + didSet { + updateActiveProvider() + userDefaults.set(providerType.rawValue, forKey: Keys.providerType) + } + } + + private var activeProvider: SyncProvider? private let userDefaults = UserDefaults.standard private let logTag = "SyncService" @@ -17,22 +26,6 @@ class SyncService: ObservableObject { private var pendingChanges = false private let syncDebounceDelay: TimeInterval = 2.0 - private func logDebug(_ message: @autoclosure () -> String) { - AppLogger.debug(message(), tag: logTag) - } - - private func logInfo(_ message: @autoclosure () -> String) { - AppLogger.info(message(), tag: logTag) - } - - private func logWarning(_ message: @autoclosure () -> String) { - AppLogger.warning(message(), tag: logTag) - } - - private func logError(_ message: @autoclosure () -> String) { - AppLogger.error(message(), tag: logTag) - } - private enum Keys { static let serverURL = "sync_server_url" static let authToken = "sync_auth_token" @@ -40,11 +33,16 @@ class SyncService: ObservableObject { static let isConnected = "is_connected" static let autoSyncEnabled = "auto_sync_enabled" static let offlineMode = "offline_mode" + static let providerType = "sync_provider_type" } + // Legacy properties for compatibility with SettingsView var serverURL: String { get { userDefaults.string(forKey: Keys.serverURL) ?? "" } - set { userDefaults.set(newValue, forKey: Keys.serverURL) } + set { + userDefaults.set(newValue, forKey: Keys.serverURL) + // If active provider is server, it will pick up the change from UserDefaults + } } var authToken: String { @@ -53,7 +51,7 @@ class SyncService: ObservableObject { } var isConfigured: Bool { - return !serverURL.isEmpty && !authToken.isEmpty + return activeProvider?.isConfigured ?? false } var isAutoSyncEnabled: Bool { @@ -68,514 +66,56 @@ class SyncService: ObservableObject { isConnected = userDefaults.bool(forKey: Keys.isConnected) isAutoSyncEnabled = userDefaults.object(forKey: Keys.autoSyncEnabled) as? Bool ?? true isOfflineMode = userDefaults.bool(forKey: Keys.offlineMode) + + if let savedType = userDefaults.string(forKey: Keys.providerType), + let type = SyncProviderType(rawValue: savedType) { + self.providerType = type + } else { + self.providerType = .server // Default + } + + updateActiveProvider() } - - func downloadData() async throws -> ClimbDataBackup { - guard isConfigured else { - throw SyncError.notConfigured + + private func updateActiveProvider() { + switch providerType { + case .server: + activeProvider = ServerSyncProvider() + case .iCloud: + // Placeholder for iCloud provider + activeProvider = nil + case .none: + activeProvider = nil } - - guard let url = URL(string: "\(serverURL)/sync") else { - throw SyncError.invalidURL - } - - var request = URLRequest(url: url) - request.httpMethod = "GET" - request.setValue("Bearer \(authToken)", forHTTPHeaderField: "Authorization") - request.setValue("application/json", forHTTPHeaderField: "Accept") - - let (data, response) = try await URLSession.shared.data(for: request) - - guard let httpResponse = response as? HTTPURLResponse else { - throw SyncError.invalidResponse - } - - switch httpResponse.statusCode { - case 200: - break - case 401: - throw SyncError.unauthorized - default: - throw SyncError.serverError(httpResponse.statusCode) - } - - do { - let backup = try JSONDecoder().decode(ClimbDataBackup.self, from: data) - return backup - } catch { - throw SyncError.decodingError(error) - } - } - - func uploadData(_ backup: ClimbDataBackup) async throws -> ClimbDataBackup { - guard isConfigured else { - throw SyncError.notConfigured - } - - guard let url = URL(string: "\(serverURL)/sync") else { - throw SyncError.invalidURL - } - - let encoder = JSONEncoder() - encoder.dateEncodingStrategy = .iso8601 - - let jsonData = try encoder.encode(backup) - - var request = URLRequest(url: url) - request.httpMethod = "PUT" - request.setValue("Bearer \(authToken)", forHTTPHeaderField: "Authorization") - request.setValue("application/json", forHTTPHeaderField: "Content-Type") - request.setValue("application/json", forHTTPHeaderField: "Accept") - request.httpBody = jsonData - - let (data, response) = try await URLSession.shared.data(for: request) - - guard let httpResponse = response as? HTTPURLResponse else { - throw SyncError.invalidResponse - } - - switch httpResponse.statusCode { - case 200: - break - case 401: - throw SyncError.unauthorized - case 400: - throw SyncError.badRequest - default: - throw SyncError.serverError(httpResponse.statusCode) - } - - do { - let responseBackup = try JSONDecoder().decode(ClimbDataBackup.self, from: data) - return responseBackup - } catch { - throw SyncError.decodingError(error) - } - } - - func performDeltaSync(dataManager: ClimbingDataManager) async throws { - guard isConfigured else { - throw SyncError.notConfigured - } - - guard let url = URL(string: "\(serverURL)/sync/delta") else { - throw SyncError.invalidURL - } - - // Get last sync time, or use epoch if never synced - let lastSync = lastSyncTime ?? Date(timeIntervalSince1970: 0) - let formatter = ISO8601DateFormatter() - let lastSyncString = formatter.string(from: lastSync) - - // Collect items modified since last sync - let modifiedGyms = dataManager.gyms.filter { gym in - gym.updatedAt > lastSync - }.map { BackupGym(from: $0) } - - let modifiedProblems = dataManager.problems.filter { problem in - problem.updatedAt > lastSync - }.map { problem -> BackupProblem in - let backupProblem = BackupProblem(from: problem) - if !problem.imagePaths.isEmpty { - let normalizedPaths = problem.imagePaths.enumerated().map { index, _ in - ImageNamingUtils.generateImageFilename( - problemId: problem.id.uuidString, imageIndex: index) - } - return BackupProblem( - id: backupProblem.id, - gymId: backupProblem.gymId, - name: backupProblem.name, - description: backupProblem.description, - climbType: backupProblem.climbType, - difficulty: backupProblem.difficulty, - tags: backupProblem.tags, - location: backupProblem.location, - imagePaths: normalizedPaths, - isActive: backupProblem.isActive, - dateSet: backupProblem.dateSet, - notes: backupProblem.notes, - createdAt: backupProblem.createdAt, - updatedAt: backupProblem.updatedAt - ) - } - return backupProblem - } - - let modifiedSessions = dataManager.sessions.filter { session in - session.status != .active && session.updatedAt > lastSync - }.map { BackupClimbSession(from: $0) } - - let activeSessionIds = Set( - dataManager.sessions.filter { $0.status == .active }.map { $0.id }) - let modifiedAttempts = dataManager.attempts.filter { attempt in - !activeSessionIds.contains(attempt.sessionId) && attempt.createdAt > lastSync - }.map { BackupAttempt(from: $0) } - - let modifiedDeletions = dataManager.getDeletedItems().filter { item in - if let deletedDate = formatter.date(from: item.deletedAt) { - return deletedDate > lastSync - } - return false - } - - logInfo( - "iOS DELTA SYNC: Sending gyms=\(modifiedGyms.count), problems=\(modifiedProblems.count), sessions=\(modifiedSessions.count), attempts=\(modifiedAttempts.count), deletions=\(modifiedDeletions.count)" - ) - - // Create delta request - let deltaRequest = DeltaSyncRequest( - lastSyncTime: lastSyncString, - gyms: modifiedGyms, - problems: modifiedProblems, - sessions: modifiedSessions, - attempts: modifiedAttempts, - deletedItems: modifiedDeletions - ) - - let encoder = JSONEncoder() - encoder.dateEncodingStrategy = .iso8601 - let jsonData = try encoder.encode(deltaRequest) - - var request = URLRequest(url: url) - request.httpMethod = "POST" - request.setValue("Bearer \(authToken)", forHTTPHeaderField: "Authorization") - request.setValue("application/json", forHTTPHeaderField: "Content-Type") - request.setValue("application/json", forHTTPHeaderField: "Accept") - request.httpBody = jsonData - - let (data, response) = try await URLSession.shared.data(for: request) - - guard let httpResponse = response as? HTTPURLResponse else { - throw SyncError.invalidResponse - } - - switch httpResponse.statusCode { - case 200: - break - case 401: - throw SyncError.unauthorized - default: - throw SyncError.serverError(httpResponse.statusCode) - } - - let decoder = JSONDecoder() - let deltaResponse = try decoder.decode(DeltaSyncResponse.self, from: data) - - logInfo( - "iOS DELTA SYNC: Received gyms=\(deltaResponse.gyms.count), problems=\(deltaResponse.problems.count), sessions=\(deltaResponse.sessions.count), attempts=\(deltaResponse.attempts.count), deletions=\(deltaResponse.deletedItems.count)" - ) - - // Apply server changes to local data - try await applyDeltaResponse(deltaResponse, dataManager: dataManager) - - // Sync only modified problem images - try await syncModifiedImages(modifiedProblems: modifiedProblems, dataManager: dataManager) - - // Update last sync time to server time - if let serverTime = formatter.date(from: deltaResponse.serverTime) { - lastSyncTime = serverTime - userDefaults.set(lastSyncTime, forKey: Keys.lastSyncTime) - } - } - - private func applyDeltaResponse(_ response: DeltaSyncResponse, dataManager: ClimbingDataManager) - async throws - { - let formatter = ISO8601DateFormatter() - - // Merge and apply deletions first to prevent resurrection - let allDeletions = dataManager.getDeletedItems() + response.deletedItems - let uniqueDeletions = Array(Set(allDeletions)) - - logInfo( - "iOS DELTA SYNC: Applying \(uniqueDeletions.count) deletion records before merging data" - ) - applyDeletionsToDataManager(deletions: uniqueDeletions, dataManager: dataManager) - - // Build deleted item lookup map - let deletedItemSet = Set(uniqueDeletions.map { $0.type + ":" + $0.id }) - - // Download images for new/modified problems from server - var imagePathMapping: [String: String] = [:] - for problem in response.problems { - if deletedItemSet.contains("problem:" + problem.id) { - continue - } - - guard let imagePaths = problem.imagePaths, !imagePaths.isEmpty else { continue } - - for (index, imagePath) in imagePaths.enumerated() { - let serverFilename = URL(fileURLWithPath: imagePath).lastPathComponent - - do { - let imageData = try await downloadImage(filename: serverFilename) - let consistentFilename = ImageNamingUtils.generateImageFilename( - problemId: problem.id, imageIndex: index) - let imageManager = ImageManager.shared - _ = try imageManager.saveImportedImage(imageData, filename: consistentFilename) - imagePathMapping[serverFilename] = consistentFilename - } catch SyncError.imageNotFound { - logInfo("Image not found on server: \(serverFilename)") - continue - } catch { - logInfo("Failed to download image \(serverFilename): \(error)") - continue - } - } - } - - // Merge gyms - for backupGym in response.gyms { - if deletedItemSet.contains("gym:" + backupGym.id) { - continue - } - - if let index = dataManager.gyms.firstIndex(where: { $0.id.uuidString == backupGym.id }) - { - let existing = dataManager.gyms[index] - if backupGym.updatedAt >= formatter.string(from: existing.updatedAt) { - dataManager.gyms[index] = try backupGym.toGym() - } - } else { - dataManager.gyms.append(try backupGym.toGym()) - } - } - - // Merge problems - for backupProblem in response.problems { - if deletedItemSet.contains("problem:" + backupProblem.id) { - continue - } - - var problemToMerge = backupProblem - if !imagePathMapping.isEmpty, let imagePaths = backupProblem.imagePaths { - let updatedPaths = imagePaths.compactMap { imagePathMapping[$0] ?? $0 } - problemToMerge = BackupProblem( - id: backupProblem.id, - gymId: backupProblem.gymId, - name: backupProblem.name, - description: backupProblem.description, - climbType: backupProblem.climbType, - difficulty: backupProblem.difficulty, - tags: backupProblem.tags, - location: backupProblem.location, - imagePaths: updatedPaths, - isActive: backupProblem.isActive, - dateSet: backupProblem.dateSet, - notes: backupProblem.notes, - createdAt: backupProblem.createdAt, - updatedAt: backupProblem.updatedAt - ) - } - - if let index = dataManager.problems.firstIndex(where: { - $0.id.uuidString == problemToMerge.id - }) { - let existing = dataManager.problems[index] - if problemToMerge.updatedAt >= formatter.string(from: existing.updatedAt) { - dataManager.problems[index] = try problemToMerge.toProblem() - } - } else { - dataManager.problems.append(try problemToMerge.toProblem()) - } - } - - // Merge sessions - for backupSession in response.sessions { - if deletedItemSet.contains("session:" + backupSession.id) { - continue - } - - if let index = dataManager.sessions.firstIndex(where: { - $0.id.uuidString == backupSession.id - }) { - let existing = dataManager.sessions[index] - if backupSession.updatedAt >= formatter.string(from: existing.updatedAt) { - dataManager.sessions[index] = try backupSession.toClimbSession() - } - } else { - dataManager.sessions.append(try backupSession.toClimbSession()) - } - } - - // Merge attempts - for backupAttempt in response.attempts { - if deletedItemSet.contains("attempt:" + backupAttempt.id) { - continue - } - - if let index = dataManager.attempts.firstIndex(where: { - $0.id.uuidString == backupAttempt.id - }) { - let existing = dataManager.attempts[index] - if backupAttempt.createdAt >= formatter.string(from: existing.createdAt) { - dataManager.attempts[index] = try backupAttempt.toAttempt() - } - } else { - dataManager.attempts.append(try backupAttempt.toAttempt()) - } - } - - // Apply deletions again for safety - applyDeletionsToDataManager(deletions: uniqueDeletions, dataManager: dataManager) - - // Save all changes - dataManager.saveGyms() - dataManager.saveProblems() - dataManager.saveSessions() - dataManager.saveAttempts() - - // Update deletion records - dataManager.clearDeletedItems() - if let data = try? JSONEncoder().encode(uniqueDeletions) { - UserDefaults.standard.set(data, forKey: "ascently_deleted_items") - } - - DataStateManager.shared.updateDataState() - } - - private func applyDeletionsToDataManager( - deletions: [DeletedItem], dataManager: ClimbingDataManager - ) { - let deletedGymIds = Set(deletions.filter { $0.type == "gym" }.map { $0.id }) - let deletedProblemIds = Set(deletions.filter { $0.type == "problem" }.map { $0.id }) - let deletedSessionIds = Set(deletions.filter { $0.type == "session" }.map { $0.id }) - let deletedAttemptIds = Set(deletions.filter { $0.type == "attempt" }.map { $0.id }) - - dataManager.gyms.removeAll { deletedGymIds.contains($0.id.uuidString) } - dataManager.problems.removeAll { deletedProblemIds.contains($0.id.uuidString) } - dataManager.sessions.removeAll { deletedSessionIds.contains($0.id.uuidString) } - dataManager.attempts.removeAll { deletedAttemptIds.contains($0.id.uuidString) } - } - - private func syncModifiedImages( - modifiedProblems: [BackupProblem], dataManager: ClimbingDataManager - ) async throws { - guard !modifiedProblems.isEmpty else { return } - - logInfo("iOS DELTA SYNC: Syncing images for \(modifiedProblems.count) modified problems") - - for backupProblem in modifiedProblems { - guard - let problem = dataManager.problems.first(where: { - $0.id.uuidString == backupProblem.id - }) - else { - continue - } - - for (index, imagePath) in problem.imagePaths.enumerated() { - let filename = URL(fileURLWithPath: imagePath).lastPathComponent - let consistentFilename = ImageNamingUtils.generateImageFilename( - problemId: problem.id.uuidString, imageIndex: index) - - let imageManager = ImageManager.shared - let fullPath = imageManager.imagesDirectory.appendingPathComponent(filename).path - - if let imageData = imageManager.loadImageData(fromPath: fullPath) { - do { - if filename != consistentFilename { - let newPath = imageManager.imagesDirectory.appendingPathComponent( - consistentFilename - ).path - try? FileManager.default.moveItem(atPath: fullPath, toPath: newPath) - } - - try await uploadImage(filename: consistentFilename, imageData: imageData) - logInfo("Uploaded modified problem image: \(consistentFilename)") - } catch { - logInfo("Failed to upload image \(consistentFilename): \(error)") - } - } - } - } - } - - func uploadImage(filename: String, imageData: Data) async throws { - guard isConfigured else { - throw SyncError.notConfigured - } - - guard let url = URL(string: "\(serverURL)/images/upload?filename=\(filename)") else { - throw SyncError.invalidURL - } - - var request = URLRequest(url: url) - request.httpMethod = "POST" - request.setValue("Bearer \(authToken)", forHTTPHeaderField: "Authorization") - request.setValue("application/octet-stream", forHTTPHeaderField: "Content-Type") - request.httpBody = imageData - - request.timeoutInterval = 60.0 - request.cachePolicy = .reloadIgnoringLocalCacheData - - let (_, response) = try await URLSession.shared.data(for: request) - - guard let httpResponse = response as? HTTPURLResponse else { - throw SyncError.invalidResponse - } - - switch httpResponse.statusCode { - case 200: - break - case 401: - throw SyncError.unauthorized - default: - throw SyncError.serverError(httpResponse.statusCode) - } - } - - func downloadImage(filename: String) async throws -> Data { - guard isConfigured else { - throw SyncError.notConfigured - } - - guard let url = URL(string: "\(serverURL)/images/download?filename=\(filename)") else { - throw SyncError.invalidURL - } - - var request = URLRequest(url: url) - request.httpMethod = "GET" - request.setValue("Bearer \(authToken)", forHTTPHeaderField: "Authorization") - - request.timeoutInterval = 45.0 - request.cachePolicy = .returnCacheDataElseLoad - - let (data, response) = try await URLSession.shared.data(for: request) - - guard let httpResponse = response as? HTTPURLResponse else { - - throw SyncError.invalidResponse - } - - switch httpResponse.statusCode { - case 200: - - return data - case 401: - - throw SyncError.unauthorized - case 404: - - throw SyncError.imageNotFound - default: - - throw SyncError.serverError(httpResponse.statusCode) + + // Update status based on new provider + if let provider = activeProvider { + isConnected = provider.isConnected + } else { + isConnected = false } } func syncWithServer(dataManager: ClimbingDataManager) async throws { if isOfflineMode { - logInfo("Sync skipped: Offline mode is enabled.") + AppLogger.info("Sync skipped: Offline mode is enabled.", tag: logTag) return } - - guard isConfigured else { + + guard let provider = activeProvider else { + if providerType == .none { + return + } throw SyncError.notConfigured } - guard isConnected else { - throw SyncError.notConnected + guard provider.isConfigured else { + throw SyncError.notConfigured + } + + // For server provider, we check connection. For others, maybe not needed or different check. + if providerType == .server && !provider.isConnected { + throw SyncError.notConnected } isSyncing = true @@ -586,725 +126,33 @@ class SyncService: ObservableObject { } do { - // Get local backup data - let localBackup = createBackupFromDataManager(dataManager) - - // Download server data - let serverBackup = try await downloadData() - - // Check if we have any local data - let hasLocalData = - !dataManager.gyms.isEmpty || !dataManager.problems.isEmpty - || !dataManager.sessions.isEmpty || !dataManager.attempts.isEmpty - - let hasServerData = - !serverBackup.gyms.isEmpty || !serverBackup.problems.isEmpty - || !serverBackup.sessions.isEmpty || !serverBackup.attempts.isEmpty - - // If both client and server have been synced before, use delta sync - if hasLocalData && hasServerData && lastSyncTime != nil { - logInfo("iOS SYNC: Using delta sync for incremental updates") - try await performDeltaSync(dataManager: dataManager) - - // Update last sync time - lastSyncTime = Date() - userDefaults.set(lastSyncTime, forKey: Keys.lastSyncTime) - return - } - - if !hasLocalData && hasServerData { - // Case 1: No local data - do full restore from server - logInfo("iOS SYNC: Case 1 - No local data, performing full restore from server") - logInfo("Syncing images from server first...") - let imagePathMapping = try await syncImagesFromServer( - backup: serverBackup, dataManager: dataManager) - logInfo("Importing data after images...") - try importBackupToDataManager( - serverBackup, dataManager: dataManager, imagePathMapping: imagePathMapping) - logInfo("Full restore completed") - } else if hasLocalData && !hasServerData { - // Case 2: No server data - upload local data to server - logInfo("iOS SYNC: Case 2 - No server data, uploading local data to server") - let currentBackup = createBackupFromDataManager(dataManager) - _ = try await uploadData(currentBackup) - logInfo("Uploading local images to server...") - try await syncImagesToServer(dataManager: dataManager) - logInfo("Initial upload completed") - } else if hasLocalData && hasServerData { - // Case 3: Both have data - use safe merge strategy - logInfo("iOS SYNC: Case 3 - Merging local and server data safely") - try await mergeDataSafely( - localBackup: localBackup, - serverBackup: serverBackup, - dataManager: dataManager) - logInfo("Safe merge completed") - } else { - logInfo("No data to sync") - } - + try await provider.sync(dataManager: dataManager) + // Update last sync time - lastSyncTime = Date() - userDefaults.set(lastSyncTime, forKey: Keys.lastSyncTime) - + // Provider might have updated it in UserDefaults, reload it + if let lastSync = userDefaults.object(forKey: Keys.lastSyncTime) as? Date { + self.lastSyncTime = lastSync + } + } catch { syncError = error.localizedDescription throw error } } - private func parseISO8601ToMillis(timestamp: String) -> Int64 { - let formatter = ISO8601DateFormatter() - if let date = formatter.date(from: timestamp) { - return Int64(date.timeIntervalSince1970 * 1000) - } - logInfo("Failed to parse timestamp: \(timestamp), using 0") - return 0 - } - - private func syncImagesFromServer(backup: ClimbDataBackup, dataManager: ClimbingDataManager) - async throws -> [String: String] - { - var imagePathMapping: [String: String] = [:] - - for problem in backup.problems { - guard let imagePaths = problem.imagePaths, !imagePaths.isEmpty else { continue } - - for (index, imagePath) in imagePaths.enumerated() { - let serverFilename = URL(fileURLWithPath: imagePath).lastPathComponent - - do { - let imageData = try await downloadImage(filename: serverFilename) - - let consistentFilename = ImageNamingUtils.generateImageFilename( - problemId: problem.id, imageIndex: index) - - let imageManager = ImageManager.shared - _ = try imageManager.saveImportedImage( - imageData, filename: consistentFilename) - - imagePathMapping[serverFilename] = consistentFilename - logInfo("Downloaded and mapped image: \(serverFilename) -> \(consistentFilename)") - } catch SyncError.imageNotFound { - logInfo("Image not found on server: \(serverFilename)") - continue - } catch { - logInfo("Failed to download image \(serverFilename): \(error)") - continue - } - } - } - - return imagePathMapping - } - - private func syncImagesToServer(dataManager: ClimbingDataManager) async throws { - // Process images by problem to ensure consistent naming - for problem in dataManager.problems { - guard !problem.imagePaths.isEmpty else { continue } - - for (index, imagePath) in problem.imagePaths.enumerated() { - let filename = URL(fileURLWithPath: imagePath).lastPathComponent - - let consistentFilename = ImageNamingUtils.generateImageFilename( - problemId: problem.id.uuidString, imageIndex: index) - - // Load image data - let imageManager = ImageManager.shared - let fullPath = imageManager.imagesDirectory.appendingPathComponent(filename).path - - if let imageData = imageManager.loadImageData(fromPath: fullPath) { - do { - // If filename changed, rename local file - if filename != consistentFilename { - let newPath = imageManager.imagesDirectory.appendingPathComponent( - consistentFilename - ).path - do { - try FileManager.default.moveItem(atPath: fullPath, toPath: newPath) - logInfo("Renamed local image: \(filename) -> \(consistentFilename)") - - // Update problem's image path in memory for consistency - } catch { - logInfo("Failed to rename local image, using original: \(error)") - } - } - - try await uploadImage(filename: consistentFilename, imageData: imageData) - logInfo("Successfully uploaded image: \(consistentFilename)") - } catch { - logInfo("Failed to upload image \(consistentFilename): \(error)") - // Continue with other images even if one fails - } - } - } - } - } - - private func createBackupFromDataManager(_ dataManager: ClimbingDataManager) -> ClimbDataBackup - { - // Filter out active sessions and their attempts from sync - let completedSessions = dataManager.sessions.filter { $0.status != .active } - let activeSessionIds = Set( - dataManager.sessions.filter { $0.status == .active }.map { $0.id }) - let completedAttempts = dataManager.attempts.filter { - !activeSessionIds.contains($0.sessionId) - } - - logInfo( - "iOS SYNC: Excluding \(dataManager.sessions.count - completedSessions.count) active sessions and \(dataManager.attempts.count - completedAttempts.count) active session attempts from sync" - ) - - return ClimbDataBackup( - exportedAt: DataStateManager.shared.getLastModified(), - gyms: dataManager.gyms.map { BackupGym(from: $0) }, - problems: dataManager.problems.map { BackupProblem(from: $0) }, - sessions: completedSessions.map { BackupClimbSession(from: $0) }, - attempts: completedAttempts.map { BackupAttempt(from: $0) }, - deletedItems: dataManager.getDeletedItems() - ) - } - - func createBackupForExport(_ dataManager: ClimbingDataManager) -> ClimbDataBackup { - // Filter out active sessions and their attempts from sync - let completedSessions = dataManager.sessions.filter { $0.status != .active } - let activeSessionIds = Set( - dataManager.sessions.filter { $0.status == .active }.map { $0.id }) - let completedAttempts = dataManager.attempts.filter { - !activeSessionIds.contains($0.sessionId) - } - - // Create backup with normalized image paths for export - return ClimbDataBackup( - exportedAt: DataStateManager.shared.getLastModified(), - gyms: dataManager.gyms.map { BackupGym(from: $0) }, - problems: dataManager.problems.map { problem in - var backupProblem = BackupProblem(from: problem) - - if !problem.imagePaths.isEmpty { - let normalizedPaths = problem.imagePaths.enumerated().map { index, _ in - ImageNamingUtils.generateImageFilename( - problemId: problem.id.uuidString, imageIndex: index) - } - - backupProblem = BackupProblem( - id: backupProblem.id, - gymId: backupProblem.gymId, - name: backupProblem.name, - description: backupProblem.description, - climbType: backupProblem.climbType, - difficulty: backupProblem.difficulty, - tags: backupProblem.tags, - location: backupProblem.location, - imagePaths: normalizedPaths, - isActive: backupProblem.isActive, - dateSet: backupProblem.dateSet, - notes: backupProblem.notes, - createdAt: backupProblem.createdAt, - updatedAt: backupProblem.updatedAt - ) - } - return backupProblem - }, - sessions: completedSessions.map { BackupClimbSession(from: $0) }, - attempts: completedAttempts.map { BackupAttempt(from: $0) }, - deletedItems: dataManager.getDeletedItems() - ) - } - - private func mergeDataSafely( - localBackup: ClimbDataBackup, - serverBackup: ClimbDataBackup, - dataManager: ClimbingDataManager - ) async throws { - // Download server images first - let imagePathMapping = try await syncImagesFromServer( - backup: serverBackup, dataManager: dataManager) - - // Merge deletion lists first to prevent resurrection of deleted items - let localDeletions = dataManager.getDeletedItems() - let allDeletions = localDeletions + serverBackup.deletedItems - let uniqueDeletions = Array(Set(allDeletions)) - - logInfo("Merging gyms...") - let mergedGyms = mergeGyms( - local: dataManager.gyms, - server: serverBackup.gyms, - deletedItems: uniqueDeletions) - - logInfo("Merging problems...") - let mergedProblems = try mergeProblems( - local: dataManager.problems, - server: serverBackup.problems, - imagePathMapping: imagePathMapping, - deletedItems: uniqueDeletions) - - logInfo("Merging sessions...") - let mergedSessions = try mergeSessions( - local: dataManager.sessions, - server: serverBackup.sessions, - deletedItems: uniqueDeletions) - - logInfo("Merging attempts...") - let mergedAttempts = try mergeAttempts( - local: dataManager.attempts, - server: serverBackup.attempts, - deletedItems: uniqueDeletions) - - // Update data manager with merged data - dataManager.gyms = mergedGyms - dataManager.problems = mergedProblems - dataManager.sessions = mergedSessions - dataManager.attempts = mergedAttempts - - // Save all data - dataManager.saveGyms() - dataManager.saveProblems() - dataManager.saveSessions() - dataManager.saveAttempts() - dataManager.saveActiveSession() - - // Update local deletions with merged list - dataManager.clearDeletedItems() - if let data = try? JSONEncoder().encode(uniqueDeletions) { - UserDefaults.standard.set(data, forKey: "ascently_deleted_items") - } - - // Upload merged data back to server - let mergedBackup = createBackupFromDataManager(dataManager) - _ = try await uploadData(mergedBackup) - try await syncImagesToServer(dataManager: dataManager) - - // Update timestamp - DataStateManager.shared.updateDataState() - } - - private func importBackupToDataManager( - _ backup: ClimbDataBackup, dataManager: ClimbingDataManager, - imagePathMapping: [String: String] = [:] - ) throws { - do { - // Store active sessions and their attempts before import (but exclude any that were deleted) - let localDeletedItems = dataManager.getDeletedItems() - let allDeletedSessionIds = Set( - (backup.deletedItems + localDeletedItems) - .filter { $0.type == "session" } - .map { $0.id } - ) - let activeSessions = dataManager.sessions.filter { - $0.status == .active && !allDeletedSessionIds.contains($0.id.uuidString) - } - let activeSessionIds = Set(activeSessions.map { $0.id }) - let allDeletedAttemptIds = Set( - (backup.deletedItems + localDeletedItems) - .filter { $0.type == "attempt" } - .map { $0.id } - ) - let activeAttempts = dataManager.attempts.filter { - activeSessionIds.contains($0.sessionId) - && !allDeletedAttemptIds.contains($0.id.uuidString) - } - - logInfo( - "iOS IMPORT: Preserving \(activeSessions.count) active sessions and \(activeAttempts.count) active attempts during import" - ) - - // Update problem image paths to point to downloaded images - let updatedBackup: ClimbDataBackup - if !imagePathMapping.isEmpty { - let updatedProblems = backup.problems.map { problem in - let updatedImagePaths = problem.imagePaths?.compactMap { oldPath in - imagePathMapping[oldPath] ?? oldPath - } - return BackupProblem( - id: problem.id, - gymId: problem.gymId, - name: problem.name, - description: problem.description, - climbType: problem.climbType, - difficulty: problem.difficulty, - tags: problem.tags, - location: problem.location, - imagePaths: updatedImagePaths, - isActive: problem.isActive, - dateSet: problem.dateSet, - notes: problem.notes, - createdAt: problem.createdAt, - updatedAt: problem.updatedAt - ) - } - // Filter out deleted items before creating updated backup - let deletedGymIds = Set( - backup.deletedItems.filter { $0.type == "gym" }.map { $0.id }) - let deletedProblemIds = Set( - backup.deletedItems.filter { $0.type == "problem" }.map { $0.id }) - let deletedSessionIds = Set( - backup.deletedItems.filter { $0.type == "session" }.map { $0.id }) - let deletedAttemptIds = Set( - backup.deletedItems.filter { $0.type == "attempt" }.map { $0.id }) - - let filteredGyms = backup.gyms.filter { !deletedGymIds.contains($0.id) } - let filteredProblems = updatedProblems.filter { !deletedProblemIds.contains($0.id) } - let filteredSessions = backup.sessions.filter { !deletedSessionIds.contains($0.id) } - let filteredAttempts = backup.attempts.filter { !deletedAttemptIds.contains($0.id) } - - updatedBackup = ClimbDataBackup( - exportedAt: backup.exportedAt, - version: backup.version, - formatVersion: backup.formatVersion, - gyms: filteredGyms, - problems: filteredProblems, - sessions: filteredSessions, - attempts: filteredAttempts, - deletedItems: backup.deletedItems - ) - - } else { - // Filter out deleted items even when no image path mapping - let deletedGymIds = Set( - backup.deletedItems.filter { $0.type == "gym" }.map { $0.id }) - let deletedProblemIds = Set( - backup.deletedItems.filter { $0.type == "problem" }.map { $0.id }) - let deletedSessionIds = Set( - backup.deletedItems.filter { $0.type == "session" }.map { $0.id }) - let deletedAttemptIds = Set( - backup.deletedItems.filter { $0.type == "attempt" }.map { $0.id }) - - let filteredGyms = backup.gyms.filter { !deletedGymIds.contains($0.id) } - let filteredProblems = backup.problems.filter { !deletedProblemIds.contains($0.id) } - let filteredSessions = backup.sessions.filter { !deletedSessionIds.contains($0.id) } - let filteredAttempts = backup.attempts.filter { !deletedAttemptIds.contains($0.id) } - - updatedBackup = ClimbDataBackup( - exportedAt: backup.exportedAt, - version: backup.version, - formatVersion: backup.formatVersion, - gyms: filteredGyms, - problems: filteredProblems, - sessions: filteredSessions, - attempts: filteredAttempts, - deletedItems: backup.deletedItems - ) - } - - // Create a minimal ZIP with just the JSON data for existing import mechanism - let zipData = try createMinimalZipFromBackup(updatedBackup) - - // Use existing import method which properly handles data restoration - try dataManager.importData(from: zipData, showSuccessMessage: false) - - // Restore active sessions and their attempts after import - for session in activeSessions { - logInfo("iOS IMPORT: Restoring active session: \(session.id)") - dataManager.sessions.append(session) - if session.id == dataManager.activeSession?.id { - dataManager.activeSession = session - } - } - - for attempt in activeAttempts { - dataManager.attempts.append(attempt) - } - - // Save restored data - dataManager.saveSessions() - dataManager.saveAttempts() - dataManager.saveActiveSession() - - // Import deletion records to prevent future resurrections - dataManager.clearDeletedItems() - if let data = try? JSONEncoder().encode(backup.deletedItems) { - UserDefaults.standard.set(data, forKey: "ascently_deleted_items") - logInfo("iOS IMPORT: Imported \(backup.deletedItems.count) deletion records") - } - - // Update local data state to match imported data timestamp - DataStateManager.shared.setLastModified(backup.exportedAt) - logInfo("Data state synchronized to imported timestamp: \(backup.exportedAt)") - - } catch { - throw SyncError.importFailed(error) - } - } - - private func createMinimalZipFromBackup(_ backup: ClimbDataBackup) throws -> Data { - // Create JSON data - - let encoder = JSONEncoder() - encoder.outputFormatting = .prettyPrinted - encoder.dateEncodingStrategy = .custom { date, encoder in - let formatter = DateFormatter() - formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSS" - var container = encoder.singleValueContainer() - try container.encode(formatter.string(from: date)) - } - let jsonData = try encoder.encode(backup) - - // Collect all images from ImageManager - let imageManager = ImageManager.shared - var imageFiles: [(filename: String, data: Data)] = [] - - // Get original problems to access actual image paths on disk - if let problemsData = userDefaults.data(forKey: "problems"), - let problems = try? JSONDecoder().decode([Problem].self, from: problemsData) - { - // Create a mapping from normalized paths to actual paths - for problem in problems { - for (index, imagePath) in problem.imagePaths.enumerated() { - // Get the actual filename on disk - let actualFilename = URL(fileURLWithPath: imagePath).lastPathComponent - let fullPath = imageManager.imagesDirectory.appendingPathComponent( - actualFilename - ).path - - // Generate the normalized filename for the ZIP - let normalizedFilename = ImageNamingUtils.generateImageFilename( - problemId: problem.id.uuidString, imageIndex: index) - - if let imageData = imageManager.loadImageData(fromPath: fullPath) { - imageFiles.append((filename: normalizedFilename, data: imageData)) - } - } - } - } - - // Create ZIP with data.json, metadata, and images - var zipData = Data() - var fileEntries: [(name: String, data: Data, offset: UInt32)] = [] - var currentOffset: UInt32 = 0 - - // Add data.json to ZIP - try addFileToMinimalZip( - filename: "data.json", - fileData: jsonData, - zipData: &zipData, - fileEntries: &fileEntries, - currentOffset: ¤tOffset - ) - - // Add metadata with correct image count - let metadata = "export_version=2.0\nformat_version=2.0\nimage_count=\(imageFiles.count)" - let metadataData = metadata.data(using: .utf8) ?? Data() - try addFileToMinimalZip( - filename: "metadata.txt", - fileData: metadataData, - zipData: &zipData, - fileEntries: &fileEntries, - currentOffset: ¤tOffset - ) - - // Add images to ZIP in images/ directory - for imageFile in imageFiles { - try addFileToMinimalZip( - filename: "images/\(imageFile.filename)", - fileData: imageFile.data, - zipData: &zipData, - fileEntries: &fileEntries, - currentOffset: ¤tOffset - ) - } - - // Add central directory - var centralDirectory = Data() - for entry in fileEntries { - centralDirectory.append(createCentralDirectoryHeader(entry: entry)) - } - - // Add end of central directory record - let endOfCentralDir = createEndOfCentralDirectoryRecord( - fileCount: UInt16(fileEntries.count), - centralDirSize: UInt32(centralDirectory.count), - centralDirOffset: currentOffset - ) - - zipData.append(centralDirectory) - zipData.append(endOfCentralDir) - - return zipData - } - - private func addFileToMinimalZip( - filename: String, - fileData: Data, - zipData: inout Data, - fileEntries: inout [(name: String, data: Data, offset: UInt32)], - currentOffset: inout UInt32 - ) throws { - let localFileHeader = createLocalFileHeader( - filename: filename, fileSize: UInt32(fileData.count)) - - fileEntries.append((name: filename, data: fileData, offset: currentOffset)) - - zipData.append(localFileHeader) - zipData.append(fileData) - - currentOffset += UInt32(localFileHeader.count + fileData.count) - } - - private func createLocalFileHeader(filename: String, fileSize: UInt32) -> Data { - var header = Data() - - // Local file header signature - header.append(Data([0x50, 0x4b, 0x03, 0x04])) - - // Version needed to extract (2.0) - header.append(Data([0x14, 0x00])) - - // General purpose bit flag - header.append(Data([0x00, 0x00])) - - // Compression method (no compression) - header.append(Data([0x00, 0x00])) - - // Last mod file time & date (dummy values) - header.append(Data([0x00, 0x00, 0x00, 0x00])) - - // CRC-32 (dummy - we're not compressing) - header.append(Data([0x00, 0x00, 0x00, 0x00])) - - // Compressed size - withUnsafeBytes(of: fileSize.littleEndian) { header.append(Data($0)) } - - // Uncompressed size - withUnsafeBytes(of: fileSize.littleEndian) { header.append(Data($0)) } - - // File name length - let filenameData = filename.data(using: .utf8) ?? Data() - let filenameLength = UInt16(filenameData.count) - withUnsafeBytes(of: filenameLength.littleEndian) { header.append(Data($0)) } - - // Extra field length - header.append(Data([0x00, 0x00])) - - // File name - header.append(filenameData) - - return header - } - - private func createCentralDirectoryHeader(entry: (name: String, data: Data, offset: UInt32)) - -> Data - { - var header = Data() - - // Central directory signature - header.append(Data([0x50, 0x4b, 0x01, 0x02])) - - // Version made by - header.append(Data([0x14, 0x00])) - - // Version needed to extract - header.append(Data([0x14, 0x00])) - - // General purpose bit flag - header.append(Data([0x00, 0x00])) - - // Compression method - header.append(Data([0x00, 0x00])) - - // Last mod file time & date - header.append(Data([0x00, 0x00, 0x00, 0x00])) - - // CRC-32 - header.append(Data([0x00, 0x00, 0x00, 0x00])) - - // Compressed size - let compressedSize = UInt32(entry.data.count) - withUnsafeBytes(of: compressedSize.littleEndian) { header.append(Data($0)) } - - // Uncompressed size - withUnsafeBytes(of: compressedSize.littleEndian) { header.append(Data($0)) } - - // File name length - let filenameData = entry.name.data(using: .utf8) ?? Data() - let filenameLength = UInt16(filenameData.count) - withUnsafeBytes(of: filenameLength.littleEndian) { header.append(Data($0)) } - - // Extra field length - header.append(Data([0x00, 0x00])) - - // File comment length - header.append(Data([0x00, 0x00])) - - // Disk number start - header.append(Data([0x00, 0x00])) - - // Internal file attributes - header.append(Data([0x00, 0x00])) - - // External file attributes - header.append(Data([0x00, 0x00, 0x00, 0x00])) - - // Relative offset of local header - withUnsafeBytes(of: entry.offset.littleEndian) { header.append(Data($0)) } - - // File name - header.append(filenameData) - - return header - } - - private func createEndOfCentralDirectoryRecord( - fileCount: UInt16, centralDirSize: UInt32, centralDirOffset: UInt32 - ) -> Data { - var record = Data() - - // End of central dir signature - record.append(Data([0x50, 0x4b, 0x05, 0x06])) - - // Number of this disk - record.append(Data([0x00, 0x00])) - - // Number of the disk with the start of the central directory - record.append(Data([0x00, 0x00])) - - // Total number of entries in the central directory on this disk - withUnsafeBytes(of: fileCount.littleEndian) { record.append(Data($0)) } - - // Total number of entries in the central directory - withUnsafeBytes(of: fileCount.littleEndian) { record.append(Data($0)) } - - // Size of the central directory - withUnsafeBytes(of: centralDirSize.littleEndian) { record.append(Data($0)) } - - // Offset of start of central directory - withUnsafeBytes(of: centralDirOffset.littleEndian) { record.append(Data($0)) } - - // ZIP file comment length - record.append(Data([0x00, 0x00])) - - return record - } - func testConnection() async throws { - guard isConfigured else { + guard let provider = activeProvider else { + AppLogger.error("Test connection failed: No active provider", tag: logTag) throw SyncError.notConfigured } - + isTesting = true defer { isTesting = false } - - guard let url = URL(string: "\(serverURL)/health") else { - throw SyncError.invalidURL - } - - var request = URLRequest(url: url) - request.httpMethod = "GET" - request.setValue("application/json", forHTTPHeaderField: "Accept") - request.timeoutInterval = 10 - - let (_, response) = try await URLSession.shared.data(for: request) - - guard let httpResponse = response as? HTTPURLResponse else { - throw SyncError.invalidResponse - } - - guard httpResponse.statusCode == 200 else { - throw SyncError.serverError(httpResponse.statusCode) - } - - // Connection successful, mark as connected - isConnected = true - userDefaults.set(true, forKey: Keys.isConnected) + + try await provider.testConnection() + + isConnected = provider.isConnected + userDefaults.set(isConnected, forKey: Keys.isConnected) } func triggerAutoSync(dataManager: ClimbingDataManager) { @@ -1365,6 +213,8 @@ class SyncService: ObservableObject { } func disconnect() { + activeProvider?.disconnect() + syncTask?.cancel() syncTask = nil pendingChanges = false @@ -1372,6 +222,9 @@ class SyncService: ObservableObject { isConnected = false lastSyncTime = nil syncError = nil + + // These are shared keys, so clearing them affects all providers if they use them + // But disconnect() is usually user initiated action userDefaults.set(false, forKey: Keys.isConnected) userDefaults.removeObject(forKey: Keys.lastSyncTime) } @@ -1388,201 +241,11 @@ class SyncService: ObservableObject { syncTask?.cancel() syncTask = nil pendingChanges = false + + activeProvider?.disconnect() } deinit { syncTask?.cancel() } - - // MARK: - Merging - // MARK: - Safe Merge Functions - - private func mergeGyms(local: [Gym], server: [BackupGym], deletedItems: [DeletedItem]) -> [Gym] - { - var merged = local - let deletedGymIds = Set(deletedItems.filter { $0.type == "gym" }.map { $0.id }) - - let localGymIds = Set(local.map { $0.id.uuidString }) - - merged.removeAll { deletedGymIds.contains($0.id.uuidString) } - - // Add new items from server (excluding deleted ones) - for serverGym in server { - if let serverGymConverted = try? serverGym.toGym() { - let localHasGym = localGymIds.contains(serverGym.id) - let isDeleted = deletedGymIds.contains(serverGym.id) - - if !localHasGym && !isDeleted { - merged.append(serverGymConverted) - } - } - } - - return merged - } - - private func mergeProblems( - local: [Problem], - server: [BackupProblem], - imagePathMapping: [String: String], - deletedItems: [DeletedItem] - ) throws -> [Problem] { - var merged = local - let deletedProblemIds = Set(deletedItems.filter { $0.type == "problem" }.map { $0.id }) - - let localProblemIds = Set(local.map { $0.id.uuidString }) - - merged.removeAll { deletedProblemIds.contains($0.id.uuidString) } - - for serverProblem in server { - let localHasProblem = localProblemIds.contains(serverProblem.id) - let isDeleted = deletedProblemIds.contains(serverProblem.id) - - if !localHasProblem && !isDeleted { - var problemToAdd = serverProblem - - if !imagePathMapping.isEmpty, let imagePaths = serverProblem.imagePaths, - !imagePaths.isEmpty - { - let updatedImagePaths = imagePaths.compactMap { oldPath in - imagePathMapping[oldPath] ?? oldPath - } - if updatedImagePaths != imagePaths { - problemToAdd = BackupProblem( - id: serverProblem.id, - gymId: serverProblem.gymId, - name: serverProblem.name, - description: serverProblem.description, - climbType: serverProblem.climbType, - difficulty: serverProblem.difficulty, - tags: serverProblem.tags, - location: serverProblem.location, - imagePaths: updatedImagePaths, - isActive: serverProblem.isActive, - dateSet: serverProblem.dateSet, - notes: serverProblem.notes, - createdAt: serverProblem.createdAt, - updatedAt: serverProblem.updatedAt - ) - } - } - - if let serverProblemConverted = try? problemToAdd.toProblem() { - merged.append(serverProblemConverted) - } - } - } - - return merged - } - - private func mergeSessions( - local: [ClimbSession], server: [BackupClimbSession], deletedItems: [DeletedItem] - ) throws - -> [ClimbSession] - { - var merged = local - let deletedSessionIds = Set(deletedItems.filter { $0.type == "session" }.map { $0.id }) - - let localSessionIds = Set(local.map { $0.id.uuidString }) - - merged.removeAll { session in - deletedSessionIds.contains(session.id.uuidString) && session.status != .active - } - - for serverSession in server { - let localHasSession = localSessionIds.contains(serverSession.id) - let isDeleted = deletedSessionIds.contains(serverSession.id) - - if !localHasSession && !isDeleted { - if let serverSessionConverted = try? serverSession.toClimbSession() { - merged.append(serverSessionConverted) - } - } - } - - return merged - } - - private func mergeAttempts( - local: [Attempt], server: [BackupAttempt], deletedItems: [DeletedItem] - ) throws -> [Attempt] { - var merged = local - let deletedAttemptIds = Set(deletedItems.filter { $0.type == "attempt" }.map { $0.id }) - - let localAttemptIds = Set(local.map { $0.id.uuidString }) - - // Get active session IDs to protect their attempts - let activeSessionIds = Set( - local.compactMap { attempt in - return attempt.sessionId - }.filter { sessionId in - // Check if this session ID belongs to an active session - // For now, we'll be conservative and not delete attempts during merge - return true - }) - - // Remove items that were deleted on other devices (but be conservative with attempts) - merged.removeAll { attempt in - deletedAttemptIds.contains(attempt.id.uuidString) - && !activeSessionIds.contains(attempt.sessionId) - } - - for serverAttempt in server { - let localHasAttempt = localAttemptIds.contains(serverAttempt.id) - let isDeleted = deletedAttemptIds.contains(serverAttempt.id) - - if !localHasAttempt && !isDeleted { - if let serverAttemptConverted = try? serverAttempt.toAttempt() { - merged.append(serverAttemptConverted) - } - } - } - - return merged - } -} - -enum SyncError: LocalizedError { - case notConfigured - case notConnected - case invalidURL - case invalidResponse - case unauthorized - case badRequest - case serverError(Int) - case decodingError(Error) - case exportFailed - case importFailed(Error) - case imageNotFound - case imageUploadFailed - - var errorDescription: String? { - switch self { - case .notConfigured: - return "Sync server not configured. Please set server URL and auth token." - case .notConnected: - return "Not connected to sync server. Please test connection first." - case .invalidURL: - return "Invalid server URL." - case .invalidResponse: - return "Invalid response from server." - case .unauthorized: - return "Authentication failed. Check your auth token." - case .badRequest: - return "Bad request. Check your data format." - case .serverError(let code): - return "Server error (code \(code))." - case .decodingError(let error): - return "Failed to decode response: \(error.localizedDescription)" - case .exportFailed: - return "Failed to export local data." - case .importFailed(let error): - return "Failed to import data: \(error.localizedDescription)" - case .imageNotFound: - return "Image not found on server." - case .imageUploadFailed: - return "Failed to upload image to server." - } - } } diff --git a/ios/Ascently/Views/SettingsView.swift b/ios/Ascently/Views/SettingsView.swift index e32f91a..52fb964 100644 --- a/ios/Ascently/Views/SettingsView.swift +++ b/ios/Ascently/Views/SettingsView.swift @@ -794,6 +794,12 @@ struct SyncSettingsView: View { syncService.serverURL = newURL syncService.authToken = newToken + + // Ensure provider type is set to server + if syncService.providerType != .server { + syncService.providerType = .server + } + dismiss() } .fontWeight(.semibold) @@ -834,6 +840,13 @@ struct SyncSettingsView: View { Task { do { + // Ensure we are using the server provider + await MainActor.run { + if syncService.providerType != .server { + syncService.providerType = .server + } + } + // Temporarily set the values for testing syncService.serverURL = testURL syncService.authToken = testToken