Swiftpack.co - aj-bartocci/SwiftUIPreviewHelpers as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
aj-bartocci/SwiftUIPreviewHelpers
Simple SwiftUI helpers for rendering UIKit / SwiftUI elements in previews
.package(url: "https://github.com/aj-bartocci/SwiftUIPreviewHelpers.git", from: "v1.0.0")

SwiftUIPreviewHelpers

This package contains helper structs and functions that make working with SwiftUI Previews a bit easier. You do not need to be using SwiftUI in your app to benefit from using SwiftUI Previews.

The package itself puts all code inside of the DEBUG macro, so that the code will not ship with release builds of your app. This means when using the library you should wrap your code in the DEBUG macro as well. This helps make sure you are not shipping preview related code with your applications.

Project Requirements

  • Swift 5+
  • iOS 10+
  • Xcode 11+

Targeting older iOS versions

Even though SwiftUI is iOS 13+ you can still benefit from SwiftUI previews in apps that target iOS 10+. This can be done by marking the preview provider code with @available(iOS 14, *), it must be 14 because this library uses some iOS 14 features. Since you never call this code directly (Xcode generates the previews automatically) it doesn't matter that it is higher than your minimum iOS version.

If your codebase already targets iOS 14+ then you do not need to worry about using @available(iOS 14, *) for your previews.

Helpers

The UIKit preview helpers follow the same general format. Each preview helper has 2 initializers, one initializer being a throwing closure that returns the UIKit element and the other taking a concreate instance of the UIKit element.

The closure based initializers can be useful for throwing errors from mock data, configuring the elements in specific ways, or for embedding the elements inside of container views / view controllers.

UIViewControllerPreview

UIViewControllerPreview is a wrapper of UIViewControllerRepresentable that makes it easy to render UIViewControllers.

UIViewControllerPreview {
    let data = ...
    let dependency = try JSONDecoder().decode(SomeDependency.self, from: data)
    let vc = TestViewController(dependency: dependency)
    return UINavigationController(rootViewController: vc)
}
UIViewControllerPreview(for: TestViewController())

UIViewPreview

UIViewPreview is a wrapper of UIViewRepresentable that makes it easy to render UIViews.

UIViewPreview {
    let data = ...
    let dependency = try JSONDecoder().decode(SomeDependency.self, from: data)
    let view = TestView(dependency: dependency)
    return view
}
UIViewPreview(for: TestView())

ThrowablePreview

ThrowablePreview is a wrapper View for rendering SwiftUI Views. This is for when mock data is needed and might throw errors. If an error is caught an error message will be rendered.

ThrowablePreview {
    let data = ...
    let dependency = try JSONDecoder().decode(SomeDependency.self, from: data)
    let view = SwiftUITestView(dependency: dependency)
    return view
}

PreviewSize

Using previewSize is helpful when working with Views so that you can size the previews to be specific sizes instead of the device size.

func previewSize(
    width: CGFloat? = nil,
    height: CGFloat? = nil,
    alignment: Alignment = .center
) -> some View

----------

UIViewPreview(for: TestView())
  .previewSize(width: 400, height: 300)

PreviewDevice

Using previewDevice is useful for rendering the previews on specific devices. This simply wraps the existing previewDevice function with some type safety. The previewDevice function provided by Apple uses strings for rendering the devices which can be annying. This helper function simple adds some pre-defined devices so you don't need to worry about having the correct string values.

func previewDevice(_ device: PreviewHelpers.Device) -> some View

----------

UIViewControllerPreview(for: TestViewController())
  .previewDevice(.iPhone11)

PreviewInDarkMode

Using previewInDarkMode simply sets the environment values to render the view in dark mode, which is a bit easier than the default way of doing it.

func previewInDarkMode() -> some View

----------

UIViewPreview(for: TestView())
  .previewInDarkMode()

PreviewInNavigationView (UIViewControllerPreview only)

Using previewInNavigationView is useful for embedding a UIViewController inside of a navigation view. This is mostly handy when you don't care about using a custom navigation controller. If you are using a custom navigation controller it is better to set it up in the UIViewControllerPreview initializer like the exmaple above.

func previewInNavigationView(displayMode: NavigationBarItem.TitleDisplayMode = .automatic) -> some View

----------

UIViewControllerPreview(for: ViewController())
  .previewInNavigationView(displayMode: .inline)

Example Usage in iOS 11 project

#if DEBUG
import SwiftUI
import SwiftUIPreviewHelpers

enum TestError: Error {
    case foo
}

struct SomeStruct: Decodable { }

@available(iOS 14, *)
struct ViewController_Previews: PreviewProvider {
    
    static var previews: some View {
        Group {
            UIViewControllerPreview(for: ViewController())
            .previewInNavigationView(displayMode: .inline)
            .previewDevice(.iPhone11)
            .previewInDarkMode()
            
            UIViewControllerPreview {
                let mockData = try JSONDecoder().decode(SomeStruct.self, from: Data())
                let vc = ViewController()
                return UINavigationController(rootViewController: vc)
            }
            .previewDevice(.iPhone8)
            
            UIViewControllerPreview {
                let storyboard = UIStoryboard(name: "Main", bundle: .main)
                let vc = storyboard.instantiateViewController(withIdentifier: "ViewController")
                return vc
            }
            
            UIViewControllerPreview {
                throw TestError.foo
            }
        }
    }
}
#endif

GitHub

link
Stars: 0
Last commit: 2 weeks ago

Ad: Job Offers

iOS Software Engineer @ Perry Street Software
Perry Street Software is Jack’d and SCRUFF. We are two of the world’s largest gay, bi, trans and queer social dating apps on iOS and Android. Our brands reach more than 20 million members worldwide so members can connect, meet and express themselves on a platform that prioritizes privacy and security. We invest heavily into SwiftUI and using Swift Packages to modularize the codebase.

Submit a free job ad (while I'm testing this). The analytics numbers for this website are here.

Release Notes

v1.0.0
2 weeks ago
  • Initial stable version

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics