swiftxcodedocumentation

Separately documenting the elements in a destructuring assignment


In Swift, you can write a documentation comment for a single declaration like this:

/// The title of the view.
private var title: String

This documentation is automatically displayed by Xcode when you put your cursor on a use of title. You can use Markdown along with some Swift-specific semantic formatting, as described in this NSHipster article.

Is it possible to separately document the variables resulting from a destructuring assignment like this?

private var (titlePromise, titleSeal) = Promise<String>.pending()

I tried what I thought was the obvious thing,

private var (
    /// Promise that will resolve when we receive the view's title.
    titlePromise,
    /// Resolver function for the view's title.
    titleSeal
) = Promise<String>.pending()

but Xcode did not pick up on these comments. I found that it was possible to put a doc comment before both,

/// Promise and resolver for the view's title.
private var (titlePromise, titleSeal) = Promise<String>.pending()

in which case Xcode applies that documentation to both promise and seal. This is not ideal, since those variables—while related—are separate types with separate uses.

Is it possible to separately document both (or all) of the elements in a tuple assignment in a way that Xcode will pick up on?


Solution

  • This is an unsatisfying answer, because it only works in some situations.

    If you are accessing the variables “through a protocol,” you can define them separately and give them their own docstrings in the protocol instead of in the struct or class. It’s possible for two (or more) separate protocol variables to be provided by a single destructuring assignment in the conforming class.

    For example, suppose you have a class that fetches articles:

    class ArticleFetcherImpl {
        var (titlePromise, titleSeal) = Promise<String>.pending()
    }
    

    I have not been able to find a way to add separate documentation comments for e.g. titlePromise and titleSeal here. But if you define a protocol,

    protocol ArticleFetcher {
        /// Promise that will resolve when we receive the view's title.
        var titlePromise: Promise<String>
    
        /// Resolver function for the view's title.
        var titleSeal: Resolver<String>
    }
    

    and declare that ArticleFetcherImpl conforms to ArticleFetcher, then when you define a variable of type ArticleFetcher and put your cursor on its titlePromise property, Xcode will display the appropriate documentation comment. For example,

    class MyClass {
        var articleFetcher: ArticleFetcher = ArticleFetcherImpl()
    
        func fetchTheArticle() {
            // Putting your cursor on `titlePromise` here will
            // give you the desired documentation.
            articleFetcher.titlePromise.then { title in
                print("The title is \(title)")
            }
        }
    }
    

    In order for this to work, articleFetcher must be defined as an ArticleFetcher instance, not as an ArticleFetcherImpl instance.