iOSDevUK Lightning Talk about Swift Playground Books

Links from the talk

  1. Playground Book package format
  2. WWDC 2016 talk about Swift Playgrounds
  3. My fix of Talking to the Live View
  4. Ash Furrow’s playgroundbook command-line tool
  5. My PlaygroundSupportMock framework for building an app from a book
  6. My pgbookc script for turning a Contents folder in a host app into one that you run as a book
  7. My ShapeSearch playground book and host app built using those tools

Read my previous post on authoring a Swift Playground Book for more information.

Authoring an iOS Swift Playground Book

I expect at some point Apple will have some kind of Playground Book authoring solution, but until then, I’ve hacked together something basic that I am ready to share.

Take a look at my previous post if you’re getting started with playground books. The important things to know are:

  1. The book is a package with a specific folder layout of chapters and pages.
  2. The left-hand side is a stateless playground with markdown and code.
  3. The right-hand side is a stateful live view that can host a View Controller and do pretty much anything you could do in an app.
  4. The playground view and live view can communicate via a simple asynchronous inter-process communication mechanism.
  5. The book is delivered as Swift source files, assets, and plist config files.

As I mentioned in the last post, Ash Furrow has a way to generate this format from a .yaml description and playground files. Even if you don’t ultimately use it as your book source, it’s a good way to generate your initial package structure. The same project also has a linter, which you should use no matter how you author playground books.

The drawback of trying to write an entire book this way is that some of the code lives in the .yaml file and is hard to write and check.

I wanted a way to:

  1. Write the code in Xcode (to get autocomplete, docs, etc)
  2. Build it there too
  3. Run it in a host app where I could test the LiveViews in the simulator
  4. Unit-test the playground and LiveView code

I started by putting a book’s Contents folder into a skeleton app and loading the first page’s LiveView as my rootViewController. The first problem is that on the iPad, there’s a framework called PlaygroundSupport with support for Swift Playground features like the messaging between the playground and LiveView. This framework is not currently available in Xcode.

To make it buildable in Xcode, I made PlaygroundSupportMock. This is a work in progress, and I will add more support of PlaygroundSupport as I need it. You can add it to a skeleton app via Carthage.

The second problem is that the format requires each page folder to have a Contents.swift and an optional LiveView.swift. But, apps cannot have two files with the same name in the same module.  To get around that, I wrote a script called pgbookc to copy the Contents folder from the host app and rename any Contents-*.swift or LiveView-*swift files (removing the -* suffix).

Finally, there are several places in the book where code that would work in the book could not work in an app (and vice versa). So, I added a feature to pgbookc to look for special comments in the Swift files that help it to alter it to work as a book.  For example, here is some typical code you might find in a book (to send a PlaygroundValue dictionary to the LiveView and call it from the playground itself)

func hasAttribute(shape: Shape, attribute: ShapeAttribute) -> Bool {
    let attributes: Set = shape.attributes
    return attributes.contains(attribute)
}

hasAttribute(shape: cloud, attribute: .IsGray)

The problem is the last line, which must be at the top-level in a playground (but cannot work in an app).  So, pgbookc will look for any line that ends with

// REMOVE LINE

and removes that entire line. This lets you write:

func Contents0102() -> Bool { return // REMOVE LINE
hasAttribute(shape: cloud, attribute: .IsGray)
} // REMOVE LINE

The first and last line will be stripped from the book, but it’s there for the app build. It’s also there for tests, which lets me write:

func testContents0102() {
    XCTAssert(Contents0102())
}

To make sure any playground code in a Contents.swift file works.

I have an (almost done) Playground Book that I am writing using this technique. It’s called Shape Search and has the reader build a simple guessing game that teaches how to do a binary search.

Swift Playground Books: 2-Sep-2016

I imagine a lot of the information here is going to go out of date fast, but if you are looking at playground books today, here is where to start.

  1. The WWDC 2016 talk, Introducing Swift Playgrounds, has a lot of technical detail about the .playgroundbook format and how the LiveView proxying works.
  2. The demo for that talk is available on Apple’s dev site, but it’s out of date. I’ve been updating it for each iOS 10 Beta (to track Swift 3). Go to my GitHub to get the fixed Talking to the Live View sample.
  3. The documentation for the .playgroundbook format can be found on the Apple Developer site.
  4. Erica Sadun, who has written the book on Xcode playgrounds did some early investigations of iOS Swift Playgrounds. You might want to read them — here is Part I, Part II, Part III, Part IV,  and Part V.
  5. Ash Furrow made a playground book linter and authoring tool (source). You can use the linter on any .playgroundbook (however you make it), and the authoring tool allows you to specify the parts of the book in a .yaml file, and it puts each piece in the correct file and folder for you in the .playgroundbook package.

