Bug Workaround: Swift Playgrounds for iPad

While doing some work on more material for the site in Swift playgrounds, I ran into a serious bug in the Swift Playgrounds for iPad. I made a short video to tell you’re about it, and I’ve included an extended transcript afterwards.

Hello Folks this is Steve from the iOS Development Tips Weekly series on lynda.com and LinkedIn learning. A lot of the weekly tips using Swift playgrounds for iPad and much of the course material in the course I wrote Learning Swift Playgrounds Application Development uses a technique to get a view controller showing on the live view. Well I just had the current Swift Playgrounds 2.1 update from April 30 2018, cause chaos on my iPad Playgrounds, killing all my playgrounds with this lovely message every time I run something that worked before the update:

Let me show you what’s going on, and an easy workaround for it.

I’ve got on this iPad playground the code as I’ve always written view controllers to the liveView.

import UIKit
import PlaygroundSupport 

class ViewController:UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .blue
    }
}

// launch the live view
let vc = ViewController()
PlaygroundPage.current.liveView = vc

You make a view controller. For something simple, In viewDidLoad I changed the background color of the view. Under the ViewController class I assign ViewController to vc, then set the current playground liveView to vc.

I’ll run this and you’ll see you get that error which doesn’t tell you much. Try this with the step through and You’ll see it fails on the line view.backgroundColor = .blue.

I did some digging on this. I appears in viewDidLoad the view does not yet exist — even though it is supposed to. This only happens on the iPad app in 2.1. On Xcode playgrounds and Version 2.0 of the iPad app, it works fine.

I also found this bug only occurs on the first view controller. There’s a few workarounds which launch ViewController later and avoids a the problem if you launch something first that doesn’t access the view of the view controller.

The simplest is to embed the controller in a navigation controller. In Swift playgrounds, that’s two or three lines of code. To embed the controller, after let vc = ViewController(), add this to embed vc into the Navigation controller:

let navigationController = UINavigationController(rootViewController: vc)

Then change the liveView to navigationController:

PlaygroundPage.current.liveView = navigationController

Run this and the live view turns blue, but with a navigation bar.

If you wish to get rid of the navigation bar, add this line:

vc.navigationController?.isNavigationBarHidden = true

so your code looks like this:

// Set up live View
let vc = ViewController()
let navigationController = UINavigationController(rootViewController: vc)
vc.navigationController?.isNavigationBarHidden = true
PlaygroundPage.current.liveView = navigationController

Run again:

This has the added benefit you can use navigation controllers in code of course. If you want to learn more about using navigation controllers in code, you can check out this tip.

If you don’t want to use a navigation controller, there is a second way of handling this. You can use a launching class that presents your view controller modally. Add the following class to the playground:

class StartViewController:UIViewController{
    override func viewDidLoad() {
        super.viewDidLoad()
        //uses global vc, you might want to encapsulate more.
        present(vc, animated: false, completion: nil)
    }
}

I set animated here to false so you don’t see the launch. Launch the live view with this:

// Set up live View
let vc = ViewController()
// set up properties of vc here
let startVC = StartViewController()
PlaygroundPage.current.liveView = startVC

And you’ll get the blue background

I did report the bug to Apple, and we’ll see what happens. If you liked this tip, check out my iOS Development Tips Weekly dropping every Tuesday afternoon on lynda.com and LinkedIn Learning.

6 Replies to “Bug Workaround: Swift Playgrounds for iPad”

  1. Thanks for posting this article. I ran into similar problems with 2.1…. gee Apple has really screwed this up! I was on the beta test program and these issues are new in the production release… which makes me wonder why even bother being a beta tester if the beta version has no relation to the final release. I’ve got some fairly complex playgrounds & most are screwed by this bug.. even your workaround doesn’t sort it out unfortunately as I was already using a navigation conroller on my first viewController (which was ok)… the 2nd viewcontroller is where it crashes. I have 4 days left before my old bug free beta version expires :(

    1. I stopped doing the beta for that exact reason.Often Apple does not warn us in beta they will change things. My book Practical Autolayout got nailed by that when Apple did not have in the beta that they changed the location and use of the resolver, pretty much obsoleting my book book a week after publication.

      I have playgrounds with multiple view controllers working fine, though they do little more than change titles and colors. I haven’t tried anything heavy duty yet. The third solution which is a little problematic but may work in your situation is in the source controller push the destination controller, then have the source controller run a method to load and layout your views. Another thing I did not try yet is using programmatic segues, but that might work too. Might have to play with that.

  2. Hi Steve, I transferred my playgrounds to xcode yesterday & fortunately got them running again… which is probably better in the long term. I had really enjoyed swift playgrounds for the past 12 months because its so quick to learn & test new app ideas.

    My playgrounds over the months have become reasonably complex, I’m fetching compressed directories with scn, json, images, html etc from secure webservers. I’m using those 3d assets in scenekit/arkit and have multiple views & functionality, joy sticks ui etc. Some of my bigger playgrounds are 2-3 thousand lines with several classes, so troubleshooting this type of serious bug is a nightmare. I had worked out that view was nil before finding this article… I also had two devices running the different versions so knew it was an introduced bug. But this article certainly helped to cement my own findings.

    1. There is point where the complexity level gets so big that playgrounds don’t work well any more. Looks like you hit that point, even if using the sources folder. Are you aware of the sources folder BTW? For code you have established as working, you can have classes and files stored there and precompiled to speed up Playgrounds. I have yet to try the bug if the view controller is in sources, but It’s something else I should try. If you are interested and want to know more, let me know.

      Either way it sounds like you are ready to go the next step of Xcode.

  3. Steve, thank you so much. This has been killing me. Ever since I took your Lynda.com course on prototyping with the iPad, I’ve been hooked. I love your weekly tips as well. Since day 1 I’ve been combing the web for even an acknowledgement that this was an issue. So glad you found a workaround. Thanks so much.

    1. You are very welcome. I know how you feel about “killing me” especially when I had deadlines for more Tips using playgrounds go swooshing by. Look out for my next course (still can’t say what yet) which should be out in a few weeks. You’ll find it very useful. I got hooked on that topic for playgrounds myself just writing it.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.