I start my new job as a developer at the Omni Group today. You already know them and their wonderful products, and I’ve expressed my admiration for them here on my blog many times.

But, before I talk about how I’m excited for this new job, I’ll reassure Vesper users: Vesper will continue, and I will continue as its developer.

It’s in great shape, actually — we’ve done the heavy lifting of designing and writing an iOS app, writing client sync code (that’s shared between iOS and Mac apps), and writing and deploying the sync server. And we have good work in the pipeline.

Plenty of work — lots of work — remains for Vesper, but we’re over the biggest hurdles, which is great. We’ll keep at it.

I love that I get to work on both Vesper and on Omni apps. Omni is one of the great Cocoa development companies, and they’ve grown slowly and steadily over many years. They write lovable productivity apps — not just great iOS apps but also great Mac apps. They’re generous to and respectful of their users, employees, and the local development community. Their values and ambitions align perfectly with mine.

And for me it’s a chance to do something I’ve never done: to work on a large team with lots of products and lots of users. To be part of something not just a little bigger than me but a lot bigger than me.

I could have shopped around and talked to other companies (including Apple, I suppose) — but I didn’t. I could have considered contract programming as a way to bring in extra money, but I know myself well enough to know I’d hate it.

Instead, I wanted to work at Omni. And now I am.

Skillet Diner User Interface Lessons

I wrote that thing about the Skillet Diner because I was insulted and angry about it the next day. (I’m not an angry person in general: this feeling is rare for me.)

But there are also some lessons to learn for software developers.

The first obvious one is to treat people with respect from the second they open the door — or from the second they launch your app. The first-time, first-run experience is massively important.

There’s also a second, less-obvious lesson.

The most charitable explanation I have is this: I said I’d be willing to sit at the counter, but I didn’t specify that I’d be willing to sit outside or at the bar. I figured I didn’t actually have to figure out all the different sections and specify each one to the host.

But the host knows the place: he thinks of the restaurant in terms of outside, dining room, counter, and bar. Whereas I, new to the place, think mainly of just sitting down somewhere. I’m no expert in that restaurant, having just arrived, but I was observant enough to notice some counters with empty seats together, so I did say we wouldn’t mind sitting there.

If my theory is correct, then the host expected me to treat him like a computer. He expected me to specify which sections would be acceptable, and he expected me to know all of them and present a list of acceptable choices.

But picture us: we were hungry, brand-new to the place, and we had enough experience to know that every other host in every other restaurant ever has managed to understand our wishes just fine — and has asked questions when needed, which is totally fine.

In other words, this particular UI was designed to be technically true but was entirely lacking in understanding of the (potential) customer.

Skillet Diner (Ballard) Considered Harmful

Sheila and I had been meaning for some time to try the Skillet Diner in Ballard. We went last night around 7 pm.

When we got there there were a couple parties standing by the front desk. The host seated them.

Then we told him that there were two people, and answered no when he asked if we had reservations.

He told us it would be about 20 minutes. I asked if we could just sit at the counter — there’s a long counter with a bar at one end, and there were clearly two seats together in a couple spots — and he said no, but he’d add a note saying we’d be willing to sit at the counter.

So we stood and waited. I counted two two-tops open outside and two in the dining room. As we waited another table paid and left, which made it three two-tops open in the dining room.

As we waited nobody was seated in those tables or at the empty counter spaces.

About five minutes in to this, another couple walks in. They don’t have reservations either. The host explains that there’s a wait. He goes somewhere else for a minute. They flag a waitress, and ask her. She explains that the restaurant is very busy. The host returns, and they ask if the bar is open seating.

The host looks bugged (he’d look bugged the whole time we’d been there) — but then he grabs a couple menus and seats them at the counter in the bar.

Ahead of us.

We walk out.

* * *

As we walk out there are still empty tables-for-two outside and in the dining room, and there was space at the counter for two.

And I had figured by saying that we’d be willing to sit at the counter, that would have been enough to say that we’d even sit at the bar. Or wherever.

The bar appears as just an extension of the counter, where it turns 90 degrees. Someone new to the place, like me, might not even realize that they’re not the same thing — but it seems like I shouldn’t have to specify every single section where I’d be willing to sit. If you’ve got space, just ask me, right?

Now, it’s possible he was about to seat us at a table after seating that couple. But he should have done so first, instead of insulting us by seating another couple ahead of us. Or he could have at least told us and then come back for us.

But he didn’t.

In other words: the service at Skillet Diner in Ballard was so bad that we didn’t even get as far as sitting down. This was a first for me.

We won’t give them a second chance.

* * *

Update 11:50 am: On Twitter, Skillet Diner replies:

there is no excuse for terrible service and that host's actions will be corrected.

I’m still not giving them a second chance. But I’m glad they recognize that this was terrible service.

UISplitViewController Question

Picture an app with three levels of hierarchy. Let’s pretend it’s an RSS reader (it’s not).

Feeds > Timeline > Article

The modern way to make this work for iPad and iPhone is to use a UISplitViewController.

  • Left: navigation controller with Feeds and Timeline.

  • Right: navigation controller with Article.

