ReviewOS

also looking at this

craft-native/craft

fix(ios): hand a notification tap that launches the app to the page that asks for it

#255
Merged glennmichael123 wants to merge fix/ios-notification-tap-cold-start into main
5 files +194 -9
packages/ios/src/index.test.tsmodified+27-0
Changes to packages/ios/src/index.test.ts
@@ -349,6 +349,33 @@ describe('Craft iOS builder', () => {
349349 expect(swift).toContain('if !wasConnected, self?.isConnected == true {')
350350 })
351351
352 it('holds a notification tap that launches the app until the page is ready', async () => {
353 // A tap on a killed app reaches the app delegate before SwiftUI has built
354 // the Coordinator. It was posted through NotificationCenter, which keeps
355 // nothing for an observer that does not exist yet, so the tap was lost.
356 // CraftEventManager exists from process start and holds it, as it already
357 // does for a home-screen shortcut.
358 const output = mkdtempSync(join(tmpdir(), 'craft-ios-notification-tap-'))
359 await init({ name: 'WildLoop', bundleId: 'org.wildloop.app', output })
360 const swift = readFileSync(join(output, 'Sources', 'WildLoopApp.swift'), 'utf8')
361
362 const didReceive = swift.slice(
363 swift.indexOf('didReceive response: UNNotificationResponse'),
364 swift.indexOf('willPresent notification: UNNotification'),
365 )
366 expect(didReceive).toContain('CraftEventManager.shared.handleNotificationResponse(')
367 expect(didReceive).not.toContain('NotificationCenter.default.post(')
368
369 // And only that path: a Coordinator still observing a NotificationCenter
370 // post would deliver a warm tap twice.
371 expect(swift).not.toContain('name: .craftNotificationResponse')
372 expect(swift).not.toContain('func receiveNotificationResponse(')
373
374 // It goes through the manager's buffer rather than straight to the page.
375 const handle = swift.slice(swift.indexOf('func handleNotificationResponse('))
376 expect(handle.slice(0, handle.indexOf('\n }\n'))).toContain('sendToWeb("craftNotificationResponse"')
377 })
378
352379 it('settles calendar callbacks only after a real EventKit operation', async () => {
353380 const output = mkdtempSync(join(tmpdir(), 'craft-ios-calendar-'))
354381 await init({