More Notes on Vesper

This is the first time I’ve ever shut down an app. In the past I’ve sold my apps (MarsEdit, TapLynx, Glassboard, NetNewsWire) — and two of those are still going. (I’m writing this post — like all my posts — in MarsEdit.)

* * *

We never debated about providing an Export feature — not only was it the obvious right thing to do, it was a feature we’d planned to do regardless.

Initially I thought we’d do it as a web app. You’d kick off an export, then the web app would create a zip file and send you email later so you could download it.

We didn’t do it this way because it sounded like a real pain to write, and, more importantly, it didn’t do anything for people who didn’t use syncing.

The iOS document provider feature — which was introduced after Vesper shipped (it was originally an iOS 6 app) — was just what we needed. It meant we could write the notes and pictures as files in a folder, and then a document provider could upload those files to iCloud Drive, Dropbox, or wherever.

Perfect. It works whether you’re syncing or not — it has nothing to do with syncing.

And it will continue to work even after sync shuts down. It will continue to work as long as you have the app on your device.

* * *

We decided to make it so that new users can’t sign up for syncing, since it’s going away. And, since a new user can’t sync, we can’t really ask them to pay for the app, either — so we made it free.

Consider the alternative: we allow new sync users, and we continue to charge for the app. Some people would buy it the same day we shut down syncing. That’s not good.

Since it’s free, it will probably get more downloads in the next few weeks than it’s had in its entire life.

* * *

Some people have asked that we make it open source. The request is getting serious consideration, but I can’t make any promises.

The code is all Objective-C. It’s an iOS 6 app with just enough changes to keep it working on iOS 7 and beyond. It knows nothing about size classes, presentation controllers, and so on. Doesn’t even use auto layout. It’s not an example of how you’d write an app these days.

* * *

Belief inside Q Branch: if we had started with a Mac app rather than an iOS app, Vesper would have been much more successful. That wasn’t clear at the time we started, though (Dec. 2012).

* * *

This is the last app on the App Store where I wrote all (or almost all) of the code. Odds are excellent that there will never be another app written largely by me on any app store.

(Yes, my day-job-apps are on the app stores, but they’re written by a team.)

I’m working on new stuff from Ranchero Software. I had planned two apps, but I think it’s going to be just one, just because two takes too much time. So I picked the one I’m more passionate about.

It’s a Mac app, because I’m a Mac developer at heart, and it won’t be on the Mac App Store because I prefer the freedom of shipping instantly, without any large corporation’s bureaucracy slowing things down and holding veto power.

And then that will be my app. The thing I work on for the next 10 or so years, until I retire. That’s the plan. (To be clear, though, I don’t plan to leave my day job, which I love.)

When will it ship? I don’t have a date. I don’t know.

Last Vesper Update, Sync Shutting Down

We at Q Branch just released the final version of Vesper. It does one crucial thing: it allows you to export your notes and pictures. See the new Export section in the sidebar.

Sync will be turned off Aug. 30 at 8pm Pacific. We’ll destroy all the data, and neither we nor anyone else will be able to recover it.

The app will be removed from the App Store on Sep. 15. Until then, starting now, it’s free — since you can’t create new sync accounts, and it wouldn’t be fair to charge new users if they can’t sync.

I loved working on Vesper. It was one of the great software-making experiences of my life. We’d get on a roll and it was wonderful.

And now it hurts to turn it off, but it’s time.

To everyone who used the app: thank you so much.

Radical Infantile Terrorism

We can’t just keep letting babies into the country. We can’t, or we won’t have a country. Won’t have a country. We have to get smart, people.

No country in history has ever been ripped off like this. We’re going to build a giant condom and make them pay! A giant, beautiful condom — oh, so beautiful — and so big.

That baby had no right to stand there and viciously attack me. Even CNN — who won’t interview me, which is fine, which is fine, believe me — well it’s disgraceful — even CNN, which I guarantee you will be out of business in three years because they won’t interview me — fine — says it was vicious. So, so vicious. Can’t I respond?

This is what’s wrong with our country — which, by the way, we won’t have anymore. People who’ve seen the plans for the condom — wonderful people, so wonderful, people who support Trump, who by the way is going to win big in November — say it’s beautiful. They say they’ve never seen anything like it in the history of the world. Believe me.

I’m a builder, so I think I know a few things about building things, okay? It will be big, and beautiful, and we’ll have a country again. We’ll make America great again.

Oh, I miss the old days. Remember the old days? We used to know what to do with babies. But now you can’t even say it, right? You can’t even talk that way anymore. We’re so politically correct.

I was always against the babies. Hillary Clinton had a baby! Do you know where babies come from? Don’t ask. It’s disgusting. Disgusting.

