-
Notifications
You must be signed in to change notification settings - Fork 24.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[iOS] JS Timers (setTimeout) don't fire when app is launched in background #38711
Comments
|
|
In my case, I was able to work around it by adding this code to my app (e.g. in AppViewController.loadView()):
|
@mikelehen Hi, I made a PR to fix this, please see #39347 , Does it work for you? |
@zhongwuzw Thanks for making the PR! Yes, it does work, though I am wondering if there's a potential race condition now that it's running async. Left a comment on the PR. Either fix (yours or the one I suggested) seems to resolve my use case though. Thanks for working on this! |
…39347) Summary: Fixes #38711 ## Changelog: [IOS] [FIXED] - Fix timer background state when App is launched from background Pull Request resolved: #39347 Test Plan: Please see #38711 Reviewed By: cipolleschi Differential Revision: D49101979 Pulled By: dmytrorykun fbshipit-source-id: e25b182539f39e4465fa40e51288d88c68967b31
Thanks so much @zhongwuzw, @cipolleschi, and @Titozzz! 🙏 |
@mikelehen, @zhongwuzw Did you also run into this issue on Android? I am trying to implement remote background pushes to wake up my app when it is force quit. I have it mostly working using react-native-firebase and this merged PR, but I noticed that a |
@cheehieu Sorry, my react native app is iOS-only so I can't speak to any Android issues. Good luck! |
Description
Summary:
Timers (setTimeout, etc.) don't run when iOS launches your React Native app in the background, because RCTTiming initializes _inBackground=NO.
More detail: #23674 added support for iOS timers to run when the app is in the background, but I believe I'm running into a case not covered by this code. In particular I'm implementing "background updates" for my app. If the app is not running when the background update arrives (e.g. after a reboot, or presumably if iOS has killed the app to free resources), iOS will launch the app from scratch in the background (as opposed to the more normal background case of being launched in the foreground and then later transitioning to the background which is handled by appDidMoveToBackground), and in this case timers (setTimeout, etc.) do not work.
It looks like if I change RCTTiming to initialize _inBackground=YES here, then my background code works as expected. But this isn't a good fix because in the normal foreground app launch case
_inBackground
will still beYES
so it will end up using the "background" timers logic until you transition to background and then back to foreground.I think the correct fix would be something like:
But that can only be called from the main thread. So you'd need to dispatch to the main thread, and I'm not sure how to do that safely without introducing race conditions.
Vague repro:
Sorry, to repro this you need to send specific push notifications from a backend server to the app. And you also need to potentially wait ~3 hours for iOS to run your background code. So I can't provide a direct repro.
RCTEventEmitter
event that I listen for in JavaScript, in order to run my background update code.Result: My JavaScript code handles that event and successfully runs in the background, but any calls to
setTimeout()
orsetInterval()
do not work (my callbacks never run).React Native Version
0.72.0
Output of
npx react-native info
info Fetching system and libraries information...
System:
OS: macOS 13.4
CPU: (10) arm64 Apple M1 Max
Memory: 72.59 MB / 32.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 18.16.0
path: ~/.nvm/versions/node/v18.16.0/bin/node
Yarn:
version: 1.22.19
path: ~/.yarn/bin/yarn
npm:
version: 9.5.1
path: ~/.nvm/versions/node/v18.16.0/bin/npm
Watchman: Not Found
Managers:
CocoaPods: Not Found
SDKs:
iOS SDK:
Platforms:
- DriverKit 22.4
- iOS 16.4
- macOS 13.3
- tvOS 16.4
- watchOS 9.4
Android SDK: Not Found
IDEs:
Android Studio: 2022.2 AI-222.4459.24.2221.9862592
Xcode:
version: 14.3.1/14E300c
path: /usr/bin/xcodebuild
Languages:
Java:
version: 20.0.1
path: /usr/bin/javac
Ruby:
version: 3.2.2
path: /opt/homebrew/opt/ruby/bin/ruby
npmPackages:
"@react-native-community/cli": Not Found
react:
installed: 18.2.0
wanted: 18.2.0
react-native:
installed: 0.72.1
wanted: ^0.72.0
react-native-macos: Not Found
npmGlobalPackages:
"react-native": Not Found
Android:
hermesEnabled: Not found
newArchEnabled: Not found
iOS:
hermesEnabled: Not found
newArchEnabled: Not found
Steps to reproduce
Sorry, I am not providing specific repro steps since it would rely on backend code sending push notifications to the app. My repro steps also rely on rebooting the device and waiting 3 hours, which isn't a very friendly repro. So I'm providing this bug in the hope that it is useful to somebody, but I understand it is not directly actionable. I understand if that means this bug gets closed. At least it will be in the searchable history of the repro.
Snack, screenshot, or link to a repository
Unavailable, sorry. See above.
The text was updated successfully, but these errors were encountered: