crossmate

A collaborative crossword app for iOS
Log | Files | Refs | LICENSE

commit 637108301883a3b8f6b6ce04d2f390bdb2b73562
parent ca02d00b7763f647648ee75a100cd79d1e6fe5d5
Author: Michael Camilleri <[email protected]>
Date:   Wed, 15 Apr 2026 00:20:53 +0900

Attempt to address missing entity ID

Diffstat:
MCrossmate/Sync/RecordSerializer.swift | 31++++++++++++++++++++++++++-----
1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/Crossmate/Sync/RecordSerializer.swift b/Crossmate/Sync/RecordSerializer.swift @@ -96,6 +96,22 @@ enum RecordSerializer { in: context ) as! GameEntity + // Recover the UUID from the record name ("game-<UUID>") so the + // library query, which filters on `entity.id`, doesn't silently drop + // newly-synced games. + if entity.id == nil { + let uuidString = String(recordName.dropFirst("game-".count)) + entity.id = UUID(uuidString: uuidString) + } + + // Seed createdAt/updatedAt from the server record so the library + // can order newly-arrived games. The CKRecord timestamps are the + // source of truth when we don't have a local creation event. + if entity.createdAt == nil { + entity.createdAt = record.creationDate ?? Date() + } + entity.updatedAt = record.modificationDate ?? entity.updatedAt ?? Date() + entity.ckRecordName = recordName entity.ckSystemFields = encodeSystemFields(of: record) entity.title = record["title"] as? String ?? entity.title @@ -226,16 +242,21 @@ enum RecordSerializer { // Parse row/col from record name (format: "cell-<uuid>-<row>-<col>") let parts = recordName.split(separator: "-") - if parts.count >= 2, - let row = Int16(parts[parts.count - 2]), - let col = Int16(parts[parts.count - 1]), - let existing = cells.first(where: { $0.row == row && $0.col == col }) { + let parsedRow: Int16? = parts.count >= 2 ? Int16(parts[parts.count - 2]) : nil + let parsedCol: Int16? = parts.count >= 2 ? Int16(parts[parts.count - 1]) : nil + + if let parsedRow, let parsedCol, + let existing = cells.first(where: { $0.row == parsedRow && $0.col == parsedCol }) { return existing } - // Create new + // Create new. Seed row/col from the record name so that cells + // first-seen via sync have their coordinates set (otherwise they + // default to 0/0 and collide with the top-left cell). let entity = CellEntity(context: context) entity.game = game + if let parsedRow { entity.row = parsedRow } + if let parsedCol { entity.col = parsedCol } return entity } }