Skip to content

Scope identifiers to bundle ID for multi-instance support#572

Closed
bjorkert wants to merge 3 commits intolive-activityfrom
feature/multi-instance-la-identifiers
Closed

Scope identifiers to bundle ID for multi-instance support#572
bjorkert wants to merge 3 commits intolive-activityfrom
feature/multi-instance-la-identifiers

Conversation

@bjorkert
Copy link
Contributor

@bjorkert bjorkert commented Mar 22, 2026

Summary

  • Derive BGTask IDs, notification IDs, URL schemes, and notification categories from Bundle.main.bundleIdentifier so LoopFollow, LoopFollow_Second, and LoopFollow_Third each get isolated identifiers
  • Show the configured display name in the Live Activity footer when the existing "Show Display Name" toggle is enabled
  • Add migration step 7 to cancel orphaned notifications scheduled with the old hardcoded identifiers

Identifiers fixed

Identifier Before After
BGTask ID com.loopfollow.audiorefresh <bundleID>.audiorefresh
Renewal notification loopfollow.la.renewal.failed <bundleID>.la.renewal.failed
Background alert IDs loopfollow.background.alert.* <bundleID>.background.alert.*
Alert category loopfollow.background.alert <bundleID>.background.alert
URL scheme loopfollow loopfollow$(app_suffix)
Info.plist BGTask com.loopfollow.audiorefresh com.$(unique_id).LoopFollow$(app_suffix).audiorefresh

Display name in LA footer

  • Respects the existing "Show Display Name" toggle from General Settings
  • OFF (default): Last Update: 14:32
  • ON: LoopFollow — 14:32 (or whatever custom name is configured)

Migration step 7

Cancels any pending/delivered notifications with the old hardcoded identifiers (loopfollow.background.alert.*, loopfollow.la.renewal.failed) so users upgrading don't get orphaned notifications.

Files changed

  • AppGroupID.swift — added baseBundleID and urlScheme helpers
  • Info.plist — BGTask ID and URL scheme use build variables
  • BackgroundRefreshManager.swift — task ID from bundle ID
  • LiveActivityManager.swift — notification ID from bundle ID, writes display name to App Group
  • BackgroundAlertManager.swift — all notification IDs from bundle ID
  • AppDelegate.swift — category ID from BackgroundAlertIdentifier
  • SceneDelegate.swift — URL scheme from AppGroupID.urlScheme
  • RestartLiveActivityIntent.swift — URL scheme from AppGroupID.urlScheme
  • LAAppGroupSettings.swift — display name + show toggle via App Group UserDefaults
  • LoopFollowLiveActivity.swift — URL scheme from AppGroupID.urlScheme, conditional footer
  • Storage+Migrate.swift — migration step 7: cancel legacy notification identifiers
  • MainViewController.swift — run migration step 7

Derive BGTask IDs, notification IDs, URL schemes, and notification
categories from Bundle.main.bundleIdentifier so that LoopFollow,
LoopFollow_Second, and LoopFollow_Third each get isolated identifiers
and don't interfere with each other's background tasks, notifications,
or Live Activities.

Also show the configured display name in the Live Activity footer
(next to the update time) when the existing "Show Display Name"
toggle is enabled, so users can identify which instance a LA belongs to.
Users upgrading from the old hardcoded identifiers would have orphaned
pending notifications that the new bundle-ID-scoped code can't cancel.
This one-time migration cleans them up on first launch.
@bjorkert
Copy link
Contributor Author

Closing since this code is already in the branch.

@bjorkert bjorkert closed this Mar 24, 2026
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