Skip to content
This repository has been archived by the owner on Oct 1, 2018. It is now read-only.

WKWebView: Inability to update on actual iPhone, though Simulator works #85

Closed
SpaceviewMob opened this issue Jan 12, 2016 · 41 comments
Closed

Comments

@SpaceviewMob
Copy link

After deploying a new version, the simulator can update itself without restarting the app (without any issues), but for a physical iPhone, the following error occurs:

file:///var/mobile/Containers/Data/Application/248629FC-C77B-4A89-917F-B286E7F1C0B0/Library/Application%20Support/vu.space.mobile/cordova-hot-code-push-plugin/2016.01.12-10.17.28/www/index.html
[Error] Failed to load resource (index.html, line 0)

If I manually shut down the app and re-open it, it will have the updated code.

Tested on an iPhone 6 Plus, iOS 9.2 - same specs for Simulator.

One possible wrench thrown in the mix might be that we're using cordova-plugin-wkwebview-engine.

@SpaceviewMob
Copy link
Author

This occurs whether manually calling chcp.installUpdate() or allowing it to occur automatically on "resume".

@nikDemyankov
Copy link
Member

Understood, will try to reproduce it on my device.

@nikDemyankov
Copy link
Member

Yes, it seems the problem is with cordova-plugin-wkwebview-engine. For some reason it doesn't load index page from the external storage.

@hussfelt
Copy link

hussfelt commented Feb 8, 2016

@nikDemyankov First off: this is just pure awesome stuff.
I just want to get this running with WKWebView, could you point me in the right direction or is there anything else I can help with?

@hussfelt
Copy link

hussfelt commented Feb 8, 2016

@nikDemyankov FYI My issue is currently the same, but I can't even restart the app and get the new resources - we just get a blank page after an update is made.

@nikDemyankov nikDemyankov added this to the v1.3.0 milestone Feb 8, 2016
@hussfelt
Copy link

hussfelt commented Feb 8, 2016

@nikDemyankov Confirmed manual update in simulator without WKWebView.

@nikDemyankov
Copy link
Member

@hussfelt thanks. Not sure at the moment. I just need to sit down and check what is wrong and how it can be fixed. It's more the timing issue for me. But now I'm starting to plan, what to be done in the next release, so will work on that one soon.

@hussfelt
Copy link

hussfelt commented Feb 8, 2016

@nikDemyankov tell me where to pour the 🍺 !

@nikDemyankov
Copy link
Member

I think it has something to do with the bug in WKWebView - https://issues.apache.org/jira/browse/CB-10237 . Although, it does work fine on emulator (both iOS 8 and 9), but it doesn't reload the page automatically on the real device (iOS 9). It just silently ignores reload request and that's it. Will keep digging.

@hussfelt
Copy link

@nikDemyankov <3 Thanks! You are plain awesome. 🎅

@Manduro
Copy link
Contributor

Manduro commented Feb 17, 2016

@nikDemyankov Could a fix be to use some sort of local proxy server for those requests? Something like this: https://github.com/shazron/CB-8838/tree/master/plugins/cordova-labs-local-webserver
Although this only serves the www folder by default, maybe it could work the same way for the folder with chcp updates?

@nikDemyankov
Copy link
Member

@Manduro Yes, that could help. There is another WKWebView plugin, which uses that approach (or something similar). The trick is to make it work with external www folder. And to restart it, when update is installed. I just don't want to make things more complicated then they are already...

@Manduro
Copy link
Contributor

Manduro commented Feb 17, 2016

@nikDemyankov I've looked into that plugin as well, but it is for pre cordova-ios 4 and won't be supporting it as the new cordova-plugin-wkwebview-engine plugin is officially supported for 4.

I understand you don't want it any more complicated, but I do think that WKWebView is very important to support as it comes with lots of benefits.

@nikDemyankov
Copy link
Member

@Manduro that's true :)

@jboothe
Copy link

jboothe commented Mar 24, 2016

