Categories
Education Portfolio Technology

Swift Student Challenge

A few days ago, Apple announced the winners of their Swift Student Challenge. I had applied and used my “taking a test” tactic, which was to hit ‘submit’ and then promptly erase the whole thing from my brain. (What’s done is done, and I feel silly worrying about something I have no control over.)

So when I got the email that “my status was updated” it was a bit of a surprise.

And when I clicked through the link (because, of course, they can’t just say in the email, you have to sign in) I was in for more of a surprise.

My submission had been accepted. I’m one of 350 students around the world whose work sufficiently impressed the judges at Apple.

Screenshot from Apple Developer website. It reads: Congratulations! Your submission has been selected for a WWDC20 Swift Student Challenge award. You'll receive an exclusive WWDC20 jacket and pin set at the mailing address you provided on your submission form. You'll also be able to download pre-release software, request lab appointments, and connect with Apple engineers over WWDC20 content on the forums. In addition, one year of individual membership in the Apple Developer Program will be assigned free of charge to eligible accounts of recipients who have reached the age of majority in their region. For details, see the WWDC20 Swift Student Challenge Terms and Conditions.
Neat!

Now, throughout the whole process of applying, I was my usual secretive self. I think two people knew that I was applying at all, much less what I was working on. Since it’s over with, though, it’s time for the unveiling.

What I made

I wanted to bring back a concept I’ve played with before: cellular automata. A few days before the competition was announced, I’d seen a video that really caught my interest.

Well hey, I thought, I’ve got some code for running cellular automata. I want to learn Swift Playgrounds. And I’ve been having fun with SwiftUI. Let’s combine those things, shall we?

The first big change was a visual history; when a cell dies, I don’t want it to just go out, I want it to fade slowly, leaving behind a trail of where the automata have spread.

The second was rewriting all the visuals in SwiftUI, which was a fun project. Animation timings took me a bit to get right, as did figuring out how to do an automated ‘update n times a second’ in Combine. The biggest issue I had, actually, was performance – I had to do some fun little tricks to get it to run smoothly. (Note the .drawingGroup() here – that made a big difference.)

And third, I didn’t want it to just be “here’s some code, look how pretty,” I wanted to actually use the Playground format to show some cool stuff. This turned out to be the most frustrating part of the whole thing – the Swift Playgrounds app doesn’t actually support creating a PlaygroundBook, and the Xcode template wasn’t supported in the then-current version of Xcode.

But the end result? Oh, I’m quite happy with it. PlaygroundBooks are cool once you get past how un-documented they are. You can, to borrow a Jupyter turn of phrase, mix code and prose in a lovely, interactive way.

Screenshot of the 'Grid' page of the playground book.  The full text is at https://github.com/grey280/SwiftLife/blob/master/Swift%20Student%20Submission.playgroundbook/Contents/Chapters/Chapter1.playgroundchapter/Pages/Grid.playgroundpage/main.swift
Don’t worry, the real version (and some videos) are below.

Doing the actual writing was pretty fun. This is a concept I’ve spent a lot of time learning about, just because it captured my interest, and I wanted to share that in a fun way.

Overall, I’m quite happy with the result. If you’d like to see more, I’ve made recordings of the ‘randomized grid’ and ‘Wolfram rule’ pages running, and the actual playground is available on GitHub.

Categories
Programming

SwiftUI’s Picker

I’m very excited about SwiftUI, and have been using what little free time I have to do some tinkering with it. I started during the beta period, which was fun in between being very frustrating; a lovely side effect was that some of the knowledge I picked up is… entirely wrong. One that caught me was the implementation details for the Picker type.
Based on the rather rough state of the SwiftUI documentation for Picker and ForEach,1 I’d assumed that combining the right binding with a .tag(_:) on the items would work:

Form {
    Picker(selection: $selectedItemID, label: Text("Choose Something") {
        ForEach(items){
            Text($0.label).tag($0.value)
        }
    }
    Text("You've selected item \(selectedItemID)!")
}

For reference, the models I’m referring to throughout are pretty simple:

struct CustomModel {
    let value: Int
    let label: String
}

Now this looks like it’s working in simple cases. However, I was trying to interact with a web API, so that items array looked something like this:

var items: CustomModel[] = [
    CustomModel(value: 7, label: "First"),
    CustomModel(value: 3, label: "Second"),
    CustomModel(value: 1, label: "Third")
]

If you tapped “Second” in the picker that SwiftUI generated, however, the text wouldn’t read “You’ve selected item 3!” like it should; it would be “You’ve selected item 1!”
A bit more tinkering revealed that, instead of pulling the value from the .tag(_:) on there, it was just using… the index in the ForEach.2
After some frustrated Googling, utterly despairing of Apple’s documentation, and a lot of StackOverflow searches, I finally figured out the solution:

Form {
    Picker(selection: $selectedItemID, label: Text("Choose Something") {
        ForEach(items, id: \.value){
            Text($0.label).tag($0.value)
        }
    }
    Text("You've selected item \(selectedItemID)!")
}

Quite frankly, I don’t have a good explanation of what’s going on here; last time I was tinkering with Pickers, the .tag(_:) provided SwiftUI with the information it needed to do the binding. (When I’ve got more time, I’d like to do another test — now that I’ve got the id keypath, do I even need the tag?)
I’d love a good explanation of what all the id keypath gets used for, and where else it might be necessary, but alas:


  1. It’s a bit unfair for me to link to No Overview Available when referring to SwiftUI; the coverage is low, but the problem isn’t so much that as the fact that ‘documentation coverage’ just doesn’t work as a metric for something like SwiftUI. The tutorials are a start, and a good sign that Apple was at least trying to rethink their approach to documentation, but they’re not nearly complete enough. 
  2. Zero-based index, of course, which seemed obvious to me, but got me a “???” response when I was complaining about this issue to a non-programmer friend.