Create a WordPress Latest Posts iOS app in Swift 2.0

Updated to work with Alamofire 3.0
×

So you want to know how to create a WordPress iOS app featuring your latest posts in Swift ha? Maybe not. But if you do, continue reading…

So where do we start?

Well, we have to figure out how to get our WordPress installation to generate a pure data feed for our iOS app to read. You could use your RSS feed, but that will mean writing some type of parsing class/method/function either server side or in your app.

Is there an easier way?

There is indeed. The WP REST API version 2 is here to save us at least an hour of coding. If you’re a WordPress developer I expect you to know what this is, if not, please get up to speed, for it’s the future of WordPress development.

Let’s get started

As I write this tutorial, the WP REST API version 2 is not yet part of the WP core. Download the plugin and install. You won’t find anything in the way of settings in your dashboard. Instead you will retrieve a JSON feed of your posts. You can configure your post index feed however you like, for this tutorial my JSON feed will be filtered by the category “tutorials”

As you can see, quite a bit of data is returned. For this tutorial however, I will only use the date, title and featured_image_thumbnail_url keys…

But there’s only a featured image id in the JSON response, no link

We need to get a link to the featured image. Not a problem. Navigate to your functions.php and add the following function to the rest_prepare_post hook

And you can name the featured image link key anything you want. For the purposes of this tutorial I named it featured_image_thumbnail_url.

Fire up Xcode

This tutorial is assuming you have some basic knowledge of Xcode.

Open Xcode. This app will be a “Single View Application”

single-view-application

Next, name your project and save it in your desired directory.

name-app

Setting up the View Controllers

Delete the default View Controller from the main story board and replace it with a Navigation Controller from the Object Library

default-viewcontroller

remove-viewcontroller

add-navigation-controller

Don’t forget to select the Navigation Controller and set check Is Initial View Controller in the Attributes Inspector

initial-viewcontroller

 

Under Simulated Metrics set the size to iPhone 4.7-inch

Setting up the Story Board

Delete the View Controller class (ViewController.swift file) and create a go to File > New File… Select Source under iOS in the left panel of the dialog box and on the right, select Cocoa Touch Class and press Next to continue.

new-cocoa-touch-class

Select UITableViewController from the drop down menu and name your file. I named my class “LatestPostsTableViewController”. Press Next and Create right after.

latest-posts-table-view-controller

Repeat the 2 steps above one more time, this time you want to select UITableViewCell and name the class “LatestPostsTableViewCell”

Reuse Identifier

Go back to the Main.storyboard and select the white area right below the Prototype Cells label. In the Attributes Inspector set the Identifier to “cell”. So what is this “Reuse Identifier”?

The reuse identifier is associated with a UITableViewCell object that the table-view’s delegate creates with the intent to reuse it as the basis (for performance reasons) for multiple rows of a table view. It is assigned to the cell object in initWithFrame:reuseIdentifier: and cannot be changed thereafter. A UITableView object maintains a queue (or list) of the currently reusable cells, each with its own reuse identifier, and makes them available to the delegate in the dequeueReusableCellWithIdentifier: method.

In simpler terms, the Reuse Identifier is used by the TableViewController Class to generate a template for the latest posts rows. Somewhat similar to an underscore.js template id, and that’s a very basic analogy for the reuse identifier does way more. Now we have to make sure the tableview in the LatestPostsTableViewController class (LatestPostsTableViewController.swift) knows the name of our reuse identifier

and make sure we cast the cell as “LatestPostsTableViewCell” instead of “UITableViewCell”

Return to the Table View and select the Prototype Cell. In the Identity Inspector, assign the LatestPostsTableViewCell class to the cell.

Screen-Shot-2015-07-16-at-6.56.03-PM

 

Select the Table View and in the Attributes Inspector choose “Grouped” for the table cell style

table-view

Make sure to apply the LatestTableViewController class to the Root View Controller in the Identity Inspector

root-controller

Setting up the Table Cell

Let’s set up the table cell receive the data from our JSON stream. As previously mentioned, for this tutorial I will one use the post title, date and featured image for display in the table view list.

Increase the height of the table cell to 200px.

cell-height

Next, drag 2 labels and an image object into the table cell from the Object Library.

cell-layout

For the constraints of each object, I set the:

  • Width
  • Height
  • Aspect Ratio (probably overkill),
  • Leading Space to Container Margin
  • Trailing Space to Container Margin
  • Top Space to Container Margin
  • Center Horizontally in Container

If you’re having some trouble with setting your constraints, take a few minutes to check out Jered’s YouTube tutorial on how to use Constraints in Xcode before continuing.

Setting up the Navigation Controller Classes