Habits 3.0

Back in 2008, I learned Objective-C to make my first “iPhone OS” app, Habits. When it was released, Habits looked like this:

habits-screen

This weekend I finally finished v3.0 and made it free.

As this is a developer site, the more interesting thing to note is that Habits was originally made in the first iPhone supporting version of Xcode (with external Interface Builder) and I have been migrating the project file from version to version since then (using 7.3.1 to make the current build).

Some things that were introduced into Habits for this version:

  1. Swift – all new classes were made in Swift and many existing ones were refactored into Swift
  2. Accessibility – Since NSSpain 2015, I’ve been running my iPhone with triple-Home to get into VoiceOver (suggested by Hermes Pique in this talk). Doing that made me realize (1) what it was like to use Habits without looking at it (2) how easy it was to make it work properly.
  3. fastlane – specifically “deliver” to manage the iTunes record and “frameit” for fancy screenshots
  4. Carthage – there had never been 3rd party libraries in Habits, but I decided that one was worth it this time.
  5. TOCropViewController – A simple framework that does one thing very well – provide a View Controller for cropping images. I use this instead of the built-in iOS one because it supports locked aspect-ratios.

Enjoy!

Resume Tip: Link to yoursite/github, not github.com/you

I look at dozens of tech resumes and StackOverflow Careers profiles a day and I’m glad that more of them have GitHub links with some code to look at. In 2011, I wrote that I thought tech applicant assessment should be more portfolio based. I described what I would be looking for as an interviewer — one point was:

I could use an orientation: I need a starting place. The bigger the project, the harder it will be to jump in and take a look around. Give me what you’d give a new contributor.

Now that I’ve been spending time in GitHub with the intent of understanding a developer, I can see that I need an overview of the whole repository. GitHub’s public profile isn’t customizable and doesn’t do a good job of describing a person’s contributions.

I recommend:

  1. Create a page with a simple URL on your own domain (e.g. example.com/github) and write a narrative that takes me through your repositories.
  2. Link to that page in your resume and in your GitHub profile.

What exactly you do on this page really depends on your specific contributions and what kinds of jobs you are applying to. I made a GitHub tour page to dogfood my own suggestion, but also because, as a consultant, I imagine that some prospective clients look at my GitHub. I decided that a reasonable organization of my page was (approximate) reverse chronological order, but that might not be right for you. If you have a particularly popular project, you probably want that at the top. If you are looking to get a job in a specific technology, you should highlight contributions using it. Most importantly, edit the list down to what someone should look at.

Another benefit of this page is that I can mix-in the non-open source parts of projects. For example, App-o-Mat is not open source, but the app template is, so I can highlight a project that you can’t even see very well on my personal GitHub page. I can also describe a contribution where the code isn’t very interesting, but context is.

Whatever your contributions, I am sure that your own organization of them will be a lot better than GitHub’s default.

Test First as a Habit

I am not a TDD zealot (or even really a practitioner), but on The App Guy podcast, Paul Kemp asked me if I had any habits to share as an app developer.  I said:

My app developing habit … is get a new passing unit test every day.  […] that new green dot is my indication that I’ve at least added a little bit to the application.

This is a habit I started in earnest when I took B. J. Fogg’s Tiny Habits course. My tiny habit was to just run the simulator, and the best way I found of doing that was to run the tests through it. Then, writing a new test for whatever functionality I was planning next just seemed to be the perfect way to extend it.

Once I write that first test, I don’t TDD the rest of the way, but I’ve found that first test to be a good way to warm up.

Happy New Year – Favorite “Resolution” Posts

My own thinking on goals has evolved over the years to:

  1. Prefer forming processes to outcomes.
  2. Keep it simple (one physical, one mental and one social/spiritual)
  3. Monthly reassessment

So, given that, here are the two best things I read this New Year’s about resolutions:

Buster Benson’s Make Better Resolutions ends with this wonderful template:

Cultivate new or existing relationships with people who I can share my strongest interests with by doing X

My mental goal this year is to do 20 minutes of Duolingo Spanish practice every day. Per Ramit Sethi, I started 3 weeks ago.

The second “resolutions” piece I recommend is James Clear’s Forget Setting Goals. Focus on this Instead, which is a perfect introduction on why to prefer systems to outcomes.

I usually focus my physical goal around working out, but after 2.5 years of crossfit, working out is such a part of my routine, that I don’t really need to worry about stopping. This year will be about eating better, and for January I joined in our gym’s Whole 30 challenge (this is both social and physical). I will reassess in a month.