Enhancing Readability: The Power of MARK Comments in Swift Development

When attempting to maintain our codebase it’s a good idea to have a clear and consistent way of structuring our code so it remains readable and easy to navigate. This becomes increasingly important as our codebase grows larger in size. There are several approaches and tools available for achieving this but the use of MARK comments is the one I want to highlight with this post.

What is a MARK comment and how do we use them?

MARK comments - also known as "MARK lines" - are comments with special powers that are interpreted by Xcode a little differently compared to regular comments. They serve as a kind of labels within our code to help us organize it and keep it easy to navigate and readable in both our code and Xcode's jump bar and minimap. There are three different types we can use to annotate our code; MARK, TODO and FIXME. Let's take a closer look at each one.

MARK

The MARK type is probably the most commonly used type of MARK comments (hence the name). With it, we can add a label, a dividing line or both to annotate sections of our files and make them more organized.

MARK with only label

// MARK: Properties
 
let myConstant1: String
var myVariable1: String

This adds an icon and the label "Properties" to the jump bar: MARK comment with only label

MARK with only divider

Sometimes we may just want to compartmentalize our code to simply make it clear that a chunk of code is separate, without adding labels. For this we can add a divider with the same // MARK: followed by a dash:

private func methodBelongingToFirstChunk() {}

// MARK: -

private func methodBelongingToAnotherChunk() {}

As expected, this shows a dividing line in the jump bar: MARK comment with only label

MARK with both divider and label

As mentioned we can easily add both a divider and a label.

// MARK: - Private Methods
    
private func myPrivateMethod() {}

private func myOtherPrivateMethod() {}

In the jump bar, this places a divider before the label: MARK comment with only label

The placement of the dash determines where the divider ends up so if we prefer the divider to be placed below the label we can simply put the dash at the end of the comment:

// MARK: Private Methods -
    
private func myPrivateMethod() {}

private func myOtherPrivateMethod() {}
MARK comment with only label

When looking at the minimap, MARK comments provide a clear overview of the file: MARK comment with only label

Compared to not using MARK comments: MARK comment with only label

TODO and FIXME

The TODO and FIXME types work exactly the same (even with dashes) but display their own respective icons to the jump bar. Keep in mind, however, that these comments do not show on the minimap.

public func myMethod() {
    // TODO: Add implementation here
}
MARK comment with only label
public func myOtherMethod() {
    // FIXME: Make this make sense        
}
MARK comment with only label

Conclusion

Structuring our code is always a good idea, especially when the files grow large. Keep in mind, though, that large files could be indicators that we need to refactor our code to split up the responsibilities into smaller ones and keep it more modular and more easily maintained. We should also not go overboard and start putting MARK comments on every other line, that would just clutter our files and defeat their purpose. Ultimately - as with so many things - it’s up to you and your team to find the right balance of how to use them.

Personally I try to avoid merging code containing FIXME or TODO comments, as my experience is that they tend to be easily forgotten. If you find yourself in a situation where you really need to merge your unfinished code (we all know it happens sometimes) with these types of comments, I highly recommend using a #warning("") statement instead.

public func myMethod() {
    #warning("TODO: Add implementation here")
}

This makes the compiler help remind you about their existence by putting a warning about it in the Issues navigator.