{ "id": "173003", "key": "TIMOB-26860", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "19882", "name": "Release 8.0.0", "archived": false, "released": true, "releaseDate": "2019-03-14" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2019-03-07T14:27:50.000+0000", "created": "2019-02-14T23:22:19.000+0000", "priority": { "name": "Critical", "id": "1" }, "labels": [ "WebView", "html", "ios", "regression" ], "versions": [ { "id": "19882", "name": "Release 8.0.0", "archived": false, "released": true, "releaseDate": "2019-03-14" } ], "issuelinks": [], "assignee": { "name": "vijaysingh", "key": "vijaysingh", "displayName": "Vijay Singh", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2019-03-13T02:00:48.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10206", "name": "iOS", "description": "iOS Platform" } ], "description": "*Summary:*\r\nWhen loading an HTML string to a {{WebView}} via its \"html\" property, it is no longer able to access the app's local files under the \"Resources\" directory as of Titanium 8.0.0.RC.\r\n\r\n*Steps to reproduce:*\r\n# Create a Classic \"Default Project\" app.\r\n# Replace the \"app.js\" code with the below code.\r\n# Build with Titanium 8.0.0 and run on iOS.\r\n# Notice that an image failed to load within the web view.\r\n# Build with Titanium 7.5.x and run on iOS.\r\n# Notice that the image successfully loaded within the web view.\r\n\r\n{code:javascript}\r\nvar htmlText =\r\n\t\t'' +\r\n\t\t'' +\r\n\t\t'\t
' +\r\n\t\t'\t\t' +\r\n\t\t'\t' +\r\n\t\t'\t' +\r\n\t\t'\t\tLocal Image File
' +\r\n\t\t'\t\t' +\r\n//\t\t'\t\t' +\r\n\t\t'\t' +\r\n\t\t'';\r\n\r\nvar window = Ti.UI.createWindow();\r\nvar webView = Ti.UI.createWebView({\r\n\thtml: htmlText,\r\n});\r\nwindow.add(webView);\r\nwindow.open();\r\n{code}\r\n\r\n*Note:*\r\nLoading local resource files via {{app://Resources/}} also fails to load on iOS in Titanium 8.0.0.RC, but worked in older versions. Note that this URL scheme is undocumented and is not supported on Android.\r\n\r\n*Work-Around:*\r\nOn iOS, the {{WebView.setHtml()}} method supports a 2nd argument where you can provide a \"baseURL\" parameter. This parameter allows you to set the directory (or URL) that file paths should be relative to. So, the below will work-around the problem.\r\n\r\n{code:javascript}\r\nvar htmlText =\r\n\t\t'' +\r\n\t\t'' +\r\n\t\t'\t' +\r\n\t\t'\t\t' +\r\n\t\t'\t' +\r\n\t\t'\t' +\r\n\t\t'\t\tLocal Image File
' +\r\n\t\t'\t\t' +\r\n//\t\t'\t\t' +\r\n\t\t'\t' +\r\n\t\t'';\r\n\r\nvar window = Ti.UI.createWindow();\r\nvar webView = Ti.UI.createWebView({\r\n// Don't do this.\r\n//\thtml: htmlText,\r\n});\r\n// Do this. It will work-around the 8.0.0.RC bug.\r\nwebView.setHtml(htmlText, {\r\n\tbaseURL: Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory).nativePath,\r\n});\r\nwindow.add(webView);\r\nwindow.open();\r\n{code}\r\n\r\n\\\\\r\n----\r\n*Original Bug Report Below*\r\n----\r\nThe upcoming change in 8.0 from UIWebView to WKWebView is major and because of my reliance on the WebView I wanted to start testing this. There is a ticket TIMOB-26095 that indicates the transition is complete and tested, but there are so many use cases that are not included in the sample tests provided that I have major concerns.\r\n\r\nFor example, I cannot get local resources like images to be rendered inside the WebView.\r\n\r\nTest case:\r\n{code:javascript}\r\nvar win = Ti.UI.createWindow();\r\n\r\nvar html = '';\r\n\r\nvar webview = Ti.UI.createWebView({\r\n html: html\r\n});\r\n\r\nwin.add(webview);\r\nwin.open();\r\n{code}\r\n\r\nWorks fine in SDK 7.5.1, but the image does not load in 8.0.\r\nAm I doing something wrong? Is there a low-level change that I should know about for this?", "attachment": [ { "id": "66184", "filename": "Screen Shot 2019-02-24 at 9.54.23 AM.png", "author": { "name": "chrishaff@gmail.com", "key": "chrishaff@gmail.com", "displayName": "chrishaff@gmail.com", "active": true, "timeZone": "America/New_York" }, "created": "2019-02-24T15:14:33.000+0000", "size": 745880, "mimeType": "image/png" } ], "flagged": false, "summary": "iOS: HTML assigned to WebView \"html\" property is unable to access app's local files as of 8.0.0.RC", "creator": { "name": "mdelmarter", "key": "mdelmarter", "displayName": "Matthew Delmarter", "active": true, "timeZone": "Pacific/Auckland" }, "subtasks": [], "reporter": { "name": "mdelmarter", "key": "mdelmarter", "displayName": "Matthew Delmarter", "active": true, "timeZone": "Pacific/Auckland" }, "environment": "Ti SDK 8.0.0.v20190130052111", "closedSprints": [ { "id": 1118, "state": "closed", "name": "2019 Sprint 5", "startDate": "2019-02-24T18:36:06.435Z", "endDate": "2019-03-08T18:36:00.000Z", "completeDate": "2019-03-07T22:19:47.057Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "446191", "author": { "name": "sdarda", "key": "sdarda", "displayName": "Sharif AbuDarda", "active": false, "timeZone": "Asia/Dhaka" }, "body": "Hello [~mdelmarter], I was able to verify the issue here. Tested with SDK 8.0.0.v20190219113758 and 7.5.1.v20190124152315(where it works). [~jquick], [~vijaysingh], [~jvennemann], Is any change made on how the webview handle local resources? Thanks.", "updateAuthor": { "name": "sdarda", "key": "sdarda", "displayName": "Sharif AbuDarda", "active": false, "timeZone": "Asia/Dhaka" }, "created": "2019-02-20T16:59:27.000+0000", "updated": "2019-02-20T16:59:27.000+0000" }, { "id": "446201", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~sdarda], the iOS {{Ti.UI.WebView}} implementation in Titanium has completely changed in 8.0.0 to use the native {{WKWebView}} instead of Apple's now deprecated {{UIWebView}}. So, yes, everything has changed.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-02-20T18:41:55.000+0000", "updated": "2019-02-20T18:41:55.000+0000" }, { "id": "446217", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~mdelmarter], I recommend that you use the following path instead. The below will work on both Android and iOS in Titanium 8.0.0 and older versions.\r\n{code}\r\n\r\n{code}\r\n\r\nI have verified that \"app://Resources/...\" broke on iOS in Titanium 8.0.0. It used to work in 7.5.1. So, yes it's a bug. But... I also want to note that this never worked on Android either. This was an iOS only feature. The portable way to do it is via a relative path as shown above.\r\n\r\nAlso, make sure to set the following in your \"tiapp.xml\" to make sure that your PNGs do not get archived. Otherwise, the PNGs will be unreachable by the {{WebView}}.\r\n{code:xml}\r\n\r\nLocal Image File
' +\r\n\t\t'\t\t' +\r\n\t\t'\t' +\r\n\t\t'';\r\nvar window = Ti.UI.createWindow();\r\nvar webView = Ti.UI.createWebView();\r\nwebView.setHtml(htmlText, { baseURL: Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory).nativePath });\r\nwindow.add(webView);\r\nwindow.open();\r\n{code}\r\n\r\nThe above will work-around the 8.0.0.RC iOS bug you two are seeing.\r\n", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-02-25T23:01:02.000+0000", "updated": "2019-02-25T23:01:02.000+0000" }, { "id": "446309", "author": { "name": "mdelmarter", "key": "mdelmarter", "displayName": "Matthew Delmarter", "active": true, "timeZone": "Pacific/Auckland" }, "body": "[~chrishaff@gmail.com] - thanks for your response.\r\n\r\nIt is not totally correct however. I have loaded images and other files from the Documents directory into a WebView for many years. My first app that did this was released in 2012 and I have used this in several apps since then. It is the only way to have the user download a file, such as an EPUB file, and to then load the HTML and images from that EPUB into a WebView. It has always worked fine. The secret with the old WebView was to prefix the image path with the path to the full `Titanium.Filesystem.applicationDataDirectory` - i.e. the apps Documents directory.\r\n\r\nHowever, again since SDK 8.0+ and the change to WKWebView, this is not working. I was initially hoping that it was similar to the `app://' suggestion from [~jquick] above where he mentioned that this was not the suggested approach and there was another way. I am hoping that there is just another way to achieve the required end result. \r\n\r\nOverall I am sure that it can all work as expected - the developers just have not fully tested for these scenarios. The WebView is the core to so much functionality, and I have been using Ti WebView to the full inside my apps for many years. I am sure they will not let me down now. At the moment the issues in this ticket are a major roadblock for me to switch my existing apps over to 8.0 and to my carrying on with a new app I am working on that allows users to save web pages offline (including images) and to display them inside a WebView.\r\n\r\nWe will get there!", "updateAuthor": { "name": "mdelmarter", "key": "mdelmarter", "displayName": "Matthew Delmarter", "active": true, "timeZone": "Pacific/Auckland" }, "created": "2019-02-25T23:10:38.000+0000", "updated": "2019-02-25T23:14:47.000+0000" }, { "id": "446310", "author": { "name": "mdelmarter", "key": "mdelmarter", "displayName": "Matthew Delmarter", "active": true, "timeZone": "Pacific/Auckland" }, "body": "[~jquick] thanks so much for the workaround I will give it a go.\r\n\r\nJust further to the above comments, should I be able to open an HTML file and related resources (CSS/images) from the Documents directory? As I mentioned above I do this with a live app at the moment that loads EPUB files that the user has downloaded...\r\n\r\nCan the baseURL property be used for this as well maybe? To define base path inside the Documents folder?", "updateAuthor": { "name": "mdelmarter", "key": "mdelmarter", "displayName": "Matthew Delmarter", "active": true, "timeZone": "Pacific/Auckland" }, "created": "2019-02-25T23:14:22.000+0000", "updated": "2019-02-25T23:47:46.000+0000" }, { "id": "446311", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Yes, you can point the \"baseURL\" to the Documents directory. I tested the following on Titanium 8.0.0 and it definitely works. Just note that this is an iOS only feature for the moment.\r\n{code:javascript}\r\nvar sourceFile = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, \"assets/images/tab1.png\");\r\nvar targetFile = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, \"tab1.png\");\r\nsourceFile.copy(targetFile.nativePath)\r\n\r\nvar htmlText =\r\n\t\t'' +\r\n\t\t'' +\r\n\t\t'\t' +\r\n\t\t'\t\t' +\r\n\t\t'\t' +\r\n\t\t'\t' +\r\n\t\t'\t\tLocal Image File
' +\r\n\t\t'\t\t' +\r\n\t\t'\t' +\r\n\t\t'';\r\n\r\nvar window = Ti.UI.createWindow();\r\nvar webView = Ti.UI.createWebView();\r\nwebView.setHtml(htmlText, { baseURL: Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory).nativePath });\r\nwindow.add(webView);\r\nwindow.open();\r\n{code}\r\n\r\nWhat's important is that you need to tell the web view which directory files should be relative to. The \"baseURL\" can be set to a web URL or a local filesystem directory path.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-02-26T00:26:31.000+0000", "updated": "2019-02-26T00:29:07.000+0000" }, { "id": "446312", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Also note that we want to add \"baseURL\" support to Android in the future. The other thing that feature is needed for is iframes because they need to be told which website their resources are relative to. It's especially needed for playing YouTube videos in iframes. Please see: [TIMOB-26848]", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-02-26T00:33:31.000+0000", "updated": "2019-02-26T00:33:31.000+0000" }, { "id": "446539", "author": { "name": "vijaysingh", "key": "vijaysingh", "displayName": "Vijay Singh", "active": true, "timeZone": "America/Los_Angeles" }, "body": "PR(8_0_X): https://github.com/appcelerator/titanium_mobile/pull/10750\r\nPR(master): https://github.com/appcelerator/titanium_mobile/pull/10751\r\n\r\n[~mdelmarter] and [~chrishaff@gmail.com]\r\nUIWebView support custom NSURLProtocol, to load a custom url scheme which we were using to implement TiUIWebView till 7.5.x. We were using above protocol to load resources for url scheme \"app\".\r\n\r\nFrom 8.0.0 we have moved to WKWebView to implement TiUIWebView. WKWebview doesn’t support custom NSURLProtocol. \r\n\r\nBut in iOS 11+ Apple added WKURLSchemeHandler. It works same as NSURLProtocol.\r\nSo I have integrated WKURLSchemeHandler to load custom url scheme for iOS 11.0+ only via above PR. \r\n\r\nIf your app supports iOS 11+ only, this PR will fix your issue.\r\n\r\nOtherwise workaround given by [~jquick], is recommended.\r\nThanks!", "updateAuthor": { "name": "vijaysingh", "key": "vijaysingh", "displayName": "Vijay Singh", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-03-05T10:42:24.000+0000", "updated": "2019-03-05T10:47:32.000+0000" }, { "id": "446582", "author": { "name": "smohammed", "key": "smohammed", "displayName": "Samir Mohammed", "active": true, "timeZone": "America/Los_Angeles" }, "body": "FR Passed, waiting on Jenkins builds. ", "updateAuthor": { "name": "smohammed", "key": "smohammed", "displayName": "Samir Mohammed", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-03-06T14:09:02.000+0000", "updated": "2019-03-06T14:09:02.000+0000" }, { "id": "446787", "author": { "name": "mdelmarter", "key": "mdelmarter", "displayName": "Matthew Delmarter", "active": true, "timeZone": "Pacific/Auckland" }, "body": "[~jquick] and [~vijaysingh] thank you so much for the detailed responses. Joshua, the sample code works as advertised and has allowed me to continue with my project. I really appreciate the quality support and the quick turnaround on these important tickets.", "updateAuthor": { "name": "mdelmarter", "key": "mdelmarter", "displayName": "Matthew Delmarter", "active": true, "timeZone": "Pacific/Auckland" }, "created": "2019-03-12T21:11:17.000+0000", "updated": "2019-03-12T21:11:17.000+0000" }, { "id": "446792", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Happy to help [~mdelmarter]. And thank you for reporting the issue.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-03-13T02:00:48.000+0000", "updated": "2019-03-13T02:00:48.000+0000" } ], "maxResults": 22, "total": 22, "startAt": 0 } } }