Categories
Past Tutorials Swift WordPress

Swift: View a WordPress Post in your iOS App

The following tutorial is a continuation of the Create a WordPress Latest Posts iOS app in Swift tutorial. Now that you know how to generate a basic table displaying your recent WordPress posts, how do we actually see each individual post when a table cell is selected?

The Approach

There are a few ways to approach this. You can simply render the excerpt or content from the JSON feed. The drawback to this approach is that Swift has no native classes to convert HTML output. The method we will be using is to use a UIWebView object to render our posts. The UIWebView object is a built in browser that renders web pages in the same fashion as the Safari browser in iOS.

Adding the Web View

Navigate to the Main.storyboard and add another view controller.

Next, control + drag from the TableViewCell of the Latest Post Scene to the new view controller.

Choose Show for the segue action

Progress so far…

Run the simulator. Now you’ll find that when you tap a preview cell a black scene appears. Believe it or not, we are close to being done.

Drag a UIWebview into the new view controller.

Set the constraints for the UIWebView to what you see below.

The contraints are set to:

  • Equal Width to Super View
  • Equal Height to Super View
  • Center Horizontally
  • Center Vertically

Adding Swift

Go to File > New and add a new Cocoa Touch Class to your project. Make sure iOS Source is selected from the dialog box.

Select a standard UIViewController class and name it “WebViewController”

On the Main.storyboard, select the view controller and attach to it the WebViewController class from the Identity Inspector.

Now create an IBOutlet for the UIWebView

Navigate to the WebViewController file. Add the UIWebViewDelegate to the WevViewController class like so:

class WebViewController: UIViewController, UIWebViewDelegate {

In a near future tutorial, I will cover why the UIWebViewDelegate was added.

This is what your completed WebViewController Class should look like:

import UIKit

class WebViewController: UIViewController, UIWebViewDelegate {
    
    @IBOutlet weak var webView: UIWebView!
    var viewPost : JSON = JSON.nullJSON
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //Make sure the json is returning the post url as a string
        if let postLink = self.viewPost["link"].string{
            
            //Convert the url string to a NSURL object
            let requestURL = NSURL(string: postLink)
            
            //Create a request from NSURL
            let request = NSURLRequest(URL: requestURL!)
            
            webView.delegate = self
            
            //Load the post
            webView.loadRequest(request)
            
            //Set the title of the navigation bar to the title of the WordPress Post
            if let title = self.viewPost["title"].string{
                self.title = title
            }
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

But if you try to run this in the simulator, it will crash the app. What we have to do is prepare the segue to the selected JSON object to the WebViewController class.

Navigate to the LatestPostsTableViewController.swift file and uncomment the prepareForSegue function. Inside prepareForSegue function, add the following:

        //Which view controller are we sending this to?
        var postScene = segue.destinationViewController as! WebViewController;
        
        //pass the selected JSON to the "viewPost variable of the WebViewController Class
        if let indexPath = self.tableView.indexPathForSelectedRow(){
            let selected = self.json[indexPath.row]
            postScene.viewPost = selected
        }

What your entire prepareForSegue should look like:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        
        //Which view controller are we sending this to?
        var postScene = segue.destinationViewController as! WebViewController;
        
        //pass the selected JSON to the "viewPost variable of the WebViewController Class
        if let indexPath = self.tableView.indexPathForSelectedRow(){
            let selected = self.json[indexPath.row]
            postScene.viewPost = selected
        }
        
    }

Now let’s fire up the app and see what we have:

Responsive/Adaptive Layout Considerations

I’m going to assume that you are using a responsive layout for your WordPress theme (you better be). You probably noticed that opening up your site inside an app is a little different than browsing your site from mobile Safari. For one, we have a large navigation bar taking up real estate at the top of the page. We didn’t have to use a push segue for this tutorial, we could have very easily used a popover segue. But if you ever find yourself in a position where you need specific styling for your in-app rendered web page, use the following PHP conditional, you can place this in the functions.php located in the theme’s folder of your WordPress installation:

if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']),"iphone")) {
   if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']),"safari")) {
      echo('Running in browser on iPhone');
   }else{
      echo('Running as stand alone WebApp on iPhone');
   }
}else{
   echo('Running on device other than iPhone.');
}

Questions, corrections or gripes? Leave a comment below.

And don’t forget to Git the latest version of this project