Xcode 12.5 Playground Access To App Types

Xcode 12.5 added enhanced playground support. When you add a new playground to a project it defaults to having access to the types in your App target. This means you are not forced to import frameworks or Swift packages to share code between your app target and the playground.

Last updated: Dec 14, 2021

Playing With Playgrounds

I’ve long wanted to have a scratch playground attached to an Xcode project that I could use to try out ideas and play with the types in the project. The problem has always been that a playground added to a project did not automatically have access to the types in the project.

My first try at adding playgrounds to Xcode projects added shared code to a framework that I then imported into the playground. With the release of Xcode 11, I switched to sharing code by creating Swift packages. That works well but only for types and resources you put in the package.

Xcode 12.5 Playgrounds

Xcode 12.5 has enhanced playground support that, if it works, might finally give me what I want. From the Xcode 12.5 release notes:

A Playground in an app’s project can now access symbols from the app target. New playgrounds you create have this option on by default. To enable this functionality in existing playground documents, turn on the Import App Types option in the File Inspector. (66357893)

Let’s give it a try with my minimal Xcode project. It has a small custom view, named GridView, that draws a grid. I’m using that view in a view controller I’ve named GridController:

Xcode Project File navigator

Add a blank iOS playground to the project in the usual way (File > New > Playground...):

Xcode template browser with blank iOS playground selected

Name the playground and save it in the root of the project directory and add it to the top level project group:

Xcode save playground dialog

At this point I hit a problem (FB8996491). Clicking on the playground in the navigator does nothing. The playground does not show up in the editor. I also don’t see the Sources and Resources sub-folders of the playground:

Xcode project navigator showing Playground.playground file

Xcode complains about “Workspace integrity”:

Xcode Workspace Integrity - Couldn’t load project Playground.playground

Closing and reopening the Xcode project fixes the problem:

Xcode project navigator with valid playground

We can now try accessing the view controller in our app target:

Xcode playground with access to a view controller in the app target

This works not just for types (classes, structs, enums, etc.) but also for resources in the app target asset catalog:

Playground access of star image

Import App Types

Starting with Xcode 12.5, new playgrounds have access to the application target by default. You can turn this on for playgrounds created with earlier versions of Xcode in the playground settings:

Playground settings with Import App Types enabled

Working With Swift Packages

Let’s try using this with a more realistic project where I’m using some Swift packages. I’ve taken my GridView class and moved it to a Shared swift package:

Xcode project navigator with Shared package containing GridView.swift

This has no effect on my playground accessing a view controller. What happens if I try to access the GridView directly? The app target has the Shared package as a dependency but I still need to import the package to the playground for it to be in scope:

Import Shared in playground to access GridView

Xcode 12.5 Warning

In Xcode 12.5, this generated a warning in the playground console (edited for brevity):

objc[81644]: Class _TtC6Shared8GridView is implemented in both Grids.app/Grids and Shared_1BC5906757289D_PackageProduct. One of the two will be used. Which one is undefined.

This looked like the playground was seeing the GridView type in both the Grids.app target and the Shared swift package (FB8990142). This bug is fixed in Xcode 13.0.