highcharts-react-native icon indicating copy to clipboard operation
highcharts-react-native copied to clipboard

Not rendering in iOS release mode

Open horstleung opened this issue 5 years ago • 26 comments

getting error:

Failed to fetch scripts or layout. File 'file:///{USER_PATH}/Library/Developer/CoreSimulator/Devices/D53BDBF8-65D5-4AC5-9436-39A94EF1CE60/data/Containers/Data/Application/879BAB8F-D419-4908-8317-01B556F7BCFA/Library/Caches/ExponentAsset-ffceb4b4585b380fc666d3882abee7e5.html' could not be read.

horstleung avatar Sep 07 '20 11:09 horstleung

Hotfix

Modifiy setLayout in HighchartsReactNative.js

setLayout = async () => {
        const indexHtml = Asset.fromModule(require('../highcharts-layout/index.html'))
        this.setState({
            layoutHTML: await FileSystem.readAsStringAsync(indexHtml.uri)
        })
    }

@Denyllon I don't understand the original flow (downloading a local file to cache folder and read that).

horstleung avatar Sep 08 '20 07:09 horstleung

@fattomhk We need to load the local index.html file and register it as an asset, read it as a string, and then pass as the html value for Webview here: https://github.com/highcharts/highcharts-react-native/blob/64f6d610555a92270667051bebff432d48d31a7b/dist/src/HighchartsReactNative.js#L209-L213

Could you provide us with the minimal project where the problem occurs?

Denyllon avatar Sep 09 '20 14:09 Denyllon

Sorry for not setting up a repo as I made this in work.

Here is the minimal project.(setup ios only.) https://drive.google.com/file/d/1L1L9iJITAPfWbu5h4i5fYtJYTTVeIxMZ/view?usp=sharing

You can run yarn ios to show the chart. But if can't see any if you run it through XCode (as I set the target to release mode).

there is a patch in patches folder for my hotfix. you can apply it by npx patch-package

horstleung avatar Sep 10 '20 02:09 horstleung

@fattomhk Thank you. We will take a look on it as soon as possible.

Denyllon avatar Sep 14 '20 09:09 Denyllon

I have the same problem. In debug mode it works perfectly, but in realease mode I get this error message on Xcode. "Failed to fetch scripts or layout. File 'file:///Users/Vinas/Library/Developer/CoreSimulator/Devices/C375A33E-EFA3-4983-B644-2E66FFD7C5BA/data/Containers/Data/Application/868BF4A0-E28C-4C4F-9485-95D94CA0BB3C/Library/Caches/ExponentAsset-ffceb4b4585b380fc666d3882abee7e5.html' could not be read."

vinasgo avatar Sep 14 '20 17:09 vinasgo

Is there any update on this ticket? I'm not getting any charts on a real iOS device. (in the emulator it's fine)

jenniferburch avatar Sep 15 '20 17:09 jenniferburch

Hotfix

Modifiy setLayout in HighchartsReactNative.js

setLayout = async () => {
        const indexHtml = Asset.fromModule(require('../highcharts-layout/index.html'))
        this.setState({
            layoutHTML: await FileSystem.readAsStringAsync(indexHtml.uri)
        })
    }

@Denyllon I don't understand the original flow (downloading a local file to cache folder and read that).

It works!

vinasgo avatar Sep 15 '20 17:09 vinasgo

@jenniferburch If you are rushing, you might apply my hotfix yourself or apply the patch in my google drive's zip by copying patches folder to your project and run npx patch-package.

I don't understand the original flow otherwise I would create a pull request. So, if you are not rushing, you better wait for the official fix.

horstleung avatar Sep 16 '20 02:09 horstleung

Hotfix

Modifiy setLayout in HighchartsReactNative.js

setLayout = async () => {
        const indexHtml = Asset.fromModule(require('../highcharts-layout/index.html'))
        this.setState({
            layoutHTML: await FileSystem.readAsStringAsync(indexHtml.uri)
        })
    }

@Denyllon I don't understand the original flow (downloading a local file to cache folder and read that).

