loading...

Fixing an error: JSON value '1' of type NSNumber cannot be converted to NSString

craftzdog profile image Takuya Matsuyama ・3 min read

After having upgraded React Native to 0.62.2, it got the following error:

JSON value '1' of type NSNumber cannot be converted to NSString
Enter fullscreen mode Exit fullscreen mode

TL;DR

  • Check your callstack
  • Check if you pass prop value wrong
    • In my case, I was passing boolean value instead of string

Callstack

Callstack

Look into variable contents at 13rd stack:

props

Most props are YES of boolean type for some reason. Weird.
It looks like it's WebView component:

WebView

The error happens when processing allowingReadAccessToURL:

allowingReadAccessToURL

allowingReadAccessToURL should be string

The error message was right.
allowingReadAccessToURL expects String:

RCT_EXPORT_VIEW_PROPERTY(allowingReadAccessToURL, NSString)
Enter fullscreen mode Exit fullscreen mode

in RNCWebView.m of react-native-webview:

- (void)visitSource
{
    // Check for a static html source first
    NSString *html = [RCTConvert NSString:_source[@"html"]];
    if (html) {
        NSURL *baseURL = [RCTConvert NSURL:_source[@"baseUrl"]];
        if (!baseURL) {
            baseURL = [NSURL URLWithString:@"about:blank"];
        }
        [_webView loadHTMLString:html baseURL:baseURL];
        return;
    }

    NSURLRequest *request = [self requestForSource:_source];
    // Because of the way React works, as pages redirect, we actually end up
    // passing the redirect urls back here, so we ignore them if trying to load
    // the same url. We'll expose a call to 'reload' to allow a user to load
    // the existing page.
    if ([request.URL isEqual:_webView.URL]) {
        return;
    }
    if (!request.URL) {
        // Clear the webview
        [_webView loadHTMLString:@"" baseURL:nil];
        return;
    }
    if (request.URL.host) {
        [_webView loadRequest:request];
    }
    else {
        NSURL* readAccessUrl = _allowingReadAccessToURL ? [RCTConvert NSURL:_allowingReadAccessToURL] : request.URL;
        [_webView loadFileURL:request.URL allowingReadAccessToURL:readAccessUrl];
    }
}
Enter fullscreen mode Exit fullscreen mode

So, it looks like I'm using it wrong:

  return (
    <WebView
      ref={webViewRef}
      source={source}
      originWhitelist={['*']}
      style={[styles.webView]}
      startInLoadingState
      hideKeyboardAccessoryView
      allowUniversalAccessFromFileURLs
      allowingReadAccessToURL
      onMessage={handleMessageFromWebView}
      onLoadEnd={handleWebViewLoad}
    />
  )
Enter fullscreen mode Exit fullscreen mode

It should be URL or something, according to the doc:

A String value that indicates which URLs the WebView's file can then reference in scripts, AJAX requests, and CSS imports. This is only used in for WebViews that are loaded with a source.uri set to a 'file://' URL. If not provided, the default is to only allow read access to the URL provided in source.uri itself.

So, the fix for my case would be:

diff --git a/src/components/mde-webview-bridge.js b/src/components/mde-webview-bridge.js
index 9ff7894..2401e5e 100644
--- a/src/components/mde-webview-bridge.js
+++ b/src/components/mde-webview-bridge.js
@@ -39,6 +39,9 @@ const MDEWebViewBridge = (props: Props) => {
           ? `file://${MainBundlePath.bundlePath}/webeditor/index.html`
           : 'file:///android_asset/webeditor/index.html'
       }
+  const allowingReadAccessToURL = isIOS()
+    ? `file://${MainBundlePath.bundlePath}/webeditor/`
+    : 'file:///android_asset/webeditor/'

   const sendMessageToWebView = useCallback(
     (message: BridgeMessage) => {
@@ -273,7 +276,7 @@ const MDEWebViewBridge = (props: Props) => {
       startInLoadingState
       hideKeyboardAccessoryView
       allowUniversalAccessFromFileURLs
-      allowingReadAccessToURL
+      allowingReadAccessToURL={allowingReadAccessToURL}
       onMessage={handleMessageFromWebView}
       onLoadEnd={handleWebViewLoad}
     />
Enter fullscreen mode Exit fullscreen mode

Okay, now it works fine!

Discussion

pic
Editor guide