@nikDemyankov has there been a resolution to this? All files except for index.html update on iOS9 devices. I was a day away from pushing to the app store and ran into this "stale index.html" issue. Let me know if we are close.

Thanks a bunch for an amazing plugin! ☀️

@hussfelt
Copy link

@jboothe Am I understanding you correctly that everything works in combination with the WKWebView except it does not update the index.html file?

In that case this could clearly be a documented tradeoff - I'd live with having to update the app through AppStore for index.html fixes until we have a solution for the core issue...

@nikDemyankov
Copy link
Member

@jboothe no, unfortunately at the moment I couldn't fix that. Not sure even how to do it correctly. There is an idea from @Manduro to use local web server for showing pages. Haven't tried it yet, but it scares me a little: kind of hack-ish way...

@hussfelt No, the problem is not with the documentation. Index page is updated properly without WKWebView. The problem is that for each new release plugin creates new folder (more details here). On simulator WKWebView has no problem with changing working directory after the update. But on a real device - it does. If it started showing files from /2015.12.01-12.01.33/www/ - it's not gonna switch to /2015.13.01-15.01.00/www/ until the full restart.

@jboothe
Copy link

jboothe commented Mar 24, 2016

Perhaps we have different issues since my app does not employ the cordova-plugin-wkwebview-engine.

To be clear, I experience the following on iOS 9 devices but not in the emulator: When following Nik's 6 steps here, all but the index.html page update and updates only occur when closing and reopening the app.

Oddly, performing a cordova build and cordova run would not show ANY changes of any file on the device but did show in the emulator. Only a cordova-hcp build and cordova-hcp deploy would update the app (again, with exception to index.html and a close/reopen was needed). Changing the ios-CFBundleVersion had no impact.

@nikDemyankov nikDemyankov changed the title Inability to update on actual iPhone, though Simulator works WKWebView: Inability to update on actual iPhone, though Simulator works Mar 24, 2016
@nikDemyankov
Copy link
Member

Renamed the thread to better define, what it is about :)

@jboothe yes, I think it relates to your question #125 . We can continue discussion about your problem in there. I'll try to reproduce it on my iOS 9 device. But I think it has something to do with the configuration files setup.

bluoma pushed a commit to bluoma/cordova-hot-code-push that referenced this issue Mar 24, 2016
@bluoma
Copy link

bluoma commented Mar 24, 2016

nikDemyankov wrote: “On simulator WKWebView has no problem with changing working directory after the update. But on a real device - it does. If it started showing files from /2015.12.01-12.01.33/www/ - it's not gonna switch to/2015.13.01-15.01.00/www/ until the full restart.”

Hi nik.
That’s a documented ‘feature’ of the WkWebView since ios 9.0:

  • (WKNavigation *)loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL

Parameters
URL The file URL to navigate to.
readAccessURL The URL to allow read access to.
Return Value
A new navigation for the given file URL.

Discussion
If readAccessURL references a single file, only that file may be loaded by WebKit. If readAccessURL references a directory, files inside that file may be loaded by WebKit.

In fact if you think about it, it’s not just that an update will fail to show up until the user performs a full restart, it’s also true that the unpacking of the bundled www inside the app to the initial hotcode push external www folder won’t be used until after a full restart. So, the fix needs to happen in two places. On startup and on update.

And the only fix I can think of, aside from re-instantiating the wkwebview with the new updated file url and all plugins, is to always use the same well-known folder to load files from. I guess that means on an update, you would have to delete the current files that are being “served” and copy the new ones into the same folder. If the user was doing something important, I’m thinking that could lead to some data corruption / race conditions. But if you could inform the user that this was about to happen and ensure that they weren’t doing anything important during an update, it might be passable. Not sure about rollbacks and update errors….

I forked your excellent repo and implemented this hack. Works on an ios 9.2 ipad and Cordova 5.0.0 with Cordova ios 4.0.1 and cordova-plugin-wkwebview-engine 1.0.2 and cordova-hot-code-push-plugin 1.2.5

