Archive for January 23, 2015

Friday, January 23, 2015

Let’s Build Swift Notifications

Mike Ash:

NSNotifications are both simple and powerful, which is why they show up so often in the frameworks. Specifically, they have a few distinct advantages:

  1. Loose coupling between notification senders and receivers.
  2. Support for multiple receivers for a single notification.
  3. Support for custom data on the notification using the userInfo property.

There are some disadvantages as well:

  1. Sending and registering for notifications involves interacting with a singleton instance with no clear relationship to your classes.
  2. It’s not always clear what notifications are available for a particular class.
  3. For notifications which use userInfo, it’s not always clear what keys are available in the dictionary.
  4. userInfo keys are dynamically typed and require cooperation between the sender and receiver that can’t be expressed in the language, and messy boxing/unboxing for non-object types.
  5. Removing a notification registration requires an explicit removal call.
  6. It’s difficult to inspect which objects are registered for any given notification, which can make it hard to debug.

My goal in reimagining notifications in Swift is to remedy these problems.

He runs into an interesting case where casting is necessary to satisfy Swift’s type system. I didn’t expect this, and it’s instructive to think about what is going on here. Also note how it transparently handles observer functions with different numbers of parameters.

The Design Philosophy of the DARPA Internet Protocols

Adrian Colyer:

Understanding the underlying principles behind something can turn what might on the surface seem to be simply a collection of facts into a chain of causes and consequences that makes it much easier to see how those parts fit together. Clark provides us with some of those insights for the design of the Internet Protocols, working from the goals towards the implementation consequences.

[…]

The only error the communicating parties should ever see is the case of total partition. If the application(s) on either end of the connection are not required to resolve any other failures, then the state necessary for recovery must be held in the lower layers – but where? One option is to put it in the intermediate nodes in the network, and of course to protect it from loss it must be replicated. I think the knee-jerk reaction of many system designers today might be to distribute the state in some such manner, maybe using a gossip-protocol. But the original designers of the internet had a insight which enabled a much simpler solution, and they called it ‘fate sharing.’

Modern Login Items

Cory Bohon:

Login Items have previously been a way for OS X apps to provide this service to users, but is not compatible with the sandbox requirements of the Mac App Store. Fortunately, there is a much more modern way to handle this, and I’ll walk you through setting it up in your own projects.

[…]

In order to launch our application at login, we’ll create a separate application that is included in the signed main application bundle. The sole purpose and function of this separate application will be to launch our main application at login, if it is not already launched.

[…]

This code uses the ServiceManagement framework’s function called SMLoginItemSetEnabled. The first parameter in this method is a CFString containing the bundle identifier of your Helper application. The second parameter is a BOOL indicating whether the Helper should launch at login or not.

The helper app is required because SMLoginItemSetEnabled() only works with paths inside of the app’s Contents/Library/LoginItems folder.

Tim Schröder:

Consider further that you have successfully implemented such a feature and shipped your application, but now want to update your application to not run in a sandbox anymore. Sounds like a strange turn of things, but this may happen, e.g., if you designed an application to be distributed in the Mac App Store (and shipped it), but now there are compelling reasons to remove the sandbox functionality and to switch to direct distribution outside the Mac App Store.

It is then sensible to provide launch at login functionality no longer via SMLoginItemSetEnabled (and a helper app), but via a shared file list as provided by the Launch Services Framework, which has the distinctive advantage that your application will be visibly marked as launching at login in the System Preferences and that the user can edit this behaviour from the System Preferences (which is not the case with the launch at login functionality providing via SMLoginItemSetEnabled).

Update (2015-01-27): Stephane Sudre says that you may need to call LSRegisterURL() before SMLoginItemSetEnabled().

Dallas Brown reminds that you need to create a separate App ID in the Developer Portal for the helper application and that it should not have the same entitlements as your main application.

How iOS Has Changed

Khoi Vinh:

I don’t link to a lot of infographics here but I like this one, and I’ve always been fascinated by the incremental, barely noticed way some interfaces can change, even when we look at them all day long. This extensive graphic from 7dayshop.com presents a pretty comprehensive overview of how iOS has evolved.

Organ Banked

In response to my roundup about Apple’s software quality, a former Apple CoreOS person writes:

A lot of us felt we were being “organ banked”, and late in Lion, on the iDevice release cycle, we were pulled away from desktop work in order to do iPhone and iPad work, which was on a 3 month release cycle, instead of alternating desktop with non-desktop, which we had formerly done on a 6 months on/6 months off cycle (release one in fall/release the other in the spring).

The desktop vastly suffered because of this, and we felt that Lion and later were more or less “phone it in” releases for the desktop.

The comments from Apple insiders underscore that there are many factors that affect software quality. It is not simply a matter of dropping the yearly schedule or of deciding to do “another Snow Leopard.” The development schedule and cycles matter. It also matters who the engineers and managers are, how they are treated, whether they are shuffled between projects, etc.

There was a lot of resentment because when the initial iPhone came out, almost no one on the second floor of IL2 was allowed to look at the internal SDKs; even after the SDKs were finally released (a lot of Apple engineers by that point were on the “iPhone Dev Team”, and compiling their own apps for jailbroken phones, providing compiler and assembler fixed, and so on).

Then we had to wait 6 months after they started external classes before we were allowed on the platform, or in the classes. We all suspected that that was because there was incredible demand for iPhone programmers, and we’d get hired away from working on boring old crap like Finder and Mail and AddressBook, because Apple couldn’t hire people willing to work on boring crap any more.

This reminds me of three things:

Update (2019-06-03): Dave DeLong:

I’ve been hearing of multiple @apple engineers who are being forced to leave the company because of the “no remote” policies. They have DECADES of combined experience who love the company and want to stay.

It’s pretty upsetting to see Apple hemorrhage talent like this