Articles and podcasts about Swift development, by John Sundell.

Genius Scan SDK

Presented by the Genius Scan SDK

This article has been archived, as it was published several years ago, so some of its information might now be outdated. For more recent articles, please visit the main article feed.

Implementing throwing protocol functions as non-throwing

Published on 05 Nov 2019
Basics article available: Protocols

In Swift, it’s possible to satisfy a throwing function protocol requirement using a non-throwing function, which can be very useful in certain situations. For example, let’s say that we’ve defined a protocol for parsers that enable us tokenize a string in some way:

protocol TokenParser {
    func parseToken(from string: String) throws -> Token
}

While certain implementations of the above protocol will need to throw, that won’t necessarily be true for all conforming types. For example, the below KeywordParser throws, while TextParser doesn’t:

struct KeywordParser: TokenParser {
    func parseToken(from string: String) throws -> Token {
        ...
    }
}

struct TextParser: TokenParser {
    // This will satisfy our protocol requirement, even though
    // this implementation doesn't actually throw:
    func parseToken(from string: String) -> Token {
        ...
    }
}

Since the original declaration of our protocol function is marked as throwing, we’ll always need to call it with try when the exact conforming type isn’t known — regardless of whether the underlying implementation actually throws:

let parsers: [TokenParser] = ...

for parser in parsers {
    // Since all we know about each parser within this iteration
    // is that it conforms to our 'TokenParser' protocol, we'll
    // need to use 'try' when calling its function:
    let token = try parser.parseToken(from: string)
}

However, when dealing with a non-throwing conforming type directly, we can now omit the try keyword — even though the original protocol requirement was marked as throwing:

let parser = TextParser()
let text = parser.parseToken(from: string)

It’s a small feature, but the fact that we can implement a throwing function requirement using a non-throwing one gives us a slightly greater degree of flexibility when conforming to protocols that contain such functions.

Genius Scan SDK

Swift by Sundell is brought to you by the Genius Scan SDK — Add a powerful document scanner to any mobile app, and turn scans into high-quality PDFs with one line of code. Try it today.