Chris Hannah

Swift


Foundation Is Becoming Fully Swift and Open Source

"The Future of Foundation", Swift.org:

Today, we are announcing a new open source Foundation project, written in Swift, for Swift.

I saw this being talked about earlier on Twitter by people that understand this sort of stuff much more than me. But my first reactions were:

  1. I didn't know Foundation wasn't already in Swift.
  2. I wonder if I can become a contributer.

The post has the project launching on GitHub in 2023, which isn't that helpful. Still, it would be pretty cool to say I contributed to Foundation.

Adding Insets to a UILabel

I ran into a situation at work today, where I was already using a UILabel to display text, but it was styled in a way that really needed some padding.

UILabel doesn’t directly support this, and the most common way to get around it is to embed the UILabel inside a UIView, and control the constraints that way. I didn’t really want to do that for what I was doing, and I also wanted to just make my own label that could handle padding.

It didn’t take long and was a lot more straightforward than I thought. I subclasses UIClass, added a UIEdgeInsets variable, and then made sure that intrinsicContentSize, sizeThatFits(_ size: CGSize), and drawText(in rect: CGRect) took that into consideration. So it still works perfectly with AutoLayout.

It’s certainly not a major open source project or anything, but it could be a quick way to add padding support to a UILabel!

You’re Practically a Mac Developer →

Brent Simmons:

Say you write an iOS app, and now you want to write the Mac version.

Assuming there’s a data model, maybe a database, some networking code, that kind of thing, then you can use that exact same code in your Mac app, quite likely without any changes whatsoever.

I agree with Brent here. I’ve never really understood the argument that AppKit is that difficult to understand, so that’s why people don’t port native apps over. Surely the underlying logic of the app is the hard part, and linking the functionality to the interface is the easier part?

I would say I’m more of an iOS developer, simply because I’ve spent more time on it. But I’ve also made a few Mac applications. Sure, a resizing window is a bit more complex than a relatively fixed screen size, and some the interface elements are names slightly differently.

It’s just different, for both sets of people. But not as difficult as it may seem.

A Collection of Interesting Swift Features →

Jordan Smith has 15 short Swift snippets, that may help you write more readable code, and also introduce you to a few new techniques. For example, custom subscript notation, labelling loops, and variadic parameters.

Read the full post.

Custom operators in Swift →

John Sundell has written a great piece about using custom operators in Swift. Some really interesting examples as well. I never really thought about custom operators like he has, but clearly they can be very powerful tools:

Few Swift features cause as much heated debate as the use of custom operators. While some people find them really useful in order to reduce code verbosity, or to implement lightweight syntax extensions, others think that they should be avoided completely.

Love ’em or hate ’em – either way there are some really interesting things that we can do with custom operators – whether we are overloading existing ones or defining our own. This week, let’s take a look at a few situations that custom operators could be used in, and some of the pros & cons of using them.

Read the full post.

A Simple and Clean Way to Store Sectioned Data for a UITableView

This is just something small in Swift/iOS that I find pretty handy, so I thought I’d share it just in case it can help.

So, the problem is that creating data that has to be presented in a UITableView can be somewhat complex, especially if you have multiple columns. This solution is geared towards quickly creating dummy data, but I think it could be expanded into an overall DataSource solution.

Anyway, we’ll start with the current way of managing sections. Usually, you would have some kind of enum that would correspond to a section integer, and also however many arrays of data for the number of sections. You would then either use the section enum to find the correct array. Or maybe you’d use a 2d array, and then use it as the index.

It just doesn’t see very Swift to me. In Swift, everything is simple, easy to read, and is pretty easy to write. So I thought I’d come up with a slight abstraction.

My first idea was to just make two structs, one for a Section, and another for a Table:

struct Section {
    var title: String
    var items: [String]
}

struct Table {
    var sections: [Section]
}

You could then go ahead, create individual sections, and add them to one table. Easy.

Example Data

Animals:

Example Code

let catSection = Section(title: "Cats", items: ["Tiger", "Lion", "Lynx"])
let bearSection = Section(title: "Bears", items: ["Grizzly", "Black", "Polar"])

let animalTable = Table(sections: [catSection, bearSection])

I just find that a bit more readable.

It also makes the number of sections and rows a bit simpler:

let numberOfSections = animalTable.sections.count
let numberOfRows = animalTable.sections[0].items.count

However, you can add this functionality to the Table struct Which makes it much, much better.

