Title: [iOS] RouterExtensions.back() fails silently after app lock/suspend mid-navigation — component stuck, native back button unresponsive on resume · Issue #164 · NativeScript/angular · GitHub
Open Graph Title: [iOS] RouterExtensions.back() fails silently after app lock/suspend mid-navigation — component stuck, native back button unresponsive on resume · Issue #164 · NativeScript/angular
X Title: [iOS] RouterExtensions.back() fails silently after app lock/suspend mid-navigation — component stuck, native back button unresponsive on resume · Issue #164 · NativeScript/angular
Description: [iOS] RouterExtensions.back() fails silently after app lock/suspend mid-navigation — component stuck, native back button unresponsive on resume Environment CLI: 9.0.5 Cross-platform modules (@nativescript/core): 8.9.9 Android Runtime: 8....
Open Graph Description: [iOS] RouterExtensions.back() fails silently after app lock/suspend mid-navigation — component stuck, native back button unresponsive on resume Environment CLI: 9.0.5 Cross-platform modules (@nativ...
X Description: [iOS] RouterExtensions.back() fails silently after app lock/suspend mid-navigation — component stuck, native back button unresponsive on resume Environment CLI: 9.0.5 Cross-platform modules (@nativ...
Opengraph URL: https://github.com/NativeScript/angular/issues/164
X: @github
Domain: www.github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"[iOS] RouterExtensions.back() fails silently after app lock/suspend mid-navigation — component stuck, native back button unresponsive on resume","articleBody":"\u003chtml\u003e\n\u003cbody\u003e\n\u003c!--StartFragment--\u003e\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1\u003e[iOS] RouterExtensions.back() fails silently after app lock/suspend mid-navigation — component stuck, native back button unresponsive on resume\u003c/h1\u003e\n\u003cp\u003e\u003cstrong\u003eEnvironment\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eCLI: \u003cem\u003e9.0.5\u003c/em\u003e\u003c/li\u003e\n\u003cli\u003eCross-platform modules (\u003ccode\u003e@nativescript/core\u003c/code\u003e): \u003cem\u003e8.9.9\u003c/em\u003e\u003c/li\u003e\n\u003cli\u003eAndroid Runtime: \u003cem\u003e8.9.2\u003c/em\u003e\u003c/li\u003e\n\u003cli\u003eiOS Runtime: \u003cem\u003e8.9.4\u003c/em\u003e\u003c/li\u003e\n\u003cli\u003ePlugin(s): \u003ccode\u003e@nativescript/angular\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eNativeScript-Angular: \u003cem\u003e17.0.0\u003c/em\u003e\u003c/li\u003e\n\u003cli\u003eAngular: \u003cem\u003e17.0.8\u003c/em\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003cp\u003e\u003cstrong\u003eDescribe the bug\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eThis is a \u003cstrong\u003eruntime error on iOS only\u003c/strong\u003e.\u003c/p\u003e\n\u003cp\u003eWhen \u003ccode\u003eRouterExtensions.back()\u003c/code\u003e is called (e.g. on form submit after an async API operation) and the user \u003cstrong\u003elocks the phone or backgrounds the app within the same moment\u003c/strong\u003e, the navigation silently fails. On resume:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eThe component that triggered the back navigation is still on screen\u003c/li\u003e\n\u003cli\u003eThe \u003cstrong\u003enative ActionBar back button\u003c/strong\u003e (top-left iOS back chevron) is also completely unresponsive\u003c/li\u003e\n\u003cli\u003eNo exception is thrown, no crash, no error log\u003c/li\u003e\n\u003cli\u003eCalling \u003ccode\u003erouter.back()\u003c/code\u003e again on resume causes the call to repeat but navigation never completes\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eFrame.topmost().canGoBack()\u003c/code\u003e returns \u003ccode\u003etrue\u003c/code\u003e but \u003ccode\u003eFrame.topmost().goBack()\u003c/code\u003e has no visible effect\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe app is permanently stuck on that page until force-quit and relaunch.\u003c/p\u003e\n\u003cp\u003eConsole output observed during a single \"submit + lock phone\" cycle (3 resume attempts):\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eback Called\nKeyboard hidden\nsuper.back Called\nback Called\nKeyboard hidden\nsuper.back Called\nback Called\nKeyboard hidden\nsuper.back Called\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003ccode\u003esuper.back()\u003c/code\u003e fires even when the app is in the background. \u003ccode\u003eNavigationEnd\u003c/code\u003e never fires. Angular router \u003ccode\u003eurl\u003c/code\u003e still points to the source page on resume. \u003ccode\u003eFrame.topmost().goBack()\u003c/code\u003e on resume is silently ignored and the native back button stops responding entirely.\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003e\u003cstrong\u003eTo Reproduce\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eSetup:\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eA custom \u003ccode\u003eRouterExtensions\u003c/code\u003e subclass wrapping \u003ccode\u003eback()\u003c/code\u003e in a \u003ccode\u003esetTimeout\u003c/code\u003e for iOS keyboard dismiss (a common and necessary iOS pattern — navigating without first dismissing the keyboard causes visual glitches):\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"language-typescript\"\u003e@Injectable()\nexport class BaseRouterExtension extends RouterExtensions {\n IOS_KEYBOARD_DISMISS_DELAY = 150;\n\n override back(options?: BackNavigationOptions) {\n this.zone.run(() =\u0026gt; {\n hideKeyboard();\n if (isIOS) {\n setTimeout(() =\u0026gt; {\n super.back(options); // fires even when app is suspended\n }, this.IOS_KEYBOARD_DISMISS_DELAY);\n } else {\n super.back(options);\n }\n });\n }\n}\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eNavigation triggered by a signal/effect on API success:\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"language-typescript\"\u003eeffect(() =\u0026gt; {\n if (this.successOperation()) {\n this.navigateBack();\n }\n});\n\nasync navigateBack() {\n await this.onStopTextToSpeech();\n this.router.back();\n}\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e\u003cstrong\u003eSteps:\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eNavigate from Page A → Page B (a form/edit screen)\u003c/li\u003e\n\u003cli\u003eOn Page B, submit the form — this triggers an async API call, on success \u003ccode\u003erouter.back()\u003c/code\u003e is called\u003c/li\u003e\n\u003cli\u003eLock the phone (press power button) within ~150ms of the \u003ccode\u003eback()\u003c/code\u003e call\u003c/li\u003e\n\u003cli\u003eUnlock the phone and resume the app\u003c/li\u003e\n\u003cli\u003eObserve: still on Page B — the programmatic back and the native ActionBar back button both do nothing\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eMost reliable reproduction (near 100% hit rate):\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eThe \u003ccode\u003esetTimeout(150ms)\u003c/code\u003e creates a guaranteed window. Lock the phone immediately after tapping Submit before the toast or transition appears.\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003e\u003cstrong\u003eExpected behavior\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eEither:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eRouterExtensions.back()\u003c/code\u003e / \u003ccode\u003eFrame.topmost().goBack()\u003c/code\u003e called on resume should complete the interrupted navigation, OR\u003c/li\u003e\n\u003cli\u003eThe native \u003ccode\u003eUINavigationController\u003c/code\u003e state and NativeScript frame/Angular router state should be re-synced automatically on resume so that navigation can be retried from JS\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003cp\u003e\u003cstrong\u003eSample project\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eUnable to provide a Playground link as the issue requires a physical device lock action to reproduce (Simulator behaves differently for lock/sleep events). A minimal reproduction would be:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003ePage A navigates to Page B\u003c/li\u003e\n\u003cli\u003ePage B calls \u003ccode\u003eRouterExtensions.back()\u003c/code\u003e inside a \u003ccode\u003esetTimeout(150)\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eLock the physical device during that 150ms window\u003c/li\u003e\n\u003cli\u003eResume — Page B is stuck and native back button is unresponsive\u003c/li\u003e\n\u003c/ol\u003e\n\u003chr\u003e\n\u003cp\u003e\u003cstrong\u003eAdditional context\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eWhat was attempted as workarounds — none fully resolved the issue:\u003c/strong\u003e\u003c/p\u003e\n\nApproach | Result\n-- | --\nCheck Application.inBackground in setTimeout | Unreliable — flag not always set before setTimeout fires depending on lock timing\nOwn _isAppInBackground flag via suspend/resume events | Race condition — suspend event fires after navigateBack() call in some sequences\nSnapshot router.url before back(), compare on resume | URL comparison is accurate, but Frame.topmost().goBack() on resume still silently fails\nFrame.topmost().goBack() directly in resume handler | No visual effect — native back button is also unresponsive at this point\nRouterExtensions.navigateByUrl(previousUrl) on resume | Pushes a new page onto the stack instead of popping — incorrect behaviour\npage.on('navigatedFrom') to detect native completion | Does not fire when navigation is interrupted by lock\n\n\n\u003cp\u003eThe native \u003ccode\u003eUINavigationController\u003c/code\u003e appears to enter a broken/stuck state after a lock-interrupted navigation transition that cannot be recovered from the JavaScript layer with currently available APIs.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eQuestions for the team:\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eAfter a lock-interrupted \u003ccode\u003eUIViewController\u003c/code\u003e pop, is there a supported way to re-trigger or complete the navigation from JS?\u003c/li\u003e\n\u003cli\u003eIs the native \u003ccode\u003eUINavigationController\u003c/code\u003e instance exposed anywhere so we can call \u003ccode\u003epopViewControllerAnimated:\u003c/code\u003e directly as a fallback?\u003c/li\u003e\n\u003cli\u003eIs there a navigation transition completion hook (equivalent to \u003ccode\u003eUINavigationControllerDelegate.navigationController:didShowViewController:animated:\u003c/code\u003e) accessible from NativeScript?\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003eRelated issues:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ehttps://github.com/NativeScript/nativescript-angular/issues/1596 — Back navigation broken after suspend/resume in TabView + nested frame scenario — closed/fixed in 2018 via PR https://github.com/NativeScript/NativeScript/pull/6528. The current issue reproduces on a \u003cstrong\u003esimple single-frame stack with no TabView\u003c/strong\u003e and is not addressed by that fix.\u003c/li\u003e\n\u003c/ul\u003e\u003c/body\u003e\u003c/html\u003e\u003c!--EndFragment--\u003e\n\u003c/body\u003e\n\u003c/html\u003e","author":{"url":"https://github.com/yogi111","@type":"Person","name":"yogi111"},"datePublished":"2026-04-21T10:11:53.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/164/angular/issues/164"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:37262886-4ce5-40cc-ae35-256412ec3481 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | DBC0:1F4768:C35C29:10CAC2C:6A63B5CB |
| html-safe-nonce | d8ca2b07557093aeee56315c873ff952a4004b417448fd4bde7aea2215c403cd |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJEQkMwOjFGNDc2ODpDMzVDMjk6MTBDQUMyQzo2QTYzQjVDQiIsInZpc2l0b3JfaWQiOiIzODI3MTcwMjc0NjMyMjUwODI3IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | 20952b92e01e6f22ee5b8a855ea5d990f5c7036735c3eb78170de3ae10109550 |
| hovercard-subject-tag | issue:4301875319 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/NativeScript/angular/164/issue_layout |
| twitter:image | https://opengraph.githubassets.com/c032c29624122594837cd6e188006d0b586de67d99102418d8fb7707be888cc9/NativeScript/angular/issues/164 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/c032c29624122594837cd6e188006d0b586de67d99102418d8fb7707be888cc9/NativeScript/angular/issues/164 |
| og:image:alt | [iOS] RouterExtensions.back() fails silently after app lock/suspend mid-navigation — component stuck, native back button unresponsive on resume Environment CLI: 9.0.5 Cross-platform modules (@nativ... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | yogi111 |
| hostname | github.com |
| expected-hostname | github.com |
| None | b1a203abf5b8fb9010b42a32ce0f19fb6e11e656f254d0d3dcdba4b65a6961a6 |
| turbo-cache-control | no-preview |
| go-import | github.com/NativeScript/angular git https://github.com/NativeScript/angular.git |
| octolytics-dimension-user_id | 7392261 |
| octolytics-dimension-user_login | NativeScript |
| octolytics-dimension-repository_id | 302428305 |
| octolytics-dimension-repository_nwo | NativeScript/angular |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 302428305 |
| octolytics-dimension-repository_network_root_nwo | NativeScript/angular |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 3ae9132c55b60e2a8f9553322217eb369dd24575 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width