Where is that baby now? She won’t tell you. Crooked Hillary is hiding that baby. I’m not saying, I’m just saying, is she hiding something? You tell me.

In the old days we used to know what to do with babies that won’t even speak English, which by the law is the law of our country.

[Trump points to man in crowd.] Sir? That’s right sir — we’d carry them out. Carry them out! [Crowd chants “carry them out!”]

It’s sad, it’s so sad. We have to get smart, and tough, and babies aren’t tough. I know tough guys, and babies aren’t tough.

After we build that giant, beautiful condom, and make them pay for it — which, by the way, will be so easy, so easy — we’ll build a big, beautiful boob and make them pay for that too. So beautiful.

[Crowd chants “giant boob!”]

In Ryan’s Shoes

I try to imagine what I would do were I Paul Ryan. I think and hope that I would un-endorse Trump. It’s obvious by now that a Trump presidency would be a calamity.

The cost of un-endorsing Trump might be the end of Ryan’s political career. He’d make more money in the private sector, sure, and he could probably still work on policy, but as a private citizen. Plenty of people do.

He’d lose an awful lot of power, though. I don’t think he’s in it for power alone — I think he’s in it for the power to turn his policies into law. Which is totally fine. Which is how it should be. (It’s not true of every politician, I grant, but I believe it’s true for Ryan.)

That’s a big thing to lose. He believes his policies will help the American people, and that the policies of Democrats (and some other Republicans) will hurt. I may disagree, but I respect it.

But here’s the thing: Trump is already hurting our country. Continuing to endorse him — no matter how tepidly, no matter how leavened with criticism — makes Ryan complicit in this harm.

Americans need to believe that the leaders of both parties are patriots first and party loyalists second. I’m sure Ryan knows this.

His un-endorsement may not hurt Trump. It may even help him. But there are times to think tactically and times — like now — to just do the right thing, the selfless thing, and be a hero.

Sound Off Round 4: Live-Captioning Open Source & Feelings

From Sound Off:

Open Source & Feelings has a thorough and unambiguous code of conduct, one of the best diversity statements we’ve seen from a conference, and an about page with everything from venue accessibility, to public transit, to tips about keeping safe while traveling to and from the conference. Everything about Open Source & Feelings communicates thoughtfulness, deliberateness, and listening to feedback.

Donate now to help out this good cause.

Sound Off board member Ashley Nelson-Hornstein explains how live-captioning is useful for all physically-present attendees, not just for people you’d expect to need the help.

It’s also worth remembering that accessibility issues aren’t just something for a small percentage of the population.

Everybody has — or will have, if they live long enough — something they need help with. I have increasing trouble hearing, and live-captioning would certainly help me, and maybe you too.

Straight up: help make sure everyone can participate.

PS The conference will be here in Seattle, at Seattle Central College. I was on the college newspaper there, in moons past.

My Rules for Mutable Foundation Collection Objects

I have some simple rules that I always follow when dealing with mutable Foundation collection objects (plus mutable strings) in my Objective-C code.


I often use a mutable collection object when constructing a thing — array, dictionary, set, or string — and then pass it somewhere else.

Once it’s passed, ownership is relinquished. The construction code never continues to hold a reference to the thing it made.

Wherever that thing goes it’s treated as immutable (whether or not it really is).

No mutable collection objects in APIs

In my .h files, under no circumstances are properties or parameters allowed to be mutable collection objects.

(Or, well, it’s extremely rare. There could be a utility API that takes a mutable thing, but that API does some kind of work that doesn’t retain that collection, so it can’t mutate it later on.)

Mutable collection objects are internal to a .m file

An object may use mutable collection objects internally, but those aren’t allowed to escape the .m file they live in. There’s no chance, then, that one of these could be mutated without its owner knowing about it.

* * *

By following these rules — which, after all these years, I do without even having to think — I never run into an issue where I’ve passed a mutable array (or whatever) to another object, then held on that array and mutated it. It just can’t happen.

But, really, whatever — these days I write Swift code instead.

Copy vs. Strong NSArray Properties

At work this morning I added a property to an Objective-C object that looked something like this:

@property (nonatomic, strong) NSArray *someArray;

And then it was suggested to me that copy would be better than strong in this case.

I have nothing against copy — but with an immutable array, is that really necessary? The array can’t change, so why copy it?

Well… that’s not strictly true. A caller could use an NSMutableArray — which would be perfectly valid — but then hold on that array and mutate it later on, which would be dumb.

So I ask: who would write code like that?

It’s not a class of mistake that I personally make. (I’ve internalized this so completely from years of writing Objective-C. I do make other classes of mistakes, of course.)