Here is the definition of the ComplexTable struct:

struct ComplexTable {
    var sections: [Section]
    
    func numberOfRows(forSection section: Int) -> Int {
        if sections.count > section {
            return sections[section].items.count
        } else {
            return 0
        }
    }

    func numberOfSections() -> Int {
        return sections.count
    }
}

Which would make it this easy to get the row and section counts:

let numberOfSections = complexAnimalTable.numberOfSections()
let numberOfRows = complexAnimalTable.numberOfRows(forSection: 0)

So there you go.

It’s nothing big, and it won’t win many programming awards. But it’s a small piece of code that will certainly help me when I’m just messing around with tables, or I want a really clean and simple way to store small amounts of organised data.

iOS Icon Sizes

There’s a lot of occasions where I’m checking the specific iOS icon sizes, and I remember I made a document a few years ago with some references. However, there’s been a huge amount of changes since then. So I decided to create a new reference document from the Xcode 9.0 beta.

It’s hosted as a Gist on Github, or you can view it below:

I’m going to make an effort to keep this updated, and I’ll probably create one for the other platforms as well. Anyway, I hope people find this useful!

I’ve Been Writing Server-Side Swift!

I made my first API today, and I used Swift to do it!

Basically, I got bored this afternoon and decided to have a little research into server-side Swift programming. I’ve heard about this before, but I’ve not gone too deep into it myself.

The problem with me tying things like this, is that I ever really have a good idea, or scenario which I could use to learn the new thing. Well as you may already know, I’m slowly working on a title casing application for iOS and macOS, and therefore I’ve already created a few functions to format text.

So far the base TextCase functions are:

  • Uppercase
  • Lowercase
  • Title Case
  • URL Encoding
  • Mocking SpongeBob (yes, like the meme)

From these formats, the only ones I could see being useful are Title casing, and the fun SpongeBob format.

From making use of various APIs myself, I knew that all I needed was a super simple HTTP server, which had support for a few GET requests.

Perfect was the tool I used to write the server side code, and I found a quick tutorial which explained the basic HTTP server that I needed. I must say it was really easy for me to create this, as I’m already familiar with Swift, so the only thing to learn was the “Perfect” way of doing things.

Because it was in Swift, I could also reuse my main TextCase class which handles the formatting. There was a slight exception, where the arc4random_uniform function isn’t available on Linux, but I found a Linux suitable replacement for this.

There are also a few more reasons why I wanted to try this out, but they’re rather meta. For example, I’m a big fan of Swift, and it feels good working with “low-level” Swift if you can really call it that, and also because I just love the look of Swift in the default Xcode theme, with the SF Mono font 😍 (weird, I know, but it’s the truth).

The final code (as in what I’ve done so far), is three endpoints, which are actually just two. /title/{input text} is to return the given text in title casing, /spongebob/{input text} is for the SpongeBob case. The third one is just /{input text}, and it returns the text in every format available, which is just the two I mentioned so far. The results are in plain JSON, and also include the plain value that was sent in the request.

For example, here is an example response to the / endpoint:

{
    "plain" : "what the hell is this",
    "title" : "What the Hell Is This",
    "spongebob" : "wHAT ThE Hell iS thiS"
}

Anyway, you can view the project over at GitHub, and if you want to suggest any new formats (or even write some yourself), just let me know on Twitter at @chrishannah

What I've Been Up to Over the Past Few Weeks

It’s been a while since I actually wrote something, and that’s mainly because of my university work that’s been piling up (I finish this June!), and also because I’ve been developing a few mini projects with Swift. The latter is what I’m going to be writing about today.

Basically, over the past few weeks I’ve been getting back into using the command line more. Why is a hard question, but mainly because I’m a nerd, and it’s pretty fun!

It started when I kept seeing a trend of more of the people I follow on Twitter, either retweet or post GIFs of command line apps. It also led me to Hyper, which is a terminal application, and it’s actually built using JavaScript, HTML, and CSS. You can also customise it a ton, especially with the massive amount of themes available.

I personally, have Hyper set up with the hyper-ayu theme, and my favourite monospaced font, SF Mono.

This is getting a bit too meta, so I’ll bring it back on topic.

So I’ve actually developed four command line applications in the past two weeks, and they’ve all been build using Xcode/Swift[1]. The apps themselves are unix executable files, that can just be double-clicked and ran, but on each project I include more helpful installation/usage information.

