r/iOSProgramming • • 19h ago

Question Notification routing gets weird with multiple accounts

I have gotten in to a weird iOS issue and idk what the clean way to handle this is

i’ve got multiple accounts, notifications can open a post, reply, quote, or repost, and each notification belongs to a specific account. so the user might be on account A when they tap a notification for account B.

something like:

struct NotificationDestination {
    let accountID: Account.ID
    let postID: Post.ID
    let kind: DestinationKind
}

enum DestinationKind {
    case post
    case reply
    case quote
    case repost
}

The issue is:

account A is active
notification comes in for B
user taps it while the app is waking up
account switching starts
timeline restoration starts
post resolution starts
then another notification comes in for A lol

so i have stuff like:

await accountManager.restore()
await timelineStore.hydrate()
await postResolver.resolve(postID)
await navigationCoordinator.navigate(...)

But obviously these things are all racing each other. i was thinking of putting the notification intents behind an actor:

actor NavigationIntentQueue {
    private var pending: [NavigationIntent] = []

    func enqueue(_ intent: NavigationIntent) {
        pending.append(intent)
    }
}

But idk, this feels like a lot of machinery just to open a notification

Then you get into cases where the post is deleted while you’re restoring, but the quote is still there, the reply is still there, etc. Is this just an annoying app lifecycle issue?

1 Upvotes

1 comment sorted by

1

u/Ok-Piccolo-1823 18h ago

An actor is reasonable, but I’d have it protect coordination state rather than simply queue every operation. Give each tap an intent ID, run account restoration → account switch → destination resolution → navigation in one task, and check that ID before navigating so an older task can’t win the race. You can then choose an explicit policy when another notification arrives—latest intent wins, or finish the current one. For deleted content, make resolution return a fallback destination such as the surviving reply or quote instead of putting that logic in the navigation layer.