Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-27159] iOS: Ti.UI.WebView cannot load html files from cache

GitHub Issuen/a
TypeBug
PriorityCritical
StatusClosed
ResolutionFixed
Resolution Date2020-01-30T21:11:45.000+0000
Affected Version/sRelease 8.0.0
Fix Version/sRelease 9.0.0
ComponentsiOS
Labels8.0.0, engSchedule, ios, webview
ReporterNikos Poulios
AssigneeVijay Singh
Created2019-05-09T09:18:49.000+0000
Updated2020-01-30T21:11:45.000+0000

Description

*Note: Issue can be reproduced only on device, webview works as expected on simulator* New WebView fails to load html files stored in the app with the error:
default	11:34:49.407006 +0300	com.apple.WebKit.Networking	0x1075e8000 - NetworkResourceLoader::startNetworkLoad: (pageID = 5, frameID = 1, resourceID = 1, isMainResource = 1, isSynchronous = 0)
default	11:34:49.407054 +0300	com.apple.WebKit.Networking	Task <0AF948FB-871A-4EDD-A632-D67CBB10B3BC>.<1> resuming, QOS(0x19)
default	11:34:49.407103 +0300	com.apple.WebKit.Networking	[Telemetry]: Activity <nw_activity 16:2 [3A7E50A1-6DED-43AC-8750-A3865F7FCB48] (reporting strategy default)> on Task <0AF948FB-871A-4EDD-A632-D67CBB10B3BC>.<1> was not selected for reporting
error	11:34:49.407332 +0300	kernel	Sandbox: com.apple.WebKit(10340) deny(1) file-read-data /private/var/mobile/Containers/Data/Application/B7D5C2EF-634E-4F7E-A7EC-BAB4DDF48868/Library/Caches/307/platform_article_1112110663/article.html
default	11:34:49.407402 +0300	com.apple.WebKit.Networking	0x1075e8000 - NetworkResourceLoader::startNetworkLoad: (pageID = 5, frameID = 1, resourceID = 1, description = LocalDataTask <0AF948FB-871A-4EDD-A632-D67CBB10B3BC>.<1>)
error	11:34:49.407557 +0300	com.apple.WebKit.Networking	Task <0AF948FB-871A-4EDD-A632-D67CBB10B3BC>.<1> finished with error - code: 1
error	11:34:49.407608 +0300	com.apple.WebKit.Networking	Task <0AF948FB-871A-4EDD-A632-D67CBB10B3BC>.<1> load failed with error Error Domain=kCFErrorDomainCFNetwork Code=1 UserInfo={_NSURLErrorRelatedURLSessionTaskErrorKey=<private>, _NSURLErrorFailingURLSessionTaskErrorKey=<private>} [1]
default	11:34:49.408142 +0300	com.apple.WebKit.Networking	0x1075e8000 - NetworkResourceLoader::didFailLoading: (pageID = 5, frameID = 1, resourceID = 1, isTimeout = 0, isCancellation = 0, isAccessControl = 0, errCode = 1)
Reading iOS documentation I noticed that local files should be loaded using *loadFileURL* method as in https://github.com/appcelerator-modules/Ti.WKWebView/blob/master/ios/Classes/TiWkwebviewWebView.m#L198 but I don't see that in https://github.com/appcelerator/titanium_mobile/blob/master/iphone/Classes/TiUIWebView.m#L664

Attachments

FileDateSize
Resources.zip2019-06-10T13:03:35.000+00002259

Comments

  1. Vijay Singh 2019-05-31

    [~nipoul] Can you give a test case for mentioned issue? Thanks!
  2. Nikos Poulios 2019-06-10

    Hi, Sorry for the delay, I uploaded a test case. It turns out issue exists when trying to access a file stored in app's Cache directory. As you can see I have 3 cases:
       //All OK
       //webView.url = fileInResources.nativePath;
       
       //Does not work at all on device
       webView.url = fileInCache.nativePath;
       
       //works but no css on device
       // webView.setHtml(htmlInCache.read(), {
       // 	baseURL: cacheDir.nativePath
       // });
       
    When html and css file are on resources everything is ok, setting url to a path under Cache fails, and setHtml using file.read from cache works but again css fails to load. Again the only workaround working is using setHtml and referring to css by absolute path in resources. Is this an iOS restriction? Is there any workaround to have html in cache and use relative paths for css files? I tried using the code below in the SDK and it works but again allowingReadAccessToURL is fixed so it's not proper solution, ideally it would be set similarly to baseURL param in setHtml
           [[self webView] loadFileURL:[NSURL fileURLWithPath:path]
               allowingReadAccessToURL:[NSURL fileURLWithPath:[[[path stringByDeletingLastPathComponent] stringByDeletingLastPathComponent]];
       
    Thank you in advance
  3. Vijay Singh 2019-06-18

    Thanks for test case [~nipoul]. Webkit has restricted more on local file loading via WKWebView. Apple has given new API in WKWebView as mentioned in above comment [- (WKNavigation *)loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL](https://developer.apple.com/documentation/webkit/wkwebview/1414973-loadfileurl?language=objc). I think we should expose new API for local file Urls- setFileUrl({ url: "local file url", readAccessUrl: "read access file url" }) [~jquick] What you think? Thanks!
  4. Joshua Quick 2019-06-18

    [~vijaysingh], this sounds like a security feature on Apple's end. Particularly for MacOS where they don't want some rogue local HTML file having full filesystem access via a file:// scheme... and iOS inherited it. Android's WebView doesn't have an equivalent to the allowingReadAccessToURL API. Do we need to add a new API? What if we were to automatically assign the allowingReadAccessToURL to the given HTML file's directory path?
  5. Nikos Poulios 2019-06-18

    If possible It would be nice to be able to set allowingReadAccessToURL actually, so that assets like css files can be shared between files in cache using relative paths
  6. Vijay Singh 2019-06-18

    https://github.com/appcelerator/titanium_mobile/pull/10976 Test Case -
       (function() {
           var window = Ti.UI.createWindow();
               
           var createDirectory = function(f) {
               if(f && !f.exists()) {
                f.createDirectory();
               }
               
               return f;   
           };
           
           //Copy from Resources to cache folder
           var cacheDir = createDirectory(Ti.Filesystem.getFile(Ti.Filesystem.applicationCacheDirectory));
           var htmlDir = createDirectory(Ti.Filesystem.getFile(cacheDir.nativePath, 'html'));
           var cssDir = createDirectory(Ti.Filesystem.getFile(cacheDir.nativePath, 'css'));
           var resourceDir = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory);
       
           var htmlFile = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, 'html', 'example.html');
           var cssFile = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, 'css', 'test.css');
           
           var htmlInCache = Ti.Filesystem.getFile(cacheDir.nativePath, 'html', 'example.html');   
           var cssInCache = Ti.Filesystem.getFile(cacheDir.nativePath, 'css', 'test.css');
               
           htmlFile.copy(htmlInCache.nativePath);
           cssFile.copy(cssInCache.nativePath);
           
           var fileInResources = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, 'html', 'example.html');
               
           var webView = Ti.UI.createWebView({
               width: Ti.UI.FILL,
               height: Ti.UI.FILL,
               url: htmlInCache.nativePath,
               assetsDirectory: cacheDir.nativePath
           });
           
       
           window.add(webView);
           window.open();
       })();
       
  7. Keerthi Mahalingam 2019-08-05

    FR passed.please provide PR for 8_3_X
  8. Christopher Williams 2019-08-29

    While the FR may have passed, the unit tests for WebView are repeatedly failing for this PR. As such, I've bumped that back to failed QE/review. 4 WebView tests are timing out on this PR, and have been after several builds on Jenkins.
  9. Vijay Singh 2019-08-30

    It looks like iOS 13 broken WKWebView's API - (nullable WKNavigation *)loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL. See discussion https://forums.developer.apple.com/thread/120566 In iOS 12 it is working fine.
  10. Vijay Singh 2020-01-14

    PR - https://github.com/appcelerator/titanium_mobile/pull/11431
  11. Samir Mohammed 2020-01-23

    FR Passed, Waiting on Jenkins build
  12. Christopher Williams 2020-01-23

    merged to master for 9.0.0
  13. Lokesh Choudhary 2020-01-30

    Verified the fix with SDK 9.0.0.v20200130075800. Closing.

JSON Source