Communicating Between IOS And React

John | April 7, 2019

Communicating Between IOS And REACT

Every once in a while when writing applications for Iphone you may need to load a component from a web application into a webview and have communication between your ios application and your web app. I ran into this recently when I wanted to reuse an interactive map I wrote for a web application using javascript and react. I found it difficult to find a straightforward tutorial of how to communicate from swift to javascript and then communicate from javascript to swift. So I figured I would write a post of what I learned.

Starting Off

I’ll assume you know how to create a react app and load a page into a WKWebView in IOS. So I’ll start with a react app I generated using create-react-app and have loaded into a WKWebView.

Now I’ll add some buttons so we have some way to manually initialize contact between the swift and ios code.

The blue button is part of the IOS app and the red button is part of the swift app. By the end of this tutorial we’ll have it so that clicking the blue button changes the direction the react logo is rotating and clicking the red button displays a UILabel with a message from the react app.

1 How To Talk From React To IOS

We’ll rip the band-aid off and start with the harder part, sending messages from react to javascript. Inside onViewDidLoad we’ll get our webView’s userContentController and add a script message handler for the message we are expecting to receive from the js:

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        let contentController = self.webView.configuration.userContentController
        contentController.add(self, name: "setLabelText");
        let url = URL(string: "http://localhost:3000")
        let request = URLRequest(url: url!)
        webView.load(request)
    }

Then we’ll add the userContentController(_:didReceive:) method, which is the method that is called when a script message is received from a webpage. Inside this method we’ll add the code that when it receives a message named “setLabelText” will unhide our display label and set the text to the message body:

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == "setLabelText"{
            label.text = message.body as! String
            label.isHidden = false
        }
    }

Next on the React side we create a function that is called when our red button is clicked an sends a message to our ios app like this:

  onButtonClicked = () => {
      window.webkit.messageHandlers.setLabelText.postMessage("This is from the webpage");
  };

And there you go now when the blue button is clicked the react app will send a message to the ios app and the ios app will display the message.

That really wasn’t that bad but swift to js communication is even easier.

1 How To Talk From Swift To React App

Calling javascript from swift is pretty simple on the react side all we have to do is expose our react class by adding this line in our component did mount:

window.app = this;

Then we’ll add a function for our swift code to call:

  spinOpposite = () => {
     this.setState({
         spinCounterClockwise: !this.state.spinCounterClockwise,
     })
  };

On the swift side all we need to do is add this for our button outlet:

     @IBAction func callJsButtonTapped(_ sender: Any) {
         let js = "app.spinOpposite();"
         webView.evaluateJavaScript(js) { (result, error) in
             if(error){
                //handle error
             }
             //we aren't going ot have a result
         }
     }

And now we can call javascript from our swift code!

Wrapping Up

I hope you found this brief introduction into how you can communicate between an ios and react app helpful!

By: John