@nikDemyankov
Copy link
Member

Hi @bluoma ,

And the only fix I can think of, aside from re-instantiating the wkwebview with the new updated file url and all plugins, is to always use the same well-known folder to load files from. I guess that means on an update, you would have to delete the current files that are being “served” and copy the new ones into the same folder. If the user was doing something important, I’m thinking that could lead to some data corruption / race conditions. But if you could inform the user that this was about to happen and ensure that they weren’t doing anything important during an update, it might be passable. Not sure about rollbacks and update errors….

Actually, the first versions of the plugin was doing exactly that :) But I had to move to "new release -> new folder" scheme because of the problems you described, plus:

  • There was a css caching issue: web view didn't want to reload css files. In order to see the changes in them you had to change the path of the css file. For example, add ?timestamp parameter to it's path.
  • No normal backup system. Right now previous version is used as a backup in case, if current one is broken.

So, moving to "new release -> new folder" scheme solved some nasty problems and made plugin much more stable. But, unfortunately, brought problem with the wkwebview. Didn't know about it, when migrated to the new scheme...

@Manduro
Copy link
Contributor

Manduro commented Mar 25, 2016

@nikDemyankov @bluoma Couldn't this be fixed by putting the release folders inside a common chcp folder? Or does the readAccessURL disallow subdirectories as well when it references a directory?

Another possibility might be to put the index.html's in their own folder, using index-{release}.html files, with some sort of solution for file references inside index.html.

@bluoma
Copy link

bluoma commented Mar 25, 2016

@Manduro "does the readAccessURL disallow subdirectories as well when it references a directory?"
Well, every release subdirectory is a child of "cordova-hot-code-push-plugin/". So I think the answer is yes, it disallows subdirectories.

Now that I re-read my original post, I think I should have said that this behavior of wkwebview, not to allow reloading from a different readAccessURL, is undocumented behavior. Maybe someone should file a radar:// on Apple to correct the docs or allow reloads from a different folder. ??

@nikDemyankov
Copy link
Member

Couldn't this be fixed by putting the release folders inside a common chcp folder? Or does the readAccessURL disallow subdirectories as well when it references a directory?

Basically, they are all already inside common chcp folder. But maybe setting allowingReadAccessToURL to that common folder might help. Should try that, thanks for the idea.

@jboothe
Copy link

jboothe commented Mar 26, 2016

Here's Telerik's overview of the good, bad & ugly of Cordova WKWebView Plugin. ...might provide some insight into solving this problem.

@bluoma
Copy link

bluoma commented Mar 30, 2016

@nikDemyankov just noticed that if the content folder is created under the application's tmp/ directory, this error doesn't occur. So if you edit HCPFilesStructure.m and change the 3rd line below to reference "tmp/":

// construct path to the folder, where we will store our plugin's files
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *supportDir = [fileManager applicationSupportDirectory];

I don't see the error:

Sandbox: com.apple.WebKit(829) deny(1) file-issue-extension
Sandbox: com.apple.WebKit(830) deny(1) file-read-data

and reloads happen fine onResume. Seems like WebKit2's sandbox rules need fixing. I don't know if using /tmp is really a workable solution. FYI, I also tried "Documents" and "Library/caches" and those both fail for me.

@nikDemyankov
Copy link
Member

@bluoma thanks for the info, will check it out. But tmp folder is not a great thing, since it can be removed by the OS when free space is needed. So the app can end up without his www folder and would have to use the one from the assets.

@nikDemyankov
Copy link
Member

Good news everyone: seems like some sort of solution has been found. Currently all release folders are stored like this:

/some/path/Library/Application Support/<PACKAGE_NAME>/cordova-hot-code-push-plugin/<RELEASE_VERSION>/www/index.html

When new update comes - new <RELEASE_VERSION> folder is created and webview loads index.html from it.

