Tag Archives: UIWebView

How to fix http load errors in Xcode

In 2016, Apple have implemented a new rule that won’t let us load data from unsecured websites anymore. That’s those beginning with http:// instead of https:// (the latter ones are secured with an SSL certificate, and hence traffic is encrypted).

When you load an unsecured source, you’ll get an error message like this:

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.

If a secured source of the data is available, it’s probably the easiest method to change the feed. However, if that’s not an option, we can convince Xcode to let our apps download what’s known as data from “arbitrary” sources. Here’s how to do it.

First, in Xcode, navigate to your project’s target and find the Info tab. The target is the one that has your app icon showing, NOT the blue Xcode icon (top left, in the Project Navigator).

Now right-click on any of the many lines and select “Add Row”. This adds a value to your Info.plist file. Notice a list that comes up. Either select “App Transport Security” (if you can find it), or type NSAppTransportSecurity (it usually auto-completes). The entry will change into App Transport Security.

Let’s add the appropriate values to this new entry now. Hover over your new row now and select the little plus icon that comes up, then choose “Allow Arbitrary Loads” from the list. Alternatively, type in NSALlowsArbitraryLoads. Again this value will change to Allow Arbitrary Loads. Notice that this entry is a BOOL, and it needs to be set to YES on the right hand side. Go ahead and do that.

This will be enough to allow HTTP loads inside your app from any URL. You can restrict this to only certain URLs or hosts by adding another entry to the App Transport Security line, namely “Exception Domains”. Add each domain to its own line, and only data from those will be allowed to load via HTTP. If you want to use restricted domains, make sure to set the Allow Arbitrary Loads value to NO.





How to create a Twitter Follow button in your iOS App

Much like the Facebook Like button we can create a Twitter Follow button. It’s easy to create a HTML button which we can load into a small UIWebView (about 40 pixels high):

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // add Twitter Follow button in a web view
    NSString *twitterFollowButton = @"<a href='https://twitter.com/versluis' class='twitter-follow-button' data-show-count='true' data-size='large'>Follow @versluis</a><script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>";
    
    [self.twitterWebView loadHTMLString:twitterFollowButton baseURL:nil];
}

The code for the button is a JavaScript snippet courtesy of Twitter. You can get your customised button code here:
https://about.twitter.com/resources/buttons#follow

We want to intercept the user action of actually following the link our button generates (it would load the Twitter website and ask users to log in) – so let’s place an invisible UIButton over the web view and action that instead:

- (IBAction)twitterButton:(id)sender {
    
    // open the Twitter App
    if (![[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"twitter://user?screen_name=versluis"]]) {
        
        // opening the app didn't work - let's open Safari
        if (![[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://twitter.com/versluis"]]) {
            
            // nothing works - perhaps we're not onlye
            NSLog(@"Nothing works. Punt.");
        }
    }
}

This code will first try to open the Twitter app and pass in the desired user profile. If it’s not successful it will try to open Safari with the user’s profile link.

Note that our web button will only be displayed if the user is online. Have a fallback image handy if the user is offline.





How to create a Facebook Like button in your iOS App

Adding a Facebook Like button to a website in HTML is extremely easy, thanks to Facebook’s Developer API. But it’s not as straightforward to implement it in an iOS App.

Thanks to UIWebViews we can create a small web view, perhaps 80 pixels tall, and load the Facebook Like button into it. Here’s how:

This content is for members only.

Now you can react however you see fit: open a URL in Safari, open the Facebook App, etc.

Another thing of note: since the button will be pulled in from Facebook.com, it will not be displayed when a user is not online. Check via UIWebViewDelegate and if the URL can’t be loaded present an image from your bundle instead.





How to retrieve the current URL from a UIWebView

To read out the URL of what a Web View is currently displaying we can use this method:

    NSURL *myURL = [[NSURL alloc]init];
    myURL = self.myWebView.request.URL.absoluteURL;

Or, if we’d like to retrieve this as a string:

    myString = self.myWebView.request.URL.absoluteString;




How to handle an error while loading a UIWebView

If you’re conforming to the UIWebViewDelegate protocol the webView:didFailLoadWithError: method gets triggered when there has been a problem.
Call it like this and display an error message (in this case a UIAlertView):

This method is also a good opportunity to stop any loading animations you’ve got going.





How to add the “spinning wheel” Activity Indicator to a web view

It’s always good to have something happening while you’re loading a UIWebView. You can use the UIActivityIndicator for this. It’s basically an animated GIF file that you can connect to your code like many other elements. To make it work we need to conform to the UIWebViewDelegate protocol and then query our web view to see if he’s finished loading.

Here’s how we do that:

  • add the protocol to your header file
  • make sure you drag from your Web View to your View Controller’s delegate (control drag to the orange oval in your storyboard, at the bottom of your view controller)
  • add the method webViewDidFinishLoad:(UIWebView *)myWebView
  • in it call the stopAnimating method for your spinning wheel.

In the storyboard make sure that you set the behaviour of the Activity Indicator to “animating” and “hides when stopped”.

Here are my files:

This content is for members only.