Skip to content
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

Not rendering in iOS release mode #104

Open
horstleung opened this issue Sep 7, 2020 · 26 comments
Open

Not rendering in iOS release mode #104

horstleung opened this issue Sep 7, 2020 · 26 comments
Labels
bug Something isn't working pending reply

Comments

@horstleung
Copy link
Contributor

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
Copy link
Contributor Author

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).

@Denyllon
Copy link
Contributor

Denyllon commented Sep 9, 2020

@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:

source = {
{
html: this.state.layoutHTML
}
}

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

@horstleung
Copy link
Contributor Author

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

@Denyllon
Copy link
Contributor

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

@vinasgo
Copy link

vinasgo commented Sep 14, 2020

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."

@jenniferburch
Copy link

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

@vinasgo
Copy link

vinasgo commented Sep 15, 2020

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!

@horstleung
Copy link
Contributor Author

@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.

@aditya1711
Copy link

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.

@horstleung
Copy link
Contributor Author

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.

@Denyllon
Copy link
Contributor

@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!

@horstleung
Copy link
Contributor Author

nvm, enjoy your holiday.

@zjhiphop
Copy link

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

@jenniferburch
Copy link

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

@horstleung
Copy link
Contributor Author

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?

@jenniferburch
Copy link

@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'

@Denyllon
Copy link
Contributor

Denyllon commented Oct 7, 2020

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!

@wzhang2
Copy link

wzhang2 commented Oct 7, 2020

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

@Denyllon
Copy link
Contributor

Denyllon commented Oct 7, 2020

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 Denyllon added the bug Something isn't working label Oct 7, 2020
@AnthonyTailer
Copy link

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",
}

@zjhiphop
Copy link

@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
Copy link

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)
    }

@miansohaibkhalid
Copy link

@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:
#104 (comment)

@horstleung
Copy link
Contributor Author

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.

@hardiksonagrav
Copy link

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.

@utsavGridKey
Copy link

utsavGridKey commented May 21, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working pending reply
Projects
None yet
Development

No branches or pull requests