And then I think “Who would write code like that?” is the wrong question. The real question is, “Why wouldn’t I write code that minimizes the effect of a possible mistake?”

(Or even not a mistake. It could be entirely legitimate that the caller has a mutable array that it holds on to and mutates later on.)

* * *

This makes me wonder about the difference between code I write for myself and code I write as part of a team. Since I know that I wouldn’t make this particular mistake, I can safely use strong instead of copy in my own code.

But, really — sharp right turn here; buckle up! — doesn’t it make me wish everything was already in Swift, so we’d have the safer behavior automatically?

Yes. Yes it does.

My personal projects are mostly in Swift — converted to Swift 3 already — but, for obvious reasons, at work we often write new code in Swift but still have a large Objective-C codebase.

What I don’t need in life — because it adds complexity, and I don’t have time for that — is three separate coding styles: Swift, my Objective-C, and work Objective-C.

The only one I can get rid of is “my Objective-C.”


So Merlin Says to Me…

I saw Merlin Mann before the Talk Show last Tuesday, and he thanked me for letting him play in my internet treehouse.

I completely misunderstood. He was talking about a small and specific thing (I realized later) — while I thought, at the time, he was doing a thing Merlin would do, which is to thank a software developer for helping to build up the world of blogs and podcasts where Merlin does, indeed, get to play (and be awesome at it).

(What you don’t know about Merlin — or maybe you do — is that he’s one of the best at liking people. It’s creativity and Jonathan-Winters-meets-James-Joyce — but mainly effort and empathy. So he would say what I thought he said.)

Anyway, my answer didn’t make any sense, surely, when I said, “We built it all for you.”

(Because he’s thinking of this one small thing and I’m thinking of the web.)

But it struck me that, as a reply to what I thought he said, it was absolutely correct. We — and I mean me and many thousands of people like me — worked hard to make the decentralized web, the web of blogs and podcasts, a place where all the Merlins would thrive.

Blogs are the Pad Thai, the rib-eye steak, the bowls of spaghetti of the web. Podcasts are the mashed potatoes, the tacos, and the hummous. You could get by for a little while with Skittles (Twitter) and peanut butter cups (Facebook) — but eventually you need something more filling, something you can sit down with and take your time.

* * *

I realize that decentralized-web fanatics are often looked at as if we’re the Libertarians of the web. Or the crazy-conspiracy-theorist-uncles. Or as if we’re stuck, sadly, in a rosy past and we won’t move on.

Think whatever you will. But wonder if, if all this goes away, could there be any more Merlins.

A Meaningful WWDC

Last year I was all set to go to WWDC — or, rather, to everything but the actual conference — with plane tickets and hotel rooms booked. I was going to speak at AltConf and play with the Breakpoints and hang out with old friends and make new ones.

But, right before, my father-in-law died of complications from the treatment of a year-long illness. We thought he would get better, and then he didn’t. (This is what prompted my In the Room post of last October, even though that talked more about my grandfather.)

I was very close to my father-in-law. He lived nearby, in the suburbs, and he was a big part of my life for 25 years.

Naturally I canceled my trip.

When he died, it was already clear that my mother-in-law was also sick — for entirely different reasons, and entirely coincidentally. So we went from one to the other without a break. I was as close to her as I was to him, and she died this past January.

Both were too young, and both had been marvelously healthy and energetic — and I still keep forgetting that they’re not just traveling or something and I’ll see them soon, and then I remember.

* * *

So this WWDC represents something for me. I missed it last year, but this year I can go and have fun — and that’s a real thing.

I’ll speak at AltConf, play with the Breakpoints, and hang out with old friends and make new ones. Same as last year would have been, but this year it’s different. Knowing that I missed it, but that I get to go this year, is helping me in a way it’s never had to help me before. It means something. And I thank everyone in advance just for literally being in SF at the same time as me next week.

Seeking Clarification

I have a side project, a Mac app, that I could also do as an iOS app. I have no plans to do so — but the news about subscriptions and free trials makes me reconsider.

It might be sustainable with this new model.

But here’s the thing: the app is a stand-alone thing. I’m not running a backend web service for it. Would it be okay to use the subscription-based pricing? Here’s what Apple says:

Starting this fall, apps in all categories on the App Store will be eligible to offer in-app purchases for auto-renewable subscriptions to services or content. Users enjoy the reliability that comes with subscribing to a service that they love, and the experience must provide ongoing value worth the recurring payment for an auto-renewable subscription to make sense. Although all categories of apps will be eligible, this business model is not appropriate for every app.

What does “not appropriate” mean? Does that mean rejection? Or is that just a warning that it’s maybe not the best fit, but it’s okay to try it anyway?


Ads via The Deck