Monthly Archives: July 2016

Swift Maturity

Ted Kremenek of Apple announced on the Swift evolution announcements mailing list that the team will no longer accept source-breaking changes for Swift 3. That is, changes that would require developers’ own Swift code to change. He notes that this means many desirable features will not make the cut, and will have to be pushed to Swift 3.1 or beyond:

The challenge of course is reconciling these diametrically opposing goals: maintaining source stability while having the ability to incorporate more core (and important) language changes that are possibly source-breaking.

How will they balance this going forward? He hints that the team wants to support a mechanism whereby developers can specify a version of Swift as a parameter to the compiler. Your code builds against Swift 3.1? The Swift 4 compiler will be able to handle that:

Our goal is to allow app developers to combine a mix of Swift modules (e.g., SwiftPM packages), where each module is known to compile with a specific version of the language (module A works with Swift 3, module B works with Swift 3.1, etc.), then combine those modules into a single binary.

This is great news for developers, but only strengthens my argument that Swift needs a mechanism for SDK-conditional compilation. At this point, a developer who wishes to maintain source code that compiles against, say, iOS 9 and iOS 10, must conditionalize on the version of Swift:

#if swift(>=2.3)
	// iOS 10 only code
#else
	// iOS 9 friendly code
#endif

When and if Ted Kremenek’s promise of a multiversioned Swift compiler comes to pass, it will presumably mean multiple versions of Swift can compile against the same SDK, so this fragile workaround will no longer … work.

Update: It occurs to me, multiple versions of Swift already do build against the same SDK. Currently we have Swift 2.3 and Swift 3 building against Apple’s latest beta SDKs. It’s the “>=” in the workaround that guarantees a suitable SDK match for now.

App Sandbox Control Tool

I wrote only yesterday about how troubling I find the opaqueness of Apple’s App Sandbox.

Well, don’t I feel ignorant today.

% man asctl

NAME
     asctl -- App Sandbox Control Tool

SYNOPSIS
     asctl [-p] [-l] command [arguments]

DESCRIPTION
     asctl is a facility for manipulating the filesystem container for an applications using App Sandbox.  A container is a per-application filesytem hierarchy rooted in ~/Library/Containers.

This tool appears to offer extensive insight into the sandbox’s understanding of containers. I wish I had discovered it earlier!

Sandbox Container Ownership

I have a knack for finding bugs and edge cases, and my experience adapting to the Mac sandboxing facility over the past few years has been no exception.

The latest issue is something of a conundrum: I’m managed to produce two versions of my app, one of which causes the sandbox container to be apparently unwritable to the other after running! Specifically, preferences are not saved and console messages indicate an attempt to write preferences outside the host app’s sandbox.

I suspect it has something to do with changes I’ve made in anticipation of a bundle identifier change. As with so many of my struggles with sandboxing, I’m trying to smooth out the process of migration from one sandbox container to another. To that end I have added some temporary entitlements for preferences and shared file access, as well as modifying the code signing designated requirement to cover both bundle identifiers.

Long story short: if I run app version 1, then run app version 2, then run app version 1, app version 1 is denied access to the container (which had previously been its own!).

These kinds of issues scare the bejeezus out of me because I really fret my users running into data migration problems after I ship an update, and because the relative opacity of the sandboxing system makes a lot of issues very hard to debug.

I suspect there is some association made between a sandbox container and the owning app’s designated requirement, and that perhaps by changing it I’ve yielded ownership to the later version of the app. The Info.plist file inside a sandbox container has various keys such as “Identity” and “SandboxProfileData” which seem likely to pertain to this issue.

Apple supplies an App Sandbox in Depth which alludes to how ownership is determined, but alas does not go quite as deep as I’d like. Has anybody dived deeply enough into the sandbox to understand this issue well?

Update: I probably should have scratched more than the surface of the Info.plist before posting. There are other interesting keyed values in there such as SandboxProfileDataValidationInfo that includes keyed values such as full paths of various apps that share ownership (?) in the container. In summary: I guess I’m curious if anybody has dealt with issues like the one I’m seeing as has debugging tips to share.