Launch in portrait on iPhone 6 Plus. The Feeds view controller takes up the full screen. Good.

Tap a feed. The Timeline appears full screen. Good.

Now rotate — the split view now appears. On the left is Feeds; on the right is Timeline. Not good.

And, if I tap a feed, a second Timeline appears in the left, which means two timelines are showing.

I have my project set up almost exactly like the Xcode template for a split view controller app. The difference is really just that the master has Feeds and Timeline view controllers, instead of just a single Feeds view controller.

How do I get the Timeline to move to the master (leftmost) side when going from compact to regular horizontal size class?

My question is much like this unanswered question on Stack Overflow. A difference is that I’m using a selection segue instead of pushing a view controller. (I’m not sure the difference matters. At any rate, we have the same issue.)

Update 2:30 pm: I ran into serious trouble when nothing I tried seemed to do anything. Clean builds didn’t help. It wasn’t till I noticed that breakpoints in delegate methods weren’t getting hit — and I was about to file a Radar — that I realized I probably needed to delete the DerivedData folder. So I did, and things started working. So: consider that a reminder.

I’ve published a gist that shows what I’ve got so far. I’m sure it’s not the final version of the code — splitViewController:​collapseSecondary​ViewController:​ontoPrimary​ViewController: will need more logic — but it solves the problem so far.

Thanks to Tim Ekl and Saniul Ahmed for help via Twitter.

And — bonus — @FriedLemur has the tip of the day (regarding DerivedData):

Option key turns Clean into Clean Build Folder, pretty much rm -rf

That’s so much better than me trying to remember where the DerivedData folder actually is.

Reeder and Unread

I asked on Twitter about which iPhone RSS reader I should use.

I got lots of responses. Reeder was most often mentioned; Unread was second-most.

So I set up both with my syncing system (Feedbin) and gave them each a shot.

They’re good apps. As a user there’s a lot to like, and as a developer there’s a lot to admire. I can’t say that one is better than the other, or that one deserves more popularity than the other.

But, in the end, choosing was for me almost a no-brainer: I went with Unread because Reeder’s low-contrast UI (light gray on even-lighter-gray) was too difficult for me to read. Which is totally subjective, of course, and doesn’t actually say much about either app. But that’s my choice.

How To Steal

Fellow Q Dave Wiskus talks about copying in the latest Better Elevation video.

David’s Critique of Swift

In my My Swift Dilemma, David Owens compares Swift to Objective-C and to a hypothetical Objective-C 3.0. And looks at the costs of optionals and generics.

David is disappointed, and not sure whether or not to be optimistic. I understand that. And while I’ve reserved judgment on a bunch of his points (not least because I have much less experience than he does), they’re well worth understanding — on the grounds that we should understand our tools and their decisions and trade-offs.

Craig on In-App Browsers

Craig Hockenberry, In-App Browsers Considered Harmful:

There is always a tradeoff between usability and security. Doing the OAuth token exchange with an in-app browser makes it easier for a user to login, but they’ll have no idea if their personal information was captured. That is why Twitterrific did its token exchange in Safari, even though it’s a more complex user interaction and a more difficult technical implementation. As a user, I know that there’s no way for my login to be compromised when the transaction involves Safari.

Glen on Swift Performance

Glen Yi writes a brute force solution to Cardano Triplets and notes Swift and Objective-C performance differences.

CocoaConf at Yosemite

This spring CocoaConf is going to Yosemite. The actual place.

I’ll be speaking. So will fellow Q Dave Wiskus. The speakers list is fantastic — one of the very best I’ve ever seen.

And it’s all within sight of Yosemite Falls.

[Sponsor] Apply to NYC Startups in 60 Seconds is a curated, two-sided marketplace for technical talent. We make it fast and painless for engineers, designers, product managers, and data scientists to get their résumés directly in front of founders and hiring managers at venture-backed startups in New York City. No more recruiters, and no need to fill out separate job applications.


Here’s why our curated marketplace is the best way to get a job at a startup in New York:

  • Free for candidates.
  • Short application process: 60 seconds or less.
  • No need to create an account or remember a password; we can do everything by email.
  • Closed network: no candidate info is public, so your job search is done in private.
  • No hand-holding or middlemen: connect directly with founders and managers.
  • Two-sided curation: only the best candidates AND startups are allowed in the network.
  • Startups loves us because we’re cheaper than recruiters : ).

Let help you land your next job.

Dave on Software Testing

Dave Winer, The lost art of software testing:

I think all developers go through the initial hatred of the tester, feeling unloved, and depressed because the labor of our love is so awfully buggy, broken and badly designed! Oh. But you eventually come to see that knowledge is power.

I’m not sure that the art is actually lost, though it’s certainly less common than it should be. Nick Arnott has tested most releases of Vesper, and he’s amazing. Best tester I’ve ever worked with. (I like to joke that he hates my guts and is trying to kill me — that’s just what it feels like sometimes when a tester is doing a great job.)

And there are companies such as Omni who have testing departments, and who are, by all accounts, similarly great.

Mark on College Board Testing

Mark Bernstein: What’s Wrong With Facts:

