Fixing an error: JSON value '1' of type NSNumber cannot be converted to NSString
Tags: reactnative, ios, javascript, objectivec
Published: 2020-05-06 06:41:54

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
```

#### 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](https://dev-to-uploads.s3.amazonaws.com/i/nu2emtrwfyif33j9d251.png)

Look into variable contents at 13rd stack:

![props](https://dev-to-uploads.s3.amazonaws.com/i/gph1qsifrwnd6wp1nliq.png)

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

![WebView](https://dev-to-uploads.s3.amazonaws.com/i/nesszzds3jpu7pqvqlqs.png)

The error happens when processing `allowingReadAccessToURL`:

![allowingReadAccessToURL](https://dev-to-uploads.s3.amazonaws.com/i/oxibol1vvdl729gwcu6k.png)

## `allowingReadAccessToURL` should be string

The error message was right.
`allowingReadAccessToURL` expects `String`:

* [react-native-webview/RNCWebViewManager.m at a6010d93e070d91e7f656cf3edf604515bde586f · react-native-community/react-native-webview](https://github.com/react-native-community/react-native-webview/blob/a6010d93e070d91e7f656cf3edf604515bde586f/apple/RNCWebViewManager.m#L66)

```objective-c
RCT_EXPORT_VIEW_PROPERTY(allowingReadAccessToURL, NSString)
```

in `RNCWebView.m` of react-native-webview:

```objc
- (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];
    }
}
```

* Related pull request: [Add prop for allowingReadAccessToURL on iOS WKWebView by hsource · Pull Request #771 · react-native-community/react-native-webview](https://github.com/react-native-community/react-native-webview/pull/771)

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

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

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

* [react-native-webview/Reference.md at master · react-native-community/react-native-webview](https://github.com/react-native-community/react-native-webview/blob/master/docs/Reference.md#allowingreadaccesstourl)

> 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
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}
     />
```

Okay, now it works fine!