This doesn't work for me. With a different but similar error message.

Failed to fetch scripts or layout. File 'file:///{USER_PATH}/Library/Developer/CoreSimulator/Devices/00C9E684-010E-45E1-AE2E-48FF90A469B9/data/Containers/Data/Application/D50BE37B-07F2-4800-B853-18066208FCA2/Library/Caches/ExponentAsset-854c52eea1c8666bdc81b6d4f0a46808.hcscript' could not be read.

aditya1711 avatar Sep 17 '20 17:09 aditya1711

Hotfix

Modifiy setLayout in HighchartsReactNative.js

setLayout = async () => {
        const indexHtml = Asset.fromModule(require('../highcharts-layout/index.html'))
        this.setState({
            layoutHTML: await FileSystem.readAsStringAsync(indexHtml.uri)
        })
    }

@Denyllon I don't understand the original flow (downloading a local file to cache folder and read that).

This doesn't work for me. With a different but similar error message.

Failed to fetch scripts or layout. File 'file:///{USER_PATH}/Library/Developer/CoreSimulator/Devices/00C9E684-010E-45E1-AE2E-48FF90A469B9/data/Containers/Data/Application/D50BE37B-07F2-4800-B853-18066208FCA2/Library/Caches/ExponentAsset-854c52eea1c8666bdc81b6d4f0a46808.hcscript' could not be read.

My hotfix is solving the html asset loading problem only.

I think that is the same problem with the html one.

a guess, haven't tried:

addScript = async (name, isModule, useCDN) => {
        if(useCDN) {
            const response = await fetch(
                httpProto + cdnPath + (isModule ? 'modules/' : '') + name + '.js'
            ).catch((error) => {
                throw error
            })
            stringifiedScripts[name] = await response.text()
        } else {
            const script = Asset.fromModule(
                isModule &&
                name !== 'highcharts-more' &&
                name !== 'highcharts-3d' ?
                HighchartsModules.modules[name] : HighchartsModules[name]
            )
            stringifiedScripts[name] = await FileSystem.readAsStringAsync(script.uri) 
// origin: await this.getAssetAsString(script)
        }
    }

Btw, maybe setting useCDN would get through the script loading part.

horstleung avatar Sep 18 '20 02:09 horstleung

@fattomhk Apologize for that takes so long, though unfortunately I still haven't had chance to run your project due to general overload of work this week (many things to close in other projects before going on vacation). I will get back to this issue right after back to the office (29th of September).

Kind regards, and than you for your patience!

Denyllon avatar Sep 18 '20 15:09 Denyllon

nvm, enjoy your holiday.

horstleung avatar Sep 21 '20 01:09 horstleung

I also have this issue, and can not resolve with the above solution.

zjhiphop avatar Sep 21 '20 09:09 zjhiphop

The patch did work in my project if running from Xcode but is still broken if running through the command line, react-native run-ios, (still unable to fetch the script) but as a stop gap (and this is a SUPER hack), in src/HighChartsReactNative.js

  1. comment out the contents of setLayout
  2. in the render() method, change the WebView source to be: source = { {
    html: COPY PASTE THE CONTENTS OF ../highcharts-layout/index.html } }

You will also need to set useCDN={true} when you render <HighchartsReactNative />

jenniferburch avatar Sep 21 '20 19:09 jenniferburch

The patch did work in my project if running from Xcode but is still broken if running through the command line, react-native run-ios, (still unable to fetch the script) but as a stop gap (and this is a SUPER hack), in src/HighChartsReactNative.js

  1. comment out the contents of setLayout
  2. in the render() method, change the WebView source to be: source = { { html: COPY PASTE THE CONTENTS OF ../highcharts-layout/index.html } }

You will also need to set useCDN={true} when you render

What error did you get after applying the patch and set useCDN to true?

horstleung avatar Sep 22 '20 01:09 horstleung

