commit 5aa266d712a1616a8ffc4b03a4979f0f182abc76
parent e1323759cdb316b03373e25575f359acad478de3
Author: Michael Camilleri <[email protected]>
Date: Thu, 2 Jul 2026 14:03:30 +0900
Cache archive zone creation
This commit stops repeated archive convergence writes from asking
CloudKit to create the same private archive zone every time. The first
write still ensures the zone exists, but later writes in the same app
run reuse the known zone and go straight to saving the archive record.
CloudKit's existing-zone response is also treated as a successful
ensure, so another device or previous launch can have created the zone
without making the archive write fail.
Co-Authored-By: Codex GPT 5.5 <[email protected]>
Diffstat:
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/Crossmate/Sync/GameArchiver.swift b/Crossmate/Sync/GameArchiver.swift
@@ -23,6 +23,7 @@ final class GameArchiver {
private let syncEngine: SyncEngine
private let syncMonitor: SyncMonitor?
private let eventLog: EventLog?
+ private var ensuredArchiveZones = Set<CKRecordZone.ID>()
init(
container: CKContainer,
@@ -139,7 +140,7 @@ final class GameArchiver {
private func write(_ snapshot: Archive.Snapshot, markComplete: Bool) async {
let zoneID = Archive.zoneID(forOriginalGameID: snapshot.originalGameID)
do {
- try await ensureZone(zoneID)
+ try await ensureArchiveZone(zoneID)
let package = try Archive.recordPackage(from: snapshot)
try await save(package.record)
removeTemporaryArchiveFiles(package.temporaryAssetFileURLs)
@@ -251,7 +252,31 @@ final class GameArchiver {
// MARK: - CloudKit helpers
- private func ensureZone(_ zoneID: CKRecordZone.ID) async throws {
+ private func ensureArchiveZone(_ zoneID: CKRecordZone.ID) async throws {
+ guard !ensuredArchiveZones.contains(zoneID) else { return }
+ do {
+ try await createArchiveZone(zoneID)
+ } catch {
+ guard Self.isZoneAlreadyExists(error) else { throw error }
+ }
+ ensuredArchiveZones.insert(zoneID)
+ }
+
+ private nonisolated static func isZoneAlreadyExists(_ error: Error) -> Bool {
+ guard let ckError = error as? CKError else { return false }
+ if ckError.code == .serverRejectedRequest {
+ let description = ckError.localizedDescription.lowercased()
+ return description.contains("already exist")
+ }
+ if ckError.code == .partialFailure {
+ return ckError.partialErrorsByItemID?.values.contains { itemError in
+ isZoneAlreadyExists(itemError)
+ } ?? false
+ }
+ return false
+ }
+
+ private func createArchiveZone(_ zoneID: CKRecordZone.ID) async throws {
try await withCheckedThrowingContinuation { (cont: CheckedContinuation<Void, Error>) in
let op = CKModifyRecordZonesOperation(
recordZonesToSave: [CKRecordZone(zoneID: zoneID)],