Type Names as Storyboard IDs

A while back I got in the habit of using the names my of custom types as different identifiers in iOS and macOS storyboards.

This post looks at a couple examples of how this simple practice removes the need for unnecessary strings and leads to cleaner code.

Storyboard Identifier

In the first example I’ve added a new UITableViewController to my storyboard, set the Class to CustomTableViewController and the Storyboard ID to “CustomTableViewController”

Xcode screenshot

I can now programmatically create a new instance of CustomTableViewController using its Storyboard ID:

var storyboardId = "CustomTableViewController";
var controller = Storyboard.InstantiateViewController (storyboardId) as CustomTableViewController;

Everything works as expected, as long as I have a view controller in my storyboard with a matching Storyboard ID, and there isn’t a typo in the string.

However, if I know that the Storyboard ID is the same as the type’s name, I can use the typeof operator and get rid of the string altogether:

var storyboardId = typeof(CustomTableViewController).Name;
var controller = Storyboard.InstantiateViewController (storyboardId) as CustomTableViewController;

Or even better, write an extension method like this:

public static T Instantiate<T> (this UIStoryboard storyboard)
	where T : UIViewController
=> storyboard.InstantiateViewController (typeof (T).Name) as T;

And cut the code down to:

var controller = Storyboard.Instantiate<CustomTableViewController>();

Now, I not only got rid of the string identifier, but I’ll also get build-time checking that my custom type inherits from UIViewController.

Reuse Identifier

An even more common example of benefiting from this practice, is in the context of Reuse IDs on UITableView or UICollectionView cells. Take the UITableViewCell subclass below.

public class CustomTableViewCell : UITableViewCell
{
	public void SetData(Item item) => titleLabel.Text = item?.Name;
}

In my storyboard, I’ve set the CustomTableViewController’s prototype cell’s Class to CustomTableViewCell:

Xcode screenshot

Then set the cell’s Reuse ID to “CustomTableViewCell”

Xcode screenshot

Normally, my CustomTableViewController (or UITableViewDataSource) GetCell override would look something like this:

public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
	var reuseId = "CustomTableViewCell";

	var cell = tableView.DequeueReusableCell (reuseId, indexPath) as CustomTableViewCell;

	cell?.SetData (Items [indexPath.Row]);

	return cell;
}

However again, if I know that the Reuse ID is the same as the cell type’s name, I can get rid of the string, and write another extension method:

public static T Dequeue<T> (this UITableView tableView, NSIndexPath indexPath)
	where T : UITableViewCell
=> tableView.DequeueReusableCell (typeof (T).Name, indexPath) as T;

And cut my GetCell override to the code below, with the build-time checks:

public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
	var cell = tableView.Dequeue<CustomTableViewCell>(indexPath);

	cell?.SetData (Items [indexPath.Row]);

	return cell;
}

Dig it?

You can find a the extension methods mention above and several more including support for collection views, here.