@fattomhk error in debugger: ExceptionsManager.js:179 Failed to fetch scripts or layout. Unsupported URI scheme for 'http://localhost:8081/assets/node_modules/@highcharts/highcharts-react-native/highcharts-layout/index.html?platform=ios&hash=ffceb4b4585b380fc666d3882abee7e5'

jenniferburch avatar Sep 23 '20 19:09 jenniferburch

Hello @fattomhk @jenniferburch @zjhiphop, Sorry for that it takes so long, but this problem is very complex, and unfortunately there is no any quick/simple solution to get rid of it, because the FileSystem and Asset objects from react-native-unimodules have significant differences in a process of how they work on different environments (Simulators, real devices, operating systems).

For example, when using the Asset.asyncDownload() on iOS Simulator, all files are downloaded into the FileSystem.cacheDirectory and because of that fact we are able to avoid downloading them multiple times one by one, by checking whether are they already downloaded in the mentioned directory. In case of running the app on a real device, files are not available there though, and they have completely different path structure.

Furthermore, while I've tried to always use the path from downloaded asset localUri property, then it breeds further problems. When having (let's say) about 20 charts with multiple modules (funnel, range, bullet etc.) in one App, then, I guess, it generates too many file read requests, and then the error is thrown from FileSystem. For some reason it is not able to read the file... but only on Simulators though.

As you can see, for now, we are not able to give you any perfect and universal solution, which could be applied to resolve all of reported issues. We definitely need to discuss the architecture of managing files in this wrapper, and find some compromise. That means, it can takes a while.

Kind regards!

Denyllon avatar Oct 07 '20 10:10 Denyllon

is this only happening on some versions of react native? we just updated to rn63.3, and now we are seeing this issue, but was fine on 61.2 with react-native-unimodules on 0.7.0

wzhang2 avatar Oct 07 '20 10:10 wzhang2

I guess that's what it comes to. Or, the react-native-unimodules works differently with different React Native versions. The problem is very complex, most probably nested somewhere in the dependent packages, and it's hard to find out what causing the issue.

Denyllon avatar Oct 07 '20 10:10 Denyllon

I'm getting the same behavior here. After upgrade my project from RN 0.61.5 to 0.63.3 and using Xcode 12. Works on Debug but not in Release mode.

I have tried the suggestions above. The one that worked was the "guess" comment by @fattomhk.

So I applied this patch with patch-package and set useCDN as false on HC component options:

diff --git a/node_modules/@highcharts/highcharts-react-native/src/HighchartsReactNative.js b/node_modules/@highcharts/highcharts-react-native/src/HighchartsReactNative.js
index fabd55a..c284c26 100755
--- a/node_modules/@highcharts/highcharts-react-native/src/HighchartsReactNative.js
+++ b/node_modules/@highcharts/highcharts-react-native/src/HighchartsReactNative.js
@@ -74,15 +74,14 @@ export default class HighchartsReactNative extends React.PureComponent {
                 name !== 'highcharts-3d' ?
                 HighchartsModules.modules[name] : HighchartsModules[name]
             )
-            stringifiedScripts[name] = await this.getAssetAsString(script)
+            stringifiedScripts[name] = await FileSystem.readAsStringAsync(script.uri)
         }
     }
 
     setLayout = async () => {
         const indexHtml = Asset.fromModule(require('../highcharts-layout/index.html'))
-
         this.setState({
-            layoutHTML: await this.getAssetAsString(indexHtml)
+            layoutHTML: await FileSystem.readAsStringAsync(indexHtml.uri)
         })
     }

My package.json:

{
  "@highcharts/highcharts-react-native": "^3.1.2",
  "react": "16.13.1",
  "react-native": "0.63.3",
  "react-native-unimodules": "^0.11.0",
  "react-native-webview": "^10.9.2",
}

AnthonyTailer avatar Oct 14 '20 13:10 AnthonyTailer

@AnthonyTailer @fattomhk I tried your solution in develop mode, it reported "Failed to fetch scripts or layout. Unsupported URI scheme for '....' '".

Is there any solution could support both develop and release mode?

zjhiphop avatar Oct 21 '20 11:10 zjhiphop

