While updating my tutorial for UIWebView I came across a problem I had heard about but had not experienced. I had even heard a claim that a lot of apps are broken or rejected because of this. Apple has increased security on web accesses, and it does crash a web view rather quickly. I’m going to show you the problem and a few ways to work around it.
Suppose you had a scene on the storyboard that is a simple web view:
You wired it up to this view controller.
class ViewController: UIViewController { @IBOutlet weak var webView: UIWebView! override func viewDidLoad() { super.viewDidLoad() //let url = NSURL(https://www.youtube.com/watch?v=bp_U-ZAWNM0) let url = NSURL(string: "http://makeapppie.com") let requestObj = NSURLRequest(URL: url!) webView.loadRequest(requestObj) } }
Then build and run. Unfortunately, you get an empty website:
and an error message in the console:
2015-10-21 05:53:28.435 WebSecurityDemo[24907:1371951] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.
The error message states that sites using http://
are insecure. Sites using https://
work fine. For example, if you change the url to this:
let url = NSURL(string: "https://www.youtube.com/watch?v=bp_U-ZAWNM0") //let url = NSURL(string: "http://makeapppie.com")
You get the YouTube page.
One solution is have all the pages you go to be secure pages. If you own a website, set it up for better security. That doesn’t work in all cases, and we need to get around that message at times.
We can change the security settings in the info.plist. The broad option is to shut it down completely for the app. In the Navigator, right-click on plist.info. Select Open As > Source Code.
In the XML code that appears add this just under the first tag:
The NSAppTransportSecurity
is a dictionary you add to the info.plist to set web preferences for the web security. Adding a key of NSAllowsArbitraryLoads
and its value to true
opens up the app to all web sites.Change the url back to makeAppPie.com
//let url = NSURL(string: "https://www.youtube.com/watch?v=bp_U-ZAWNM0") let url = NSURL(string: "http://makeapppie.com")
Build and run. We get the website now.
However, this is also the least secure way of doing this. Apple may frown on a broad use of the web, and your app is far from secure. A better way is to use specific exceptions. Change the NSAppTransportSecurity
in the info.plist to this:
The NSExceptionDomains
key makes a dictionary of excepted domains. Each key in this dictionary is a domain excepted from security, depending on settings in its own dictionary. You can use all or some of the keys. The keys and their default settings can be found in Apple’s App Transport Security Technote. Most likely NSExceptionAllowsInsecureHTTPLoads
or NSThirdPartyExceptionAllowsInsecureHTTPLoads
and NSIncludesSubdomains
will be the important ones.
Build and run.It almost works:
We’re missing the header image. Here’s the problem with NSExceptionDomains
: you have to find all of them. If a website uses stuff outside the domain, it will fail. As makeapppie.com is a WordPress hosted site, we added wordpress.com to the domain exceptions:
Build and run:
There’s still errors since we’re getting the message still, but we do get the header image. However, the fonts are wrong, since they come from Google. Going into the HTML for the page, You’d find a lot of domains we need to add.
The point is, if you use web pages in your app, make sure to know where everything is coming from, and account for it in your exceptions. In a content management system like WordPress, that might be a herculean task. On a self made site, that might be easy. I added wordpress.com
for expediency. It would be better if I added only the subdomain I needed. Try to keep things tight to keep the secure.
Leave a Reply