Now that we have the Storyboard laid out, let’s build out the controller classes. First we but set IBOutlets for the objects inside the cell template. Notice how I labeled the post title “Loading…”. This is a very basic indicator letting the viewer know to expect incoming content from an external source (your WordPress site). Of course you can add your own fancy loading indicator with animations, but for the sake of this tutorial I’ll keep it very basic.

In the Main.storyboard select the table cell and open the Assistant Editor. If you don’t initially see see the linked subclass (LatestPostsTableViewCell) select it from the preview menu up top

attributes-editor

Select the “Loading…” UILabel and Control + Drag inside the LatestPostsTableViewCell class, right above the first method and release. After releasing, keep the default setting displayed in the dialog box and name the IBOutlet. The name I used for this label is “postTitle”. Repeat the steps above with the post date UILabel and the featured image UIImageView

IBOutlets

By now you’re probably curious to see some progress, given all the work we’ve done so far. So let’s run the app in the simulator and see what we have…

nix

LOL. Don’t fret, let’s add some code to out classes to see our latests posts.

Swift and JSON

To be frank, parsing JSON in Swift is a pain. Ray Wenderlich discusses this in depth in his Swift/JSON tutorial. Instead of dealing with an infinite amount of closures, we will use the SwiftyJSON parser. After downloading, extract the SwiftyJSON.swift file and drag it into your project. Don’t forget to check “Copy Items if Needed” while importing.

Now open the LatestPostsTableViewController.swift file and add the follow to the class:

What happening here is that we set a constant with the JSON feed from our WordPress site. Following the constant a variable json was set with an empty object. When working in Swift, get in the habit of assigning a value when initializing variables. If you don’t, unexpected crashes can occur.

Avoiding a *Gotcha* moment

SWIFT 2.0 ALERT

Remote calls will no longer function if you’re server does not support TLS 1.2 and your SSL isn’t SHA2 encrypted. Read About It

The Work Around

Open your Info.plist in text editor. After the last tag, paste the following:

What you don’t want to do is load the JSON feed in the main thread. What if the feed is not available due to a network outage? What the user has a poor data connection or no data connection at all? Loading the JSON feed in the main thread can potentially crash the app, especially if the 2 scenarios above are happening. Instead we will load the feed asynchronously with the following function, which you can place right below the viewDidLoad function

Now inside the viewDidLoad function, let’s call the getPosts function with out latestPosts constant

The retrieved JSON from the site is not yet available in viewDidLoad function but will be available by the time the tableView functions are called. So let’s set those up. First, we have to have a minimum of 1 section for the cell template

Next, we have know how many rows we need in the table view based on the post count in the JSON feed.

If the JSON feed is not Null and if it’s of a type Array (see SwiftyJSON documentation to clarify any confusion about returned types) return the feed count, else return 1. Go ahead and fire up the app and let’s see the results…

Making Progress

Making Progress

For the sake of the tutorial, I set the UIImageView background to blue so you can see that it didn’t disappear. To finish things off, let’s link the data from the feed to the UILabel and UIImageView

So, what’s going on here? What is this guard keyword? Guard follows a Bouncer Pattern, meaning the statement turns away undesirable cases before letting the cool kids into the club. There is no guard keyword on PHP (or at least none that I’m aware of). However, if you are a WordPress developer (and I’m assuming you are if you’re reading this tutorial) then you’ve seen this Bouncer Pattern before if you’ve ever added a custom save function to the save_post hook

Beware of Type Hinting

PHP has weak type hinting. That means we don’t have to worry about whether function parameter was a string, integer or float. PHP figured all that out for us. Swift is not so forgiving. It’s pretty strict (at least from my POV) about types. So please keep that in mind if you plan on delving into Swift. Swift wants to know exactly what type of parameters you are inputing and the exact type of result you will output.

The 3rd conditional/guard/bouncer is a *Gotcha*.  Remember what I wrote about http calls earlier, anytime you plan to make a network call, you want load them asynchronously to avoid potential errors and crashes. There are a few ways to go about loading our featured images. One popular method is the Alamofire networking library, which is what I use most of the time. But in this tutorial I will use an ImageLoader class, similar to the getPosts function. Add the following class after the LatestPostsTableViewController class

Using the ImageLoader class, we can now safely add the featured images to the UIImageView

Now launch the app…

cool

And there you have it. Your first latest post WordPress iOS app. This is very basic and not production ready. In part 2 of this tutorial we’ll fix the date, cover Alamofire and finally a segue to the actual post when a table cell is tapped (selected).

BUT WAIT, THERE’S MORE!

For this bonus round we’ll add a refresh control. These are pretty standard in most apps. When the Table View is dragged down, we want the cells to display new posts if there are any.

refresh

newpost

Pretty simple ha? And don’t forget to Git this tutorial. Feel free to leave me any comments, questions or gripes!

Check out part 2 of this tutorial!