By default, wkwebview doesn't allow to switch to another folder. In the CDVWKWebViewEngine.m WK plugin set's readAccessURL to the folder, that is 1 level up to the index.html.

So, the fix is to set it pointing to /some/path/Library/Application Support/<PACKAGE_NAME>/cordova-hot-code-push-plugin/. This way wkwebview will allow loading index.html from different subfolders.

Thanks @Manduro for pointing in the right direction. Now I need to figure out, how to set this readAccessURL to point to the correct folder in the chcp, instead of manually changing CDVWKWebViewEngine.m from the Xcode.

@Manduro
Copy link
Contributor

Manduro commented Mar 31, 2016

@nikDemyankov Great news! Seems like an easy solution :)

@MarcBT
Copy link

MarcBT commented Apr 5, 2016

Hi @nikDemyankov. First thanks for the awesome work !
If I understood properly, the approach you mention on your previous comment is only valid for Cordova WKWebView Plugin, not for Telerik WKWebview plugin, right ?

@nikDemyankov
Copy link
Member

Hi, @MarcBT. Thanks :)

Yes, that is correct: for Telerik WKWebView there, probably, should be another fix. As we discussed in #127 - it stopped working after I switched from setting startPage to wwwFolder. Reason for that was to support # in the index page.

I will try to upload in the dev branch fix for wkwebview today, and then will start looking into telerik version.

@MarcBT
Copy link

MarcBT commented Apr 6, 2016

Ok, thanks for the fast answer. Have a good day !

nikDemyankov added a commit that referenced this issue Apr 6, 2016
… we need to set the correct readAccessURL, or WKWebView is not gonna load our updates. Work in progress.

#85
nikDemyankov added a commit that referenced this issue Apr 7, 2016
…on the presence of the cordova-plugin-wkwebview-engine.

#85
nikDemyankov added a commit that referenced this issue Apr 7, 2016
nikDemyankov added a commit that referenced this issue Apr 7, 2016
@nikDemyankov
Copy link
Member

Okey, cordova-plugin-wkwebview-engine should now work with chcp. Uploaded a fix in the dev/1.3.0 branch. Want to add some more stuff before releasing new version. But you can try it out already, if you want.

@nikDemyankov
Copy link
Member

Released in v1.3.0. CHCP plugin should now work with cordova-plugin-wkwebview-engine. If not - please, reopen the issue.

@barocsi
Copy link

barocsi commented May 2, 2016

@nikDemyankov I can only use Teleriks wkwebview, can is it possible to ship a fix for that as well?

@nikDemyankov
Copy link
Member

@barocsi yes, but can't give you any dates when... There is already task for this: #98

@hirbod
Copy link

hirbod commented Aug 25, 2016

So this is not working for me, at least not with https://github.com/driftyco/cordova-plugin-wkwebview-engine

This is the first WkWebview Engine, with a XHR polyfill hack, that allows remote and local XHRs with a breeze. I don't know if its possible for you to fix this.

I have 1.4.0 installed, the simulator will update, but not the real device.

@nikDemyankov
Copy link
Member

@hirbod have you tried with original wkwebview plugin? Also, have you tried to launch the app via Xcode instead of console (just as an experiment)?

@hirbod
Copy link

hirbod commented Aug 25, 2016

First question: no, I did not. Cause it does not work for my use case (no local XHR on file:/// possible = useless, as I can't use any framework)

Second: No, I will try and give you a feedback.

@cvaliere
Copy link

cvaliere commented Sep 5, 2016

@hirbod hi, it seems that we are using same technologies... :)
Did you find a solution, we have the same problem with driftyco's plugin

@hirbod
Copy link

hirbod commented Sep 5, 2016

@cvaliere no, I did not. I am sticking to the simulator currently, so "real time testing" on a real device is not possible currently. Lauching with or without Xcode did not change anything @nikDemyankov

In my case, it's not a big deal, as I am developing inside simulator 99% of time, but it would be a nice to have.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

10 participants