Skip to content

fix(ios): keep connection Safe Mode across iCloud sync#1435

Merged
datlechin merged 1 commit into
mainfrom
worktree-fix-ios-safemode-sync
May 27, 2026
Merged

fix(ios): keep connection Safe Mode across iCloud sync#1435
datlechin merged 1 commit into
mainfrom
worktree-fix-ios-safemode-sync

Conversation

@datlechin
Copy link
Copy Markdown
Member

Problem

On iOS, a connection's Safe Mode does not survive relaunch. Set it to Confirm Writes, save, quit, reopen: it's back to Off.

Root cause

Safe Mode persists to disk fine, but iCloud sync (on by default) round-trips connections through CloudKit, and the iOS package's SyncRecordMapper never wrote or read safeModeLevel. On relaunch the pull rebuilds the connection with the field defaulted to .off; the connection is no longer dirty, so mergeConnections treats remote as newer, overwrites the saved .confirmWrites, and persists .off back to disk.

The macOS app already syncs safeModeLevel; only the iOS/package mapper dropped it. macOS and iOS keep separate DatabaseConnection/SafeModeLevel/SyncRecordMapper implementations and meet only at the CloudKit field names.

Fix

SyncRecordMapper now round-trips safeModeLevel:

  • toRecord and updateRecord write the field.
  • toConnection reads it via safeModeLevel(fromWire:isReadOnly:), which:
    • maps the iOS values (off/confirmWrites/readOnly) directly, which also covers macOS readOnly so write protection round-trips cross-device;
    • maps macOS-only values (silent -> .off, alert/safeMode variants -> .confirmWrites) so a connection protected on the Mac reads correctly on iPhone;
    • falls back to isReadOnly ? .readOnly : .off for legacy/absent records, matching DatabaseConnection's Codable decoder.

No macOS, model, or PluginKit-ABI changes. No new user-facing strings, so no localization or docs changes.

Tests

New TableProSyncTests target (none existed) with SyncRecordMapperTests:

  • round-trip for every Safe Mode level
  • updateRecord carries the new level
  • legacy record without safeModeLevel falls back to isReadOnly
  • macOS wire values decode to the nearest iOS level

swift test --filter SyncRecordMapperTests passes (13 cases).

@datlechin datlechin merged commit 340cbf5 into main May 27, 2026
2 of 3 checks passed
@datlechin datlechin deleted the worktree-fix-ios-safemode-sync branch May 27, 2026 11:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant