Iterating over SwiftUI views delivered in a Swift Package

The idea was iterate on shiny new SwiftUI code in a package. Turns out Xcode 11 Previews (as of beta 2) need some sheananigans to achieve that.

Anatoly Rosencrantz
2 min readJun 23, 2019

Straightforward Approach

Here we’ll try to have all the SwiftUI code in a package and continue development of a package enjoying live Views rendering.

Problem 1: SwiftUI Previews can not be rendered in an environment that does not have codesigning

Solution:

  1. create the package, close it Xcode — because a package can not be opened in two Xcode editors simultaneously
  2. create separate Xcode project with a terget that can be built for the platforms of interest (an iOS Framework, for example). We’ll need this wrapper-project only for rendering the package’s SwiftUI views
  3. drop the package into wrapper project, include into target dependency list
  4. now you can create SwiftUI wrapper view in the wrapper target

Now you can import the package into wrapper file and make sure it can be built.

Problem 2: Package is imported as module, so only public stuff can be seen from wrapper

Solution:
1. mark SwiftUI structs in the package aspublic

2. write constructors for Views in the package — you can’t use generated constructors of SwiftUI structs because they are generated as internal

Now you can see the rendered preview of a View.

Problem 3: you can not pin Preview of a View from wrapper target and edit code View from package

Solution: the most similar to on-demand rendering workflow I’ve succeeded to achieve was

  1. open two editors on one screen
  2. Editor one: canvas + editor, wrapper View from wrapper target
  3. Editor two: editor only, View from package

Now you can edit View from package, Cmd+B in order to build the target and pull changes from packet into the wrapper, then click on Resume button in the canvas in order to re-render wrapper View

In the end of the day, you’re publishing only Package repo and no one knows how screwed up the wrapper project is 💁

Problem 4: you will not have build errors marked in the package editor and canvas will give “Failed to build active scheme” error

Solution:

  1. write code without errors
¯\_(ツ)_/¯

More Correct Approach

The easier approach will be to create a taget project first, develop everything we need as part of the project using live rendering as much as we want, then create a Package 📦 and drop the needed code to the package.

--

--