July 27, 2016
Using WebView in a React Native application allows us to reuse already built web pages.
With iOS 9 or higher if our application attempts to connect to any HTTP server that doesn't support the latest SSL technology (TLSv1.2), WebView will fail and will not be able load the web pages.
Let's see this in action. Here we are trying to access a HTTP site via WebView in React Native.
<WebView style={styles.container} source={{ uri: "http://del.icio.us" }} />
Running that on an iPhone simulator with iOS version 9.0 or greater would show following error.
Error Loading Page
Domain: NSURLErrorDomain
Error Code: -1022
Description: The resource could not be loaded because
the App Transport Security policy requires the use of a
secure connection
Ideally, the site we are trying to connect to should have HTTPS enabled. However there might be cases where we need to connect to sites where HTTPS is not enabled.
For example, while developing the app, we might want to connect to local server which is running just HTTP.
To access HTTP sites inside our WebView,
we need to open the project in Xcode
and
open the Info.plist
file.
In the list of keys, we will find
App Transport Security Settings
.
When we expand the section, we would find
localhost
inside the Exception Domains
and
the key NSTemporaryExceptionAllowsInsecureHTTPLoads
with value true
.
Because of this setting when we are connecting to localhost then app runs even if server is running on HTTP and not on HTTPS.
So in order to make our non HTTPS site run, we need to add our website url to this whitelisting.
When we hover over the Exception Domains
key,
we would see a +
sign at the right hand side.
Click on it and add our
domain here. Set the type to dictionary
.
Now click on the domain we just entered
and add NSTemporaryExceptionAllowsInsecureHTTPLoads
with type Boolean
and value YES
similar to the one present for localhost
Re-run the app using react-native run-ios
from the terminal and now the site
would be loaded.
If it doesn't work, then prior to running the app, do a clean build from xcode.
By making the changes from XCode, if we look at the changes in info.plist file, we would find a few lines of code added.
So if we don't want to open Xcode for the fix, we can add the following lines directly in our info.plist.
Edit the node for the key NSAppTransportSecurity
so that the whole node now looks like this:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>del.icio.us</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
<key>localhost</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
Be sure to re-run the app using react-native run-ios
. Now let's see
how to
allow all the HTTP sites instead of whitelisting each and everyone
Using Xcode : To allow all the non HTTPS sites,
just delete the Exception Domains
from
Xcode inside info.plist
and add a new key Allow Arbitrary Loads
with the value true
.
Our NSAppTransportSecurity
should just
contain the following.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
If this blog was helpful, check out our full blog archive.