Update element value in React component from iOS UIWebView

I am trying to transfer data from a native iOS application to a React (non-responsive) web application running in UIWebView.

I get a string from a native viewcontroller and must "insert" it into the value of the <input> element inside the React component class. I gave the element a id like this:

 render() { <div> ... <input id="iccid" type="text" name="iccid" pattern="\d*" onChange={this.iccidChanged.bind(this)} autoFocus /> ... </div> } 

Then, using JavaScriptCore from iOS (Swift code), I run:

 self.context = self.webView.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") as? JSContext self.context!.evaluateScript("document.getElementById('iccid').value='\(barcodeValue)';") 

This seems to work, and I can see the value updated in the DOM inside the webview, the problem is that my React onChange function (which checks the value and state of the component component) does not work, because React does not interpret this as a change (possibly because behind the DOM and virtual DOM processing).

What is the proper way / best practice to update an element's value from iOS and make the React component behave the way the user typed it?

+7
javascript ios reactjs swift uiwebview
source share
1 answer

I assume that you want to trigger an event when scanning a barcode. Perhaps your iOS application does not need to know where , the event should be sent (i.e. what input field and how). Simply indicate the web view that the barcode is being scanned.

You can send a custom DOM event to window and add some React component to it.

 window.dispatchEvent(new CustomEvent('barcodescan', { detail: { value: '(barcodeValue)' } })) 

Then you can create a component without a render that will listen to the barcode event:

 const BarcodeListener = React.createClass({ propTypes: { onBarcodeScan: React.PropTypes.func.isRequired }, componentDidMount () { window.addEventListener('barcodescan', this.handleBarcodeScan) }, componentWillUnmount () { window.removeEventListener('barcodescan', this.handleBarcodeScan) }, render () { return null }, handleBarcodeScan (e) { this.props.onBarcodeScan(e) } }) 

Then, in your form, you can visualize the input along with the barcode event listener:

  render () { return ( <div> ... <input ... /> <BarcodeListener onBarcodeScan={this.handleBarcodeScan} /> </div> ) } 

Then handle the barcode scan event separately.

+5
source share

All Articles