Move iMessage sync into BlackbookServer (un-sandboxed) - #40
Merged
Merged
Conversation
iMessage Sync in the sandboxed main macOS app could never read ~/Library/Messages/chat.db: NSHomeDirectory() resolved to the sandbox container, and the App Sandbox blocks the Messages DB regardless of Full Disk Access. De-sandboxing the main app isn't an option — App Store Connect rejects non-sandboxed macOS builds (ITMS-90296), which would break the TestFlight pipeline. BlackbookServer is already un-sandboxed, always-running, owns the master SwiftData store, and syncs to all devices, so the iMessage reader belongs there. Interactions it creates reach iOS + macOS via /sync/changes (the pull query serves by updatedAt). It also works when the Mac app is closed. Main app: - Restore sandboxed entitlements / project.yml (revert exploratory de-sandbox); macOS build re-embeds com.apple.security.app-sandbox. - Remove the dead main-app IMessageSyncService, its BlackbookApp wiring, the SettingsView section, and the unused AppConstants.IMessageSync enum. BlackbookServer: - New IMessageSyncService: polls chat.db, matches contacts by phone AND email (handles routed to Apple-ID emails now match), 30-day backfill, (contactId, second, summary) dedup guard, and an unmatched-handles diagnostic. Path uses NSUserName() (sandbox-independent). - Wire into ServerStatusModel (starts if enabled) and add the controls to the menu-bar popover: Log iMessages toggle, Sync Last 30 Days, Open Full Disk Access, Unmatched handles. Requires granting Full Disk Access to "Blackbook Server" (not "Blackbook"). BlackbookServer is not in TestFlight; rebuild/reinstall locally per docs/test-scenarios/TEST_SCENARIOS.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
iMessage Sync in the sandboxed main macOS app could never read
~/Library/Messages/chat.db:NSHomeDirectory()resolved to the sandbox container, so the path didn't exist → "chat.db not found".De-sandboxing the main app isn't viable — App Store Connect rejects non-sandboxed macOS builds (
ITMS-90296), which would break the macOS TestFlight pipeline.BlackbookServeris already un-sandboxed, always-running (login item), owns the master SwiftData store, and syncs to all devices — so the iMessage reader belongs there. Interactions it creates reach iOS + macOS via/sync/changes(the pull query serves byupdatedAt). Bonus: it now works even when the Mac app is closed.Changes
Main app
project.yml(revert exploratory de-sandbox). macOS build re-embedscom.apple.security.app-sandbox(verified viacodesign -d --entitlements -).IMessageSyncService, itsBlackbookAppwiring, theSettingsView"iMessage Sync" section, and the unusedAppConstants.IMessageSyncenum.BlackbookServer
IMessageSyncService: polls chat.db, matches contacts by phone AND email (Apple-ID-email threads now match — the likely reason some contacts never logged), 30-day backfill,(contactId, second, summary)dedup guard, and an unmatched-handles diagnostic. Path usesNSUserName()(sandbox-independent).ServerStatusModel(starts if enabled) and add controls to the menu-bar popover: Log iMessages toggle, Sync Last 30 Days, Open Full Disk Access, Unmatched handles.Test plan
xcodegen generate; BlackbookServer (Debug + Release), Blackbook iOS + macOS all build clean./Applications, running on:8765.docs/test-scenarios/TEST_SCENARIOS.md.)Deploy note
BlackbookServer is not in the TestFlight pipeline. After merge, rebuild/reinstall locally (commands in
docs/test-scenarios/TEST_SCENARIOS.md). The main-app changes deploy via the normal iOS/macOS TestFlight build.🤖 Generated with Claude Code