-
Notifications
You must be signed in to change notification settings - Fork 401
Allow wkwebview to continue running (and processing javascript!) when app is in the background #45
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
Conversation
|
This update solves the problem most of the time but wkwebview can still be suspended overly eagerly when it is considered to be idle, which would be ideal for a native app that was just showing a webpage but is not good for hybrid apps that rely upon the webview for processing. If you were polling location every 5-10 seconds then this PR alone would probably do the job. In my case I am playing audio in the background so it may be 5 minutes or more between activity in the webview as once a file is playing there is nothing else to do until the next track needs to start and wkwebview can sometimes be suspended causing play back to stop until the app is brought back to the foreground. I have found two possible solutions that add to this pull request that I am currently testing. I prefer option 1 as it seems
|
tie background operation to config.xml WKEnableBackground setting. Default background mode to NO which will immediately suspend GCDwebserver and allow wkwebview to be eagerly suspended if the OS wants to.
|
I have been testing option 1 above for the last day and it has been working consistently well so have updated this PR with an additional commit. I have tied background operation to the WKEnableBackground preference in config.xml with it defaulting to off, this lines up with the changes for GCDWebserver background operation also being tied to this preference in my other complimentary PR. There should be no further need for the background mode plugin once these PR's are merged. Note: This does NOT artificially keep your app alive if it is idle, it can and will still be suspended by the OS if it is truly idle in the background. This simply attaches to a keywindow so that wkwebview is still considered to be active in the background and not instantly frozen and then adds the same config parameter as the background plugin does to allow for ongoing processing in the background. Without the second part the OS can be overly eager in deciding your app is idle as discussed in earlier comments. This does NOT spoof activity by playing silent audio like the background mode plugin. You still need a legitimate reason for background activity, the associated capability enabled in xcode and actual activity of that type for your app. What this does do is allow you too play audio in the background, even long running audio with your app being suspended between audio tracks, or to poll for location, or conduct background fetch tasks with appropriate spacing in between activities without being incorrectly suspended. This removes the reasons for the background mode plugin potentially causing app store rejections. |
|
I have a fork with all 3 of my submitted PR's integrated for anyone that wants to try it in your config.xml you can set these new preferences use dark keyboard appearance on iOS, defaults to false if not specified
set a custom port, defaults to 8080 if not specified, ensure to update your
enable background mode, defaults to false if not specified
|
|
FYI - I have built tested and submitted updates for several of my own apps using my fork with all commits from the 3 PR's that I have open. All updates have been accepted and published to the app store without issue. |
|
Looks promising @ghenry22 , I will test it for our usecase - background notification handling sometime next week. |
|
@ghenry22 Could a similar change be made to the original https://github.com/apache/cordova-plugin-wkwebview-engine? (we can't use the Ionic version because code-push doesn't work with it) I've also found that background JS execution in WKWebView is incredibly slow compared to UIWebView (our use case is Bluetooth LE data transfer). Does this change help with that? Thanks. |
|
@ghenry22, I had to do the same for our use case to prevent the webview from being suspended since our app is being woken up by polling location every 5 - 10 seconds. The app used to hang on the splashscreen. However all I did was to add this configuration option |
|
@cryo243 - that isn't enough on it's own for a few reasons.
SO with this fork your app can run in the background, as it should, the OS can still suspend it when it wants to and it honors background capabilities. You can also go from background to foreground and the GCDwebserver will CHECK for any TCP socket errors and if it finds an error will reconnect the socket so you don't get connection errors immediately after coming back to the foreground. |
|
Thanks @ghenry22 . Number 3 is exactly what we were experiencing. When the app is brought forward, local images won't display sometimes. |
|
@cryo243 yeh that is the bug with GCDwebserver where it doesn't try to reconnect a disconnected socket on resume It's fixed in my branch. |
|
Thanks, just merged #79 which had some keyWindow changes, but not all the stuff in this PR. Will leave this open for later |
|
@mlynch, all these PR's do is allow the webview to continue processing javascript when in the background UNTIL the OS decides to suspend it as with any other app. Without this any app that has any kind of background processing will not work. One of my app is a music player so for me without these changes I could not use the ionic fork of wkwebview. There are also fixes to GCDWebserver incorporated here. There is a known bug with GCDwebserver which has been open for some time where sockets can enter an error state while in the app is in the background and are not checked for errors on resume so the webview has a dead socket and cannot retrieve any resources from the GCDwebserver. There is an open PR against GCDwebserver for some time with fixes for this. I have incorporated the basics of that PR into this work as well as I was observing that issue where my app would come back from background mode and, for example, ionicons and locally storage images would just show a blank square or not found icon until the app was hard closed and restarted to force the tcp connection to the webserver to be reset. |
|
Hi @ghenry22 , my app has exactly the problem described by you. When it is in the background for about a day, it will remain stuck on the splashscreen, probably due to the GCDWebServer bug. This bug drove me crazy for months, and when I found your fork I thought I had finally found the solution. I replaced the Ionic WebView with yours and put it into production, but my users still complain about this bug. So I ask you, since you worked on it, did you find a way to faithfully reproduce the bug? A series of steps that manifest it? I have tried many different things, but I can not reproduce it systematically, the only way I have is not to use the app for a couple of days and see that it does not open. I ask as I can not reproduce it, I can not understand when it's solved, and my project manager keeps asking for information. My app does not make location or audio background work, it have only the OneSignal plugin for push notification (which I think do some stuff in background). |
|
I doubt any app will remain running in the background for a day without the OS killing it. This fork does not override the default OS app suspension behaviour when it considers the app idle so you need to have legitimate background activity to keep it alive. This is usually background audio or Geo-location. I don’t think intermittently issuing notifications will do it. As for getting stuck at the splash screen get safari connected up so you can get debug logs and try to reproduce and see what it is hanging on, this is not an issue I have seen before. |
|
For me it's fine that the SO kills my app at some point in time, the only thing I want is that then it starts and does not remain stuck on the splashcreen. The bug on the GCDWebServer that does not reopen the failed connections seems to be responsible for this. I think it's exactly the problem described by @cryo243 in #45 (comment) Do you have solved the bug in GCDWebServer? Is this the commit that introduce it? ghenry22@526b031 |
|
That reconnection bug is fixed in this fork, you just have to make sure to set the enable background setting in config.xml . Again though this shouldn’t really cause an issue with the splash screen, If you could capture whatever error is being thrown when I gets stuck that might help to narrow down the problem you are having. |
|
I tried in many ways to get the error, but starting the app from XCode never shows the bug, and I can not connect the safari debugger until the app does not start, and at that time the console is gone. .. I set I think the problem is this -> #57 (comment) |
|
@Maqix, maybe a suggestion to reproduce the error. Run your app once and then force close it (on iOS just swipe it away) and don't open it for at least a day. Depending on how often you background service runs and on when the OS decides to kill your app you should be able to see it hanging |
|
Thanks for the answer @cryo243, right now, this is the only way I know to reproduce it, I just wonder if there is a faster method to speed up the debugging cycle (edit, check). Did you manage to solve it on your side? EDIT: I just found this, the lock/unlock trick is interesting swisspol/GCDWebServer#292 And this: swisspol/GCDWebServer#299 |
|
Any Updates here? We built an app which makes heavy usage of background modes / geolocation and are constantly facing strange issues which seems to be based on the issue described in this PR. |
|
@iliraga just use my fork here: refer to the config.xml settings required in the above posts. This should solve any issues with background usage. |
|
Hi all, I have installed @ghenry22 's fork and the problem is reduced (it still happen, but less times)... Did not find a way to reproduce it in a reproducible way 😞 |
|
@ghenry22 How reliable is your fork? We will release a version to the app stores in a couple of days and currently i'm not sure whether to switch to your version or not. |
|
I’ve had multiple apps in the store for months with it with no issues. Seems solid to me. |
|
Okay thanks @ghenry22 we will submit the version today - it's quite a big project so let's find out whether it will work properly 😃 |
|
It’s really just some small but important fixes to the ionic webview, hope it works for you, it solved my |
|
@jacquesdev @mlynch If it will actually get merged I will gladly resolve the conflicts that have occured after I submitted this. Otherwise its kind of a waste of time to resolve them just for this to continue to sit here not being merged. You can use my fork at https://github.com/ghenry22/cordova-plugin-ionic-webview which has my PR's and several others already merged and good to go. |
|
Hi @cryo243 , I have integrated this plugin https://github.com/cryo243/cordova-plugin-ionic-webview the splash screen stuck issue is solved but one new issue is occurring - The application when comes from background to foreground after 2 or 3 hours the application is started but the images which are in assets folder is not displaying on the view. I need to restart my application manually to load those images. |
|
Hi @chinmay-ksolves ,
|
This stops wkwebview from instantly stopping all javascript processes when app is sent to the background by attaching it to a key window so that it is still seen as "active" even when in the background vs the default of instantly being considered inactive as it has no active window attached.
Makes it behave the same as UIWebview when app is sent to the background and removes the need for the background mode plugin making things more predictable for developers.
This DOES NOT keep the app alive beyond the normal OS enforced limits for background run time etc, you still need to have an appropriate background capability enabled in xcode and if you app is actually idle it will still be suspended exactly as it should.