And the more the tests depend on facts, the more vulnerable they are to corruption. Worse, the potential for corruption is so obvious that there doesn’t really need to be any corruption at all before people generally believe that it’s hopelessly corrupt.

Vesper and New iPhones

Now that some people are getting their iPhone 6 and 6+ deliveries, they’re checking out their apps — and, if tweets are anything to go by, Vesper is one of the few apps ready for the larger screen sizes.

Here’s one from Josh Biggs:

God @vesperapp looks amazing on the #iPhone6

It’s a good day. I love days like this.

Bryan on Building Share Extensions

Bryan Irace writes What we learned building the Tumblr iOS share extension.

Sounds like extensions are very much at 1.0. Of course. My congratulations go to the team at Apple that shipped it — it’s huge. Big cool thing.

Josh on “Homeland”

Josh Marshall, “Homeland” And Other Un-American Words and Ideas:

But the ‘homeland defense’ concept was always closely tied to creating a missile shield over the United States. And when I poked around a little further to try to find the earliest uses of the phrase in this context the earliest ones all traced back to Reagan missile defense initiative in the 1980s.

I never heard it used as a word referring to our country until after September 11. And it’s made my stomach hurt ever since.

The word makes me feel as if I’ve fallen through to a parallel world, one where the simplistic things said about America in college freshman dorm rooms by the newly engagé are actually all true.

Nick on Privacy

My co-worker on Glassboard Nick Harris talks about privacy:

Apple’s decision to make it impossible to decrypt data on the device without the users password is the real reason they can say no to warrants. This was another idea we had tossed around. It would have been a paid feature where the board would be encrypted from end to end with only the chairperson having the keys. I had a plan for this and pushed it but didn’t win over the team on getting it built.

Privacy was a huge big deal with us with Glassboard. (And I brought those lessons with me to Vesper.)

With Glassboard we definitely wanted, as Nick pointed out, to do on-device encryption, so that the server would have no way of decrypting text. But we had to do so much so quickly that we couldn’t make the time. (And there were some technical issues — how could we do push notifications if the server can’t push the decrypted text? It’s possible Nick’s plan accounted for that; I don’t recall now.)

It seems as if the realization among regular users that privacy is critical has been glacially slow. But it appears to be picking up speed. (I sure hope that’s true.)

Charlie on Democracy

Charlie Stross, in 2013: Political failure modes and the beige dictatorship:

So the future isn’t a boot stamping on a human face, forever. It’s a person in a beige business outfit advocating beige policies that nobody wants (but nobody can quite articulate a coherent alternative to) with a false mandate obtained by performing rituals of representative democracy that offer as much actual choice as a Stalinist one-party state.

Facts and Thinking

I was reading about Texas and the AP History course — and the thing I was bugged about wasn’t Texas. (The article doesn’t provide enough information to form an opinion.)

Instead, I was bugged by this statement:

The controversy stems from the recent overhaul of the AP test, administered by the New Jersey-based College Board, that was meant to de-emphasize memorization.

Lots of people are nodding their heads. Why memorize things? Of what value is knowing a bunch of dates and the names of dead generals?

The point of school is to teach us how to think, after all.

But that always sounds to me like people arguing that you could learn the rules of English grammar without learning any of the actual words. The facts — and, especially, the stories — of the world are its words. That’s our vocabulary. That’s what we think with and about.

It’s not a matter of memorization to know that World War I came before the Roaring Twenties, and that the Great Depression came next, and that World War II followed. There should be no way a high school graduate could be unsure of the sequence of events, and they should be able to get the decades right, even if they don’t recall, for instance, the exact date of the stock market crash (October 24, 1929).

They ought to know that the Soviet Union was our ally in World War II and our enemy later. And they ought to know that Germany fought a two-front war, and that Germany’s army wasn’t the first to run into trouble in Russia, and why. And they ought to know enough to be able to speculate as to why Germany hadn’t learned from the past.

Knowing the stories isn’t memorization. Once you know the stories you know how one thing causes another, how things are related and reflected, and you can think about the present and the future. And you end up knowing pretty well when things happened — because you know how things fit together — even if you don’t recall every single precise date and the names of every player. (Who assassinated Franz Ferdinand? I had to look it up. Gavrilo Princip.)

To “de-emphasize memorization” sounds like a thing everybody can agree on — except that I suspect it really means “we’ve made it so you don’t have to know what actually happened, which makes it easier for you to do well on the test, which makes us look good.”

* * *

Darmok and Jalad at Tanagra. Temba, his arms wide.

Code-Signing Confusion

Daniel Jalkut documents recent issues regarding code-signing.

While WWDC 2014 was the best Christmas ever, and while the new iPhone models and the Apple Watch look very cool (I’ll be getting a 6+ and a watch), I still can’t help but worry.

What worries me these days is bugs.

Developers know what I’m talking about. To start listing them would seem like Apple-bashing, which isn’t my point.

Bugs make developers reluctant to adopt new things. A developer thinks: I’d love to do x, y, and z — but I think I’ll let everybody else go first.

I’ve said before recently that OS X 10.11 and iOS 9 could be about bug fixes and performance enhancements, and nothing else, and developers would be thrilled.