Minimal code change to fix the issue and support for both dev and release mode. Just update getAssetAsString to following will done:

 getAssetAsString = async (asset) => {
        if (!__DEV__) {
            return await FileSystem.readAsStringAsync(asset.uri);
        }

        const downloadedModules = await FileSystem.readDirectoryAsync(FileSystem.cacheDirectory)
        let fileName = 'ExponentAsset-' + asset.hash + '.' + asset.type

        if (!downloadedModules.includes(fileName)) {
            await asset.downloadAsync()
        }

        return await FileSystem.readAsStringAsync(FileSystem.cacheDirectory + fileName)
    }

zjhiphop avatar Oct 22 '20 03:10 zjhiphop

@AnthonyTailer @fattomhk I tried your solution in develop mode, it reported "Failed to fetch scripts or layout. Unsupported URI scheme for '....' '".

Is there any solution could support both develop and release mode?

You should try this one. It's working on both modes: https://github.com/highcharts/highcharts-react-native/issues/104#issuecomment-696327683

miansohaibkhalid avatar Oct 22 '20 05:10 miansohaibkhalid

Minimal code change to fix the issue and support for both dev and release mode. Just update getAssetAsString to following will done:

 getAssetAsString = async (asset) => {
        if (!__DEV__) {
            return await FileSystem.readAsStringAsync(asset.uri);
        }

        const downloadedModules = await FileSystem.readDirectoryAsync(FileSystem.cacheDirectory)
        let fileName = 'ExponentAsset-' + asset.hash + '.' + asset.type

        if (!downloadedModules.includes(fileName)) {
            await asset.downloadAsync()
        }

        return await FileSystem.readAsStringAsync(FileSystem.cacheDirectory + fileName)
    }

I faced the problem and tried this fix this week. Thanks for saving my hours.

horstleung avatar Nov 03 '20 06:11 horstleung

I'm getting the same behavior here. After upgrade my project from RN 0.61.5 to 0.63.3 and using Xcode 12. Works on Debug but not in Release mode.

I have tried the suggestions above. The one that worked was the "guess" comment by @fattomhk.

So I applied this patch with patch-package and set useCDN as false on HC component options:

diff --git a/node_modules/@highcharts/highcharts-react-native/src/HighchartsReactNative.js b/node_modules/@highcharts/highcharts-react-native/src/HighchartsReactNative.js
index fabd55a..c284c26 100755
--- a/node_modules/@highcharts/highcharts-react-native/src/HighchartsReactNative.js
+++ b/node_modules/@highcharts/highcharts-react-native/src/HighchartsReactNative.js
@@ -74,15 +74,14 @@ export default class HighchartsReactNative extends React.PureComponent {
                 name !== 'highcharts-3d' ?
                 HighchartsModules.modules[name] : HighchartsModules[name]
             )
-            stringifiedScripts[name] = await this.getAssetAsString(script)
+            stringifiedScripts[name] = await FileSystem.readAsStringAsync(script.uri)
         }
     }
 
     setLayout = async () => {
         const indexHtml = Asset.fromModule(require('../highcharts-layout/index.html'))
-
         this.setState({
-            layoutHTML: await this.getAssetAsString(indexHtml)
+            layoutHTML: await FileSystem.readAsStringAsync(indexHtml.uri)
         })
     }

My package.json:

{
  "@highcharts/highcharts-react-native": "^3.1.2",
  "react": "16.13.1",
  "react-native": "0.63.3",
  "react-native-unimodules": "^0.11.0",
  "react-native-webview": "^10.9.2",
}

Working fine.

hardiksonagrav avatar Jun 02 '21 05:06 hardiksonagrav

Hey Falas, I have tried all the above solution but at the end i have this error and this the issue with highchart react native

Failed to fetch scripts or layout. Calling the 'readAsStringAsync' function has failed → Caused by: File '/~assets/ffceb4b4585b380fc666d3882abee7e5' is not readable

utsavGridKey avatar May 21 '24 04:05 utsavGridKey