Improving Swift Optional Unwrapping

Developing in Swift can often mean dealing with multiple levels of optional unwrapping. It’s messy and it’s annoying. Colin Eberhardt’s post got me thinking about better ways to deal with this, and he has some suggestions that work without modifying the language.

I think it’s worth making some tweaks to how optional unwrapping works, and I have two suggestions. Here’s an example of a fairly common scenario:

var a: Int? = 1
var b: Int? = 2
var c: Int? = 3

if let realA = a {
    if let realB = b {
        if let realC = c {
            let sum = realA + realB + realC
            println("Sum: \(sum)")
        }
    }
}

Unwrapping gets pretty cumbersome. The first problem is this deep nesting. Many times you don’t really want to do anything if the optional is nil, you just want to handle the case where all of the variables have a value. Why not allow if-let to include multiple terms, the way you might with any other if statement, like so:

var a: Int? = 1
var b: Int? = 2
var c: Int? = 3

if let realA = a && let realB = b && let realC = c {
    let sum = realA + realB + realC
    println("Sum: \(sum)")
}

Secondly, it’s often irritating to come up with another name for the unwrapped variable, and you sometimes even see developers do things like if let a = a. In this case, the name a represents the unwrapped optional inside the if statement. Why not allow the language to do something like this:

var a: Int? = 1
var b: Int? = 2
var c: Int? = 3

// Equal to if let a = a && let b = b && let c = c
if let a && let b && let c {
    let sum = a + b + c
    println("Sum: \(sum)")
}

It keeps the functionality of optionals in place, and adopts some of Swift’s conciseness, while making the code less leggy. I’ve filed a Radar that you can dupe if you agree.

I’m Building a New App

I’m working on a new app. After a little more than a year of focusing almost entirely on client work, I want to spend a little more time building my own. I’ll have more to say about the details of the app in a bit, but first I want to talk about a few goals I want to accomplish with this project.

Start simple and build on it. Rather than trying to do everything in 1.0, I plan to begin with a relatively modest set of features and expand on them in future releases. I hope this will make it easier to get a first version out the door, and give the app a little momentum through consistent updates. This will also give me a chance to collect and make use of some user feedback before I go too far in any particular direction.

Build something in Swift. My new app will be a Swift app. Yes, there are challenges with the tools (I’ve seen more Xcode source highlighting crashes than I can count) but I want to really get my feet wet with the new language. It’s still very early, but sooner or later I’ll need to be fluent in Swift, and there’s no better way to learn a language than by using it.

Experiment with In-App Purchase. I’ve never worked with in-app purchases in a production context, and I’d like to give it a try. IAP is clearly a huge part of the iOS ecosystem at this point, and this is a good, low-risk opportunity to get some real-world experience with it.

Ship something! I have a bad habit of starting personal projects and leaving them half finished. Often I’ll get distracted by client projects, or bite off more than I can chew in a first version. By keeping the scope narrow and allocating some dedicated time to working on the app, I’m going to get this one out the door before it gets bogged down.

The Spirit of the Law

Another day, another iOS app forced to remove features because of an unwritten App Store rule. This time it’s Panic’s excellent Transmit iOS, and the feature in question is the ability to upload files to iCloud Drive.

I’m not writing to debate the merits of the particular rule in question. As with lots of Apple’s rules, there are probably good points to be made on both sides. I am, however, interested in promoting just a bit more transparency so that developers have a solid understanding of what they can and can’t do.

Specifically: When possible, Apple should publish not just a list of rules, but a list of principles that underlie them. John Siracusa brought this up on the most recent episode of ATP. The worst thing about Apple’s recent flailing when it comes to the rules is that the changes seem to come out of the blue. A well-meaning developer, looking at Apple’s APIs and other apps that have been approved, could reasonably believe that buttons in a Notification Center widget are permissible. Same goes for uploading files to iCloud Drive.

Some statements of principle would go a long way toward helping developers comply with Apple’s ideas. For example, a principle could be something like “Notification Center widgets are intended primarily for display of information, not for interaction.” It doesn’t cover all possible scenarios, but it does convey important hints about Apple’s intentions for a particular technology. I can forgive the company for not having thought out every edge cases, but I have to believe that these types of principles drive a lot of the individual rules. (If not – which seems at least within the realm of possibility – we have a bigger problem.)

These principles don’t need to be set in stone. Just like the rules themselves, the principles could change over time. If Apple changes its mind about something, it should update the principles. That way, developers won’t need to spend so much time parsing the implications of this or that recent rejection.

As developers, we can’t afford to spend time building features that we won’t be able to ship. Good iOS and Mac developers want to obey the spirit of the law when it comes to the App Store rules. We want to build features that Apple will allow us to ship, and we want to take advantage of the newest features in the OS. As it stands, the company is making it riskier for developers to do so. Giving a window into the thought process behind enforcement of the rules would be a great start toward fixing that.

Shifting Sands in the App Store

Today brought the latest in a string of confusing rulings from Apple concerning iOS Notification Center widgets. Drafts author Greg Pierce was told that he must remove most of the buttons from the app’s Today extension. Pierce elaborated that buttons aren’t prohibited per se, but that “buttons that took you to the widget’s containing app to process/complete a task” are. The whole thing reminds me of the drama surrounding the PCalc calculator widget from a few weeks ago.

Here’s the thing I can’t figure out: What’s the reasoning behind the rule change? Most of the App Store Guidelines have a fairly clear rationale behind them: improving user experience, promoting security and performance, keeping the App Store clear of trashy content, etc. A rule against functional, as opposed to informational, Notification Center widgets doesn’t fit clearly into any of those buckets. It’s hard to argue that users suffer by having the option to perform useful tasks from widgets, nor do there seem to be widespread performance issues associated with them. If security were an issue, the solution would almost certainly lie in the API for working with widgets, and not in the selective enforcement of App Store rules. Both Drafts and PCalc are widely-respected apps and their widgets could hardly be accused of lowering the App Store’s standards.

The best explanation I can come up with is that Apple wants to limit Notification Center widgets to information presentation only. But why? How would that help either users or Apple? And why did Apple provide APIs that let developers build more capable widgets if we weren’t meant to do so? Why wasn’t this limit part of the rules before iOS 8 launched? Did something change at Apple in the interim? If so, why?

It feels as though there’s an internal struggle going on at Apple, and we’re experiencing the effects of it. Perhaps there’s been a change in the balance of power between one team and another. I can’t help but thinking there are at least a couple more shoes still left to drop. If Apple truly does aim to restrict Notification Center widgets to read-only presentation, it would be helpful of them to simply add that to the guidelines.