Custom Xcode Templates for UIViewControllers

One way to enforce good software design and architecture is by using boiler plate code. Xcode supports custom file templates to help with this.

Let’s walk through creating a custom template for a UIViewController. First we will create the directory that Xcode looks for templates in. Then we will copy a template into this directory that we can edit.

$ mkdir -p ~/Library/Developer/Xcode/Templates/File\ Templates/Custom
$ cd ~/Library/Developer/Xcode/Templates/File\ Templates/Custom
$ cp /Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates/File\ Templates/Source/Swift\ File.xctemplate Swift\ UIViewController.xctemplate

Next open up TemplateInfo.plist.

 $ open Swift\ UIViewController.xctemplate/TemplateInfo.plist 

You will want to edit the Description and Summary fields.

Next open up ___FILEBASENAME__.swift.

$ open Swift\ UIViewController.xctemplate/___FILEBASENAME___.swift 

I like to split up my UIViewControllers using extensions. IBOutlets, members, and existing initializer‘s must be in the class declaration. However, lifecycle code can be in an extension. I also put segues and actions in their own extensions.

//___FILEHEADER___

import UIKit

class ___FILEBASENAMEASIDENTIFIER___: UIViewController {

    // MARK: - IBOutlets

    // MARK: - Members

    // MARK: - Initializers
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension ___FILEBASENAMEASIDENTIFIER___ {
    
    // MARK: - View lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    }

   override  func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
    }

   override  func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
    }
}

extension ___FILEBASENAMEASIDENTIFIER___ {
    
    // MARK: - Segues
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Inject dependencies in child viewcontrollers
    }
}

extension ___FILEBASENAMEASIDENTIFIER___ {
    // MARK: - IBActions
    
}

Now when you create a File -> New -> File, the Swift UIViewController template appears in the dialog box.

Custom Template