With iOS 10, Apple came out with an app for iPad called Swift Playgrounds, that has fun coding books that helps learn to code in Swift.

For WWDC 17, Apple's student scholarship asks students to create their own Swift Playground files that are "visually interactive". Since not all students have iPads to develop on, they can also create an Xcode playground, which will run in both Swift Playgrounds and Xcode Playgrounds.

I decided to apply for this scholarship and create my first Swift Playground. I ran into a few issues along the way, and I have documented them here.

You can check out my submission here!

File formats

The first major issue I ran into that was not immediately obvious to me is that there are two separate file formats: Xcode Playground and Playground Book, with the .xcplayground and .playgroundbook file extensions, respectively.

The differences between these are not documented well, but are very important to know about before deciding which one to develop.

Xcode Playgrounds

Playgrounds in Xcode came out before Playground Books, so this is an older format. Xcode playgrounds can be developed within Xcode on the Mac, and run on both Macs and iOS devices. They can be created easily through Xcode with a wizard.

half-on-large

They can target macOS, iOS, and tvOS, with access to the entire SDK for each platform.

Playground Books

Apple Documentation

side-regular Playground Books are specific to the Swift Playgrounds app on iOS, and only run on-device. Xcode is unable to provide any support while developing a Playground Book on your Mac, including nice things like code completion and compiler warnings / errors.

However, Playground Books are much more interactive and customizable. They include the following unique features compared to Xcode Playgrounds:

  • Animated cut scene pages built in HTML5
  • Full width live views (borderless)
  • Hidden code on each page (for hidden setup, teardown, and other interactivity code)
  • Custom auto-complete in the keyboard
  • Chapters of pages
  • Editable areas (restrict editing to a certain portion of code on the page)
  • Placeholders
  • Glossaries (add a list of terms and definitions viewable when tapping a term)
  • Each page can be assessed on a pass/fail basis.
  • Changes are tracked to each page and the page can be reset back to default by the user
  • Data can be stored in an NSUserDefaults-like key value store.

PlaygroundSupport

When developing a playground, there is a framework you can use to do helpful things, called PlaygroundSupport. This framework helps you to:

  • Access a playground page and manage its execution
  • Display and dismiss live views
  • Share and access persistent data

PlaygroundSupport was added in iOS 8, and it used to be called XCPlayground before that.

The live view you display on the right can be either a UIViewController or UIView.

Differences

While easier to create and cross-platform, Xcode Playgrounds are more limited in interactivity compared to Playground Books.

When I started my work for this scholarship, I did not realize that Playground Books use a separate format, so I started out creating an Xcode Playground and ended up switching mid-project.

I followed the Playground Book package hierarchy in the documentation and copied my code into a new book. Everything worked for the most part, except I had to change/separate some code because:

  • In a Playground Book, each page can consist of both a Contents.swift and LiveView.swift. Xcode Playgrounds only have a Contents.swift. LiveView.swift should contain code setting up the live view when the page is opened. You can set the PlaygroundPage.current.liveView in either file, but the code in LiveView.swift will be executed when the page opens, not when the Run My Code button is pressed.
  • Live views run isolated from the content and communication must be done through messages.
    • To support this communication, the PlaygroundSupport framework in Swift Playgrounds has many more utilities you should look at, including PlaygroundValue and PlaygroundViewLiveMessageHandler. These are specific to Playground Books. The PlaygroundSupport framework in Xcode does not contain these.

Learning by Example

The best way to learn how to write a Playground Book is by examining Apple's books. Download a book in Swift Playgrounds from the Featured page. Tap the share button at the top left and AirDrop it to your Mac. From there, you can right-click the .playgroundbook file and select Show Package Contents. Explore the code and layout of those. It will help you tremendously.

Developing a Playground Book

I've been writing my code in Xcode. Open your .playgroundbook in Xcode, and press cmd+1 to show the files/folders.

To run my book, I use AirDrop to transfer the file from my Mac to my iPad and run it there.

This is definitely not the best, but it's the most efficient method I've found.

Code completion

Some have suggested writing an Xcode playground and moving your files in between it and your Playground Book to get code completion. See here. This may work for simple projects, but for instances where you are using more advanced features in PlaygroundSupport, you will run into compiler errors, since PlaygroundSupport is different in Swift Playgrounds than in Xcode.

I have not found a reliable way to get code completion yet.

Debugging a Playground Book

There is no way to set breakpoints in either type of playground. Because of this, I was debugging via print statements. This got a lot harder when running a Playground Book since there is no console to look at.

Here's the solution I've found that works:

  • Use NSLog() instead of print().
  • Plug your iPad into a Mac using USB.
  • Open Console at /Applications/Utilities/Console.app.
  • Select your iPad from the Devices section on the left sidebar.
  • In the search bar, type the following:
    • process:Playgrounds process:ExecutionExtension process:CompilerExtension
    • Press Enter
  • You should see logs from both the Swift Playgrounds app and your own Playground in the console window.

Typically, when something crashes, you can see at least the description of the exception in Console, instead of a generic error that is displayed on screen.

You'll also now see constraint warnings and other warnings.

Cut Scenes

A cut scene is a special kind of page that renders HTML that is bundled into the playground. Apple used an app called Hype to create their animations for Learn to Code, but any HTML page will do.

half-on-large Believe it or not, Apple built this in HTML5, not in UIKit.

In a cut scene, it is important to add a button to go to the next page. In order to do this, make your button a link to the URL @next. When clicked, this will tell Playgrounds to go to the next page. Likewise, you can add a @previous link to go back.

Conclusion

If Apple wants people to create and distribute Playground Books, they NEED to allow Xcode to create them. It was a major pain creating my book without code completion or compiler warnings. Waiting to run on-device to see if what I did worked was no fun either. Thankfully AirDrop allows quick wireless transfer of Playground Books to my iPad, but even then, each time I sent an updated version to my device, it was copied along-side existing playgrounds, so pretty soon I ended up with hundreds of the same book from each iteration I pushed.

Even though the documentation is available, it is sometimes outdated and incomplete. I've filed two radars already with typos and incorrect information in the Playground Book documentation.

Hopefully, this experience improves in the future.