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
Add a blank iOS playground to the project in the usual way (
Name the playground and save it in the root of the project directory and add it to the top level project group:
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
Resources sub-folders of the playground:
Xcode complains about “Workspace integrity”:
Closing and reopening the Xcode project fixes the problem:
We can now try accessing the view controller in our app target:
This works not just for types (classes, structs, enums, etc.) but also for resources in the app target asset catalog:
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:
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:
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:
Xcode 12.5 Warning
In Xcode 12.5, this generated a warning in the playground console (edited for brevity):
objc: 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.