cwiki

(Not to be mistaken with my macOS app, Qwiki)

This is the first one I made, and it was probably the easiest of them all. That’s because the majority of the code I could just reuse from my already released app, Qwiki! This app, cwiki , is just a super minimal version of that app.

You just type cwiki followed by a search query, and it will print out the most relevant matches. It does however, only print out a basic description of the articles.

Check out cwiki on GitHub.

So after the first project, I was a bit more intrigued, I decided to make a more interactive app. slink is purely a URL shortener that uses the Goo.gl API, but this lets you shorten, and also expand (Goo.gl) shortened links.

The slightly more complex functionality than before, led me to work out how options are managed in command line apps. So if you want to shorten or expand a link, just use either -s, --shorten, -e, or --expand. I also made a mini usage guide, that you can print out using -h or --help 🤓.

Check out slink on GitHub.

hacker

The third project was a bit similar to the first two, in that it made use of a few different options to return different data, but it also presented it like cwiki.

It’s a basic interface for Hacker News, and by making use of the various options, you can retrieve the new, top, and best lists.

Check out hacker on GitHub.

TitleCase

Okay this one is really simple, it makes use of Brett Terpstra’s TitleCase API, which formats a given string of text to the AP Title Case style. I actually find these types of tools perfect when writing a blog post, as usually the title is formatted incorrectly.

The API was probably the easiest one I’ve ever used. But then again, there was only one parameter, no options, and one return type.

Check out TitleCase on GitHub.


Now I guess everyone knows what I’ve been up to, so I can get back to slaving away over university work, and making some random projects!

P.S. I actually have some other really great news that I’m going to share here soon, but I’m just waiting on it being finalised a bit more.


  1. My favourite programming language 😍. ↩︎

Getting Started with UITableView: Populating Data

This article is part of a collection of articles about Swift Basics, where I try to explain different parts of Swift development in a more understandable way.


In most iOS applications, you will probably need to use a UITableView at some point. In this short guide, you will find out how to create a UITableView, and populate it with your own data.

UITableView

As Apple say in the documentation, “A table view displays a list of items in a single column.”. Basically, it’s a list of cells, that you can take complete control over. With a UITableView object, there are two ways in which you can control them. They are the UITableViewDelegate, and the UITableViewDataSource. The delegate is what manages the interactions on the table cells, such as selecting and reordering. The UITableViewDataSource is as you may of guessed, what controls the data that populates the table, and also configures the cells in the Table View. However in this guide, we will just be focussing on the DataSource, as this is all we need to populate a TableView with data.

Styles

There are various ways in which you can customise the style of the TableView manually, but there are two main styles that you can choose from in the InterfaceBuilder, “Grouped” or “Plain”. There aren’t many differences, but in the “Plain” style, each cell fills the Table, and the relevant header/footer float above the cells. However in the “Grouped” style, the sections are visually separated into groups, with the addition of a background colour.

Creating the Project

We’ll start with a new Xcode project. So create a new iOS project, and select the “Single View Application” template. Then you can give it a name, for this example I’m using “TableViewExample”.

Just make sure the Language is Swift, and the other options aren’t needed for this example. This will create all the necessary files, such as “AppDelegate.swift”, “ViewController.swift”, and “Main.storyboard”.

Putting a UITableView on the Screen

Click on the “Main.storyboard” file, and from the object library on the right, drag a Table View onto the view (There should only be the one).

Then to make sure it works on all iOS devices and screen sizes, we’ll set up the layout. Just drag the corners of the TableView so that it fills the view, but keeps the top status bar visible, it should automatically align. Select the Table View, and then open up the “Add New Constraints” view from the bottom right corner. It is the icon with a square, which has a vertical line either side.

Once you constraint view appears, select the four lines around the square at the top, while making sure each value is 0. This will simply make it fit to the edges on any screen size.

Configuring the UITableView

Now we need to configure the Table View so that we can manage it later on. So select the Table View, and then click to show the “Attributes Inspector” from the right sidebar.

The only values you need to change are:

All we are doing with these settings, is making the cells in the table dynamic, so that we can update them with live data later on. Then we set the style to grouped, so we can see each section better visually.

UITableViewCell

As we also want to populate the cells with some data later on, we will make use of the dynamic prototyping in Interface Builder, to design the cells.

Firstly we will set a “Reuse Identifier” for the cell, this is so that we can reuse the same cell prototype when loading the TableView. To do this, just select the cell (it may be easier to do this in the Document Outline to the left”, and while still showing the “Attributes Inspector”, set the Reuse Identifier to “PlainCell”.

Linking the UITableView to the ViewController

We will manage the Table View from the initial View Controller, so the next step is to set it as the DataSource of the Table. You can do this programatically, but for this example we will do it using Interface Builder. To do this, select the Table View, and then choose the “Connections Inspector” in the right sidebar.

From there, just click and drag from the open circle to the right of “delegate” and “dataSource” to the View Controller icon at the top of the view. Then in the “ViewController.swift” file, we will need to set the class to be the DataSource. Just replace the current class definition:

class ViewController: UIViewController {

To the following:

class ViewController: UIViewController, UITableViewDataSource {

It will show some errors right now, but that is just because we haven’t implemented the required functions yet.

Populating the Table View

We have the Table View set up in Interface Builder, and it’s linked to the View Controller, so now it’s time to populate it with real data. At the top of the View Controller class, just below the code you’ve just written, copy the below code:

let sections = ["Fruit", "Vegetables"]
let fruit = ["Apple", "Orange", "Mango"]
let vegetables = ["Carrot", "Broccoli", "Cucumber"]

This is just three arrays that will be used for the section headings, and the content of each of them.

UITableViewDataSource

To fill the table with data, we need to write four functions to do the following:

Section Headings

We already defined the section headings before, so all we need to do here is to return the string for the associated section, which the function receives as an Int.

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return sections[section]
}

Number of Sections

This is quite a simple method, and it just tells the TableView how many sections there are. We already have the section headings in an Array, so we can just return the count value of this.

func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}

Number of Rows

Very similar to the method above, but this time we have slightly more complexity in how we return the value of the number of rows. As this method is for every section, we first need to check which section it is for, and then return the count value of the relevant array.

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  switch section {
  case 0:
    // Fruit Section
    return fruit.count
  case 1:
    // Vegetable Section
    return vegetables.count
  default:
    return 0
 }
}

Configure the Cell

The last part of populating the Table View, is to load the data into the cell. We do this by first creating a UITableViewCell object, by making use of the dequeueReusableCell(withIdentifier:) function. This uses the Reuse Identifier we set earlier, to dynamically reuse one of the cells that have already been created. Then depending on the section that the cell is in, we set the text of the text label of the cell, to the value from the relevant array. After this, the cell is returned, and it is displayed.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  // Create an object of the dynamic cell "PlainCell"
  let cell = tableView.dequeueReusableCell(withIdentifier: "PlainCell", for: indexPath)
  // Depending on the section, fill the textLabel with the relevant text
  switch indexPath.section {
  case 0:
    // Fruit Section
    cell.textLabel?.text = fruit[indexPath.row]
    break
  case 1:
    // Vegetable Section
    cell.textLabel?.text = vegetables[indexPath.row]
    break
  default:
    break
  }  

  // Return the configured cell
  return cell

} 

Results

If you run this project now, it should look like this:

Final Code

Here is the final code for the View Controller that we created:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {  

  let sections = ["Fruit", "Vegetables"]
  let fruit = ["Apple", "Orange", "Mango"]
  let vegetables = ["Carrot", "Broccoli", "Cucumber"]

  override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
  }

  // MARK: UITableViewDataSource

  func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return sections[section]
  }

  func numberOfSections(in tableView: UITableView) -> Int {
    return sections.count
  }

  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    switch section {
    case 0:
      // Fruit Section
      return fruit.count
    case 1:
      // Vegetable Section
      return vegetables.count
    default:
      return 0
    }
  }

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // Create an object of the dynamic cell "PlainCell"
    let cell = tableView.dequeueReusableCell(withIdentifier: "PlainCell", for: indexPath)
    // Depending on the section, fill the textLabel with the relevant text
    switch indexPath.section {
    case 0:
      // Fruit Section
      cell.textLabel?.text = fruit[indexPath.row]
      break
    case 1:
      // Vegetable Section
      cell.textLabel?.text = vegetables[indexPath.row]
      break
    default:
      break
    }

    // Return the configured cell
    return cell
  }

} 

You can find the example project on GitHub.

Congratulations! You’ve now developed an app that makes use of a UITableView, along with a UITableViewDataSource to dynamically populate data, and also to configure the UITableViewCell. As this is an ongoing series of articles, you can expect more guides on how to take this project even further.