UIPreviewCatalog

UIPreviewCatalog is a library that takes snapshots of SwiftUI’s Preview and generates Markdown that lists them.

It outputs a list of snapshot images of the View describing the Preview, and Markdown like the following.

outputs

output_markdown

The demo project is here.
yyokii/DemoUIPreviewCatalog

Usage

There are three steps to follow.

  1. install the library
  2. generate the PreviewItem array
  3. generate snapshot and Markdown files

1. Installing the library

Since it does not affect the functionality of the application, add the dependency to the test target.
It can be run in unit tests.

It can be installed using the Swift Package Manager.
It can be installed via Xcode or the Package.swift manifest.

2. Generate the PreviewItem array

There is a struct called PreviewItem in this library, which is the target of creating a snapshot.
You can define it yourself as follows, or you can use an existing code generator to simplify it.
The file you create should be included in your test target.

import SwiftUI
import UIPreviewCatalog
@testable import DemoUIPreviewCatalog

let previewItems: [PreviewItem] = [
    .init(name: "BlueView_Previews", previews: BlueView_Previews._allPreviews),
    .init(name: "ContentView_Previews", previews: ContentView_Previews._allPreviews),
]

Code generation using Sourcery

In an application under development, it is troublesome to manually create the PreviewItem array as described above. So, let’s use Sourcery to extract the struct that conforms to the PreviewProvider and generate the PreviewItem array.

First, install Sourcery.
Then, create a template file for source generation.
The template file is PreviewItem.stencil. Please create the same one.

Then use the Sourcery command to generate the code.
A sample is shown below.

$ sourcery \
   --sources /Users/{Foo}/Desktop/DemoUIPreviewCatalog/DemoUIPreviewCatalog \
   --templates /Users/{Foo}/Desktop/PreviewItem.stencil   \
   --output /Users/{Foo}/Desktop/DemoUIPreviewCatalog/DemoUIPreviewCatalogTests \
   --args mainTarget=DemoUIPreviewCatalog

--sources : Specify the path to analyze the sources. Here, the main target of the application is specified.

--templates: Specify the path to the template files. We will use the ones we created earlier.

--output: Specify the path where the generated code will be placed. It is to be included in the test target.

--args : Give an arbitrary variable. The generated file will be placed in the test target, but since it uses the Preview information of the main target, we need to write @testable import DemoUIPreviewCatalog to resolve the reference. Therefore, here we specify the module name of the main target of the application.

Executing this will generate the following file.

import SwiftUI
import UIPreviewCatalog
@testable import DemoUIPreviewCatalog

let previewItems: [PreviewItem] = [
    .init(name: "BlueView_Previews", previews: BlueView_Previews._allPreviews),
    .init(name: "ContentView_Previews", previews: ContentView_Previews._allPreviews),
]

3. Generate snapshot and Markdown files

Set the environment variable in Edit Scheme of Xcode.
Name : PREVIEW_CATALOG_PATH.
Value : The output path for images and markdown. For example, $(SOURCE_ROOT).

add_environment_variable

Output a snapshot and a Markdown file.
The file will be output by executing createCatalog(previewItems:) as shown below.

func testOutputUIPreviewCatalog() {
    let catalog = UIPreviewCatalog(config: .defaultConfig)
    do {
        try catalog.createCatalog(previewItems: previewItems)
    } catch {
        print(error.localizedDescription)
        XCTFail()
    }
}

Contributions

Pull requests and issues are always welcome. Please open any issues and PRs for bugs, features, or documentation.

License

UIPreviewCatalog is licensed under the MIT license. See LICENSE for more info.

GitHub

https://github.com/yyokii/UIPreviewCatalog