Tyler on Mac Apps

Tyler Hall:

In 2007, I priced the app at $7. Over time I raised the price to $9, $12, $14, $19, $24, $29, $34, $39, and, now, $49. With each price increase my total sales and revenue have only gone up. And, as an extra bonus, the quality of my customers has increased as well. I never received as many angry emails from customers as I did when the app was priced cheaply.

(Via Jared Sinclair.)

Lots of Apps

Benjamin Mayo comments on Jared Sinclair writing about Unread’s revenue:

In my opinion, you make money on the App Store by selling small things — its very nature is a bitesize marketplace. This is how you maximise your effective hourly wage. This doesn’t mean you have to turn around crap. You can still output quality pieces of software.

I think he’s right that this is a workable strategy.

The obvious downside, though, is that you don’t get apps like Overcast, Unread, Tweetbot, and my own app Vesper (and plenty of others) if everyone sticks to this strategy.

We want those kinds of apps, not just the bite-sized apps.

More on iOS Indies

When I asked who all the iOS indies are, I got a bunch of good responses. By iOS indies, I meant:

• People making all (or almost all) of their money from iOS.

• And who are making that money from publishing their own apps, not via contracting or a paycheck.

There are plenty of people with both iOS and Mac apps, and plenty of indies who make much of their money from contracting. But I was curious about the pure iOS indies, since I thought it would tell me something about the ability of indies to make money on the iOS App Store.

(Games, by the way, are another country. I should be explicit about not thinking about games, since I don’t know anything about the market or what it takes to make an iOS game. It’s possible that game-writing is a wonderland of fun and money. I don’t know.)

There aren’t many pure iOS indies. I’m sure I’m missing some, but the names that kept coming up were David Barnard (Launch Center Pro), Jared Sinclair (Unread), David Smith (Feed Wrangler and others), Charles Perry (Action Lists and Benjamin), and Greg Pierce (Drafts and others).

(Congratulations to these folks! And to the others whose names I missed. You’re living the dream, and that’s cool.)

I think my point still stands — pure iOS indies are fairly rare. I can easily come up with a bigger list of pure Mac indies, even though iOS developers in general outnumber Mac developers.

If you want to write your own iOS apps, it appears that either you accept the likelihood of a pretty low income or you have a day job, write Mac apps, or do contracting (or some combination).

I think this is too bad. It seems like the iOS market is so huge that it should be able to support lots of iOS-only indies.

But with how prices have fallen — how people are now accustomed to not paying anything until they’re hopelessly addicted and need the $4.99 packet of imaginary things that will get them to the next level — I can’t recommend to anybody that they quit their job to just write their own iOS apps.

(Unless those apps are games. Maybe games are fine. I have no idea.)

There’s a downside to this beyond just the vague feeling that it’s a shame that iOS developers have to supplement their incomes — it’s that any rational developer aware of the economics will not be able to make as big an investment in iOS apps as they would if they could expect their effort would be rewarded.

Consumers win in terms of quantity of choices and low prices, but not in terms of quality.

[Sponsor] Creating static blogs made easy!

Statiked is a blog client for your static blog hosted on Github and S3.

The online world has seen a new revolution lately: static blogs. However, as the current tools that are available to host and manage a static blog stand, it is only accessible to a minority of bloggers out there. Even seasoned programmers who use Github daily often find it difficult to write and publish a blog post. Statiked takes out all the pain points in publishing to a static blog.

Statiked allows you to compose your article in your favorite text editor. Currently it supports, TextMate, TextEdit, Sublime Text 2, and BBEdit. You write all your articles in plain text using Markdown. Statiked generates the corresponding HTML before publishing it to the host.

If you are like us and don’t want to leave the comforts of a blog editor which you are used to, Statiked provides an XML-RPC server built in. Point your favorite blog editor to the URL provided by Statiked, and blog as if you are publishing to any hosted blog.

There are three beautifully designed responsive themes packaged within Statiked. With a bit of hacking you can port your Jekyll or Wordpress theme to use with Statiked too. Porting a theme is easy as Statiked supports the famous Liquid template system.

Statiked is a useful tool for any blogger who wishes to host a static blog. There are no bash commands to remember. No scripts to deal with. You do everything through a simple and intuitive UI. Publishing to a static blog is as easy as writing an email. Use your time to focus on writing. Write Just Right!

You can get Statiked from our website. Follow us on Twitter at @statikedapp.

I Was Wrong — You Totally Can Use CloudKit for Identity

See Session 208, Introducing CloudKit.

Your app gets a stable but random user identifier that does not include any user information. Two different applications get different identifiers, but the same application run by the same user on different devices get the same identifier, as you’d expect.

From the session, at 40:36:

And lastly, this is an independent API. This is a section of the CloudKit framework. You can use this in collaboration with the database API, or you can use this completely separately. We’ve given you enough support that, if you wanted to, you could implement a login-via-iCloud flow in your application using the CloudKit framework.

Unread’s Numbers

Jared Sinclair writes about Unread sales.

(I bought Unread about a month ago, by the way. It’s a very good app, and I recommend it.)

Contrast Jared’s numbers with NetNewsWire’s numbers in 2004 and 2005 (the last time I paid attention to its sales) — NetNewsWire made 5 figures every month, month after month.

This was before the App Store. It was a Mac app in a small market. (Far smaller than iOS, and much smaller than the Mac market is now.)

Setting Expectations About CloudKit

Macworld: Why you should care about CloudKit:

The big difference is that the information stored in it can be made available to multiple users, allowing them to collaborate and share information through the cloud—something that iCloud “Classic” was unable to do…

Don't let the term “public” put you off, though—CloudKit doesn't force all the shared data in a big bucket that is automatically visible to everyone who installs a particular app. Instead, developers will be able to protect the information as they see fit, allowing, for example, users from a particular group or organization only to have access to specific content…

It’s not hard to see that CloudKit greatly simplifies the creation of apps that revolve around multi-user collaboration. Previously, creating a group chat app like Glassboard, or a team-based task management software like Wunderlist, would have required a significant amount of work.

I don’t see how this is true. While it’s technically possible to use the public data for group collaboration, it’s only the code in the client app that enforces this. CloudKit has no notion of groups.

It would be irresponsible to use the public data for private group collaboration.

Neither of the two apps mentioned as example — Glassboard and Wunderlist — should use CloudKit.

And, since CloudKit is iOS and Mac only, and those two apps exist on other platforms, they couldn’t use CloudKit even if it did have private group data.

CloudKit is cool, and I think lots of developers and users will benefit from it. But it’s important to set expectations properly, and not suggest that it’s useful in cases where it’s not.

(Hopefully that will change. I’d love for CloudKit to understand groups.)

Also, there’s this:

Finally, CloudKit allows third-pa>rty apps to piggyback their authentication mechanism on Apple ID, thus making it easy to tell each user apart in a unique way without having to write and maintain a login system—and without forcing users to remember yet another password.

I don’t see how that’s true, either. If CloudKit gives you a user-specific token that identifies a user, sending that token to your own server — without an additional authentication system — isn’t secure. An attacker could submit random tokens until they found somebody’s data.

Update a few minutes later:

Kyle Sluder asks on Twitter:

If authentication is user id + nonce, how is it not secure?

Good question. Perhaps this could be made to be secure.

So I’ll make another point: in the absence of Apple saying, “Yes, you can use it this way,” I wouldn’t. It feels like a misuse of the system, and something Apple would recommend against. Putting your app in that position is not a good idea, especially given that it’s the kind of practice Apple could choose to disallow.

If I’m wrong — if Apple is indeed offering just the authentication part of CloudKit as a service to developers — then I’d like to see where this is spelled-out.

Update 9:45 am:

Well, Tom Harrington tells me that Apple has indeed said you can use CloudKit authentication as a service.

It was specifically mentioned in one of the CloudKit WWDC sessions. Log in with iCloud instead of Facebook or whatever.

That’s really cool. I’ll go back to the session and double-check, of course, but I don’t doubt Tom. (He knows this stuff.)

Update 10:06 am:

See I Was Wrong — You Totally Can Use CloudKit for Identity.

Who at the Table is an Indie iOS Developer?

Until last night’s unofficial Xcoders I hadn’t thought to ask this question.

There are a ton of Mac and iOS developers in the Seattle area — and almost all the iOS developers are making money either via a paycheck (they have a job) or through contracting.

The only local indie iOS-only developer I could think of was me — and even that won’t be true for much longer, as we’re working on Vesper for Mac.

There probably are other local indie iOS-only developers, but I just can’t think of them at the moment. At any rate, they’re rare.

To be fair, there aren’t that many more indie Mac developers. There’s Gus with Acorn. John Chaffee and BusyCal. Chris and Napkin. Hal Mueller and SkunkTracker. The Vellum folks. But that’s a bigger list than indie iOS developers.

(Noted: not all of the Mac developers are making a living solely through their Mac apps. Gus and John are, but Chris, for instance, also does iOS contracting.)

I think I have two points.

One is that indie developers — people who make all or most of their money via products they create and sell — are fairly rare these days. Most of the local developers I know work at Omni, Black Pixel, or Apple or do contracting.

The second is that indie iOS developers are more rare than indie Mac developers. Though iOS developers outnumber Mac developers by a huge margin, they’re under-represented in the indie community.

This isn’t scientific or anything. I’m just observing the local community, and I could be missing important data.

But if I’m right that this is the general trend, then it means that people making a living as indie iOS developers just isn’t a thing these days. Some money for iOS development is coming from companies like Omni that do create products — but most of it appears to be coming from corporations that need apps (or think they do). Places like Starbucks and Target.

The dream of making a living as an indie iOS developer isn’t dead — see Overcast as a recent example — but, if I’m right, hardly anyone believes in it any more.

I’d love to be wrong.

Who are the indie iOS developers? Who, that is, is making iOS apps only and supporting themselves solely or largely via sales of their apps? (Anywhere, not just in Seattle.)

You could say Q Branch, but we’re working on a Mac app. Marco has a new app, so that’s one. You might say Loren Brichter, but it’s possible his money comes more from Facebook than Letterpress. (I just don’t know.) You might say Michael Simmons and Flexibits, but they have a Mac app.

Found another one: Tutu Lab. That makes two. Who else?

Prefixes Considered Passé

Me on Twitter:

Decided. No longer prefixing classes in app code, even with Objective-C. I can hear your screams and I don’t care.

Prefixing was always a poor solution to the lack of namespaces in Objective-C. There was no enforcement anywhere — and a prefix like RS could stand for Ranchero Software, Red Shed, Red Sweater, and Rogue Sheep. (Those are all real companies that used RS.)

A couple things have made me decide not to use prefixes in app code class names anymore.

First is that I’m spoiled by Swift. I didn’t think it would make much difference to me to be able to use naked class names — CreditsViewController instead of VSCreditsViewController, for example — but it does. It’s much nicer.

The second is that the Xcode 6 betas no longer ask for a prefix when starting a new project. And it creates AppDelegate and friends — not BSAppDelegate and friends.

If I had to guess, I’d say that Apple engineers are also spoiled by Swift’s no-prefixing, and somewhere in developer tools a decision was made not to push prefixes for app code any more.

This — no prefixes for app code classes — will become a recommendation, I’d bet.

There is a caveat, though. There could be non-prefixed class names in Apple’s frameworks. I haven’t personally verified these, but Spencer MacDonald says there’s a Message class and Saul Mora says there’s a BluetoothDevice class. There could be more.

Avoiding these conflicts is the point of prefixing. We can argue that it’s the responsibility of frameworks to use prefixes so that we app developers don’t have to watch out for these — but arguing doesn’t make it so.

Nevertheless, I’d bet these are rare enough that it’s the worth the potential hassle, and we can always file Radars if these come up.

Better Words

James Somers (via Gabe Weatherhead, via Michael Tsai) writes about using a better dictionary — and how to get it installed on your Mac, in Dictionary.app.

Had double-rainbow guy been raised on this older Webster’s, he might have read this:

Besides the ordinary bow, called also primary rainbow, which is formed by two refractions and one reflection, there is also another often seen exterior to it, called the secondary rainbow, concentric with the first, and separated from it by a small interval. It is formed by two refractions and two reflections, is much fainter than the primary bow, and has its colors arranged in the reverse order from those of the latter.

I had never noticed that the second rainbow has its colors in reverse order. This is the quality of eyesight that we want in a dictionary.

I looked up “glass,” and noticed that the default dictionary and this old Webster’s both note that it can be used as a synonym for “to reflect.”

The default dictionary provides this example: “the opposite slopes glassed themselves in the deep dark water.” Which isn’t terrible, but it sticks to the literal pretty closely — while the old Webster’s give us two examples, one literal and one not, to illustrate the range of uses.

Happy to glass themselves in such a mirror. —Motley.

Where the Almighty’s form glasses itself in tempests. —Byron.

(Byron. Wow. I like a metaphor like that because you learn something about both sides, about the Almighty and tempests both.)

This is after two minutes of clicking around. There’s an entire language of rewards in there.

(Tip: the original article suggested p { line-height: 0.7em } — which I think might be a typo. I went with 1.2em.)

Swift and Internal Access as Default

So if internal access is the default, and I don’t want to use it (or want to use it exceedingly sparingly), what do I do?

I can think of a few options.

  • Just pay attention. By convention treat internal as private, and pretend that other objects can only see what’s public. The compiler won’t enforce this, but it’s the kind of convention that’s easily enforced manually if it’s habit.

  • Actually mark every damn thing as either public or private. Just don’t ever use the default. That’s a pain, but also the kind of thing that’s not that hard if it’s habit.

  • Modularize.

The last one intrigues me. My app could be broken up into modules — Q Branch Standard Kit, DB5, data layer, syncing, images/attachments rendering and storage, and user interface.

In that case, I’d be less bugged about objects presenting a larger API, since the objects that could see that expanded API are only other objects in the same module.

I do have a natural bent toward modularizing. I’ve always liked splitting things into frameworks. And the tea leaves clearly spell out Way of the Future for this approach.

But I have two objections, one practical and one theoretical.

The practical one is that I’m still shipping an app for iOS 7, which doesn’t support embedded frameworks. (Or, not exactly.) That problem will take care of itself after a while — but still, it means that right now I’d have to start an iOS 8 branch just for frameworks, which leads down the road to merge debt. Merge debt’s a killer.

The theoretical one is the same problem I expressed previously: where I used to think about public vs. private, now I have to think about public vs. internal vs. private, and I’m not sure that that additional complexity is good for me. The discipline of public vs. private, along with the drive to reduce what’s-public down to the barest minimum, has been good for my designs. It suits my brain — which is more experienced than it is clever — quite well.

There’s an argument that frameworks really need this, that objects need to expose some bits to their neighboring objects that they don’t expose to the world. I bet that that’s how many frameworks have been written. But I also bet that that’s not how I’d do it.

But I could be wrong, and I could be missing out, and maybe I’m just being a stick in the mud.

Swift Access Control

It’s out, and we have public, internal, and private levels of control.

Public means the world can see it; internal is visible inside a target; private is inside-the-file only. (I think I have this right.)

My first thought: I’m not sure I’ll ever use internal.

My second thought: protected would have been nice. I actually used this in Objective-C, back in the days when we’d declare our instance variables.

My third thought: maybe I don’t really care about protected.

I’ll clarify.

With my Objective-C header files I’m accustomed to thinking about only two levels of access: public and private.

I used to use @protected sometimes, back in the days when we declared our instance variables. But I haven’t missed it. And I haven’t even once wished for a target-only access level.

Public-or-private as the only choice imposes a discipline that makes for simpler code. I design for the least-possible surface area, and this makes me think harder about design. If I use internal (or protected) access, then my designs are more complex, and I’m one step away from taking expedient shortcuts at the expense of good design.

So I have classified internal as a code smell and decided not to use it. But this is entirely provisional, because this stuff is all so new, and because I haven’t thought about it as much as the language designers have. I’m a total Swift newbie, like almost everybody else. (I may end up a fan of internal access, in other words, however unlikely that seems right now.)

Glassboard Changes

I’ve been watching with interest as Justin Williams works to turn Glassboard into a sustainable service. It’s not profitable or even break-even at this point — but he’s making changes to turn this around.

Those changes do mean that people using Glassboard for free will be more limited than they were. For example, boards created by non-paying users will be limited to five members — but people can buy a basic membership for $1/month and get up to 25 members.

That’s reasonable. If something isn’t worth $1/month to me, then it’s not worth my time at all.

A few people are complaining on Twitter, of course. And some of the complaints seem to be based on the same magical internet thinking that has led to so much doom and heartbreak — that if you make a whole bunch of people happy by giving them wonderful free things, you’ll be rolling in dough.

And when that thinking is contradicted by facts and logic, that magical thinking says: you should have given them more and even better wonderful free things, and it would have worked out.

I like how Justin is handling all this. He’s direct and clear. Some may take this as bluntness, and it’s true that Justin might never get accepted to the diplomatic corps. But it’s because he doesn’t care about being liked so much as providing a great service. And that’s what we should want him to care about.

I use Glassboard all day every day. Our internal Q Branch communication goes through Glassboard. We have a board for Vesper beta testers. Chris Parrish and I have a board where we work on The Record. Seattle Xcoders has a board. My family has several boards.

I like that it’s simple and private, that there are no ads, and that we’re not being tracked for nefarious reasons. It’s no Google or Facebook where the users are the product — it’s an honest service that is itself the product. As it should be.

I can imagine being in Justin’s shoes. As a fellow indie doing a hard job, he deserves our best wishes. And, if you find the service useful — as I most certainly do — it deserves your financial support. Because we developers all know that wonderful things are not free — or, if they are, they don’t last.

[Sponsor] UI for iOS: Filling Gaps in the UIKit Framework

Telerik UI for iOS is a native development toolset featuring an advanced Charting library with 10+ fully customizable chart types, Calendar, AppFeedback and Data Sync controls.

Integrating the components in your Xcode project is very straightforward thanks to the easy-to-use API. The product comes with dedicated support and detailed documentation of the API.

Give it a try for free and get advantage of the dedicated support that comes even with the trial version of the product.

Chris Liscio Does the Hard Work

Chord Intelligence.

Screw that guy. While I’m fussing over the best way to do an animation, he’s doing science.

Vesper, Auto Layout, and Justin’s Book

Last night I decided to use auto layout for some sub-sub-sub-view in Vesper for iPhone. Worked great. (I’m getting the hang of it.)

Except that it broke the interactive pan-back-from-detail transition. The view just wouldn’t move with your finger.

I have no idea why. I pulled out the little bit of auto layout code I was using.

So: enter Justin Williams. Today I emailed him to ask if his new book covered auto layout and interactive transitions, and he said he’d give it a shot.

I like how he’s doing this. He’s put out an early, unfinished version of his book and he’s getting feedback as he goes. Very cool.

The thing I need to learn isn’t really using auto layout for layout — I’m getting the hang of that part. The Mac version is all auto layout, even. But the iPhone app barely uses it all, since the app is so full of animations and interactive transitions, and I just don’t get (yet) how to use auto layout with all this.

You might think I’d feel some urgency about auto layout, given the rumors of 4.7" and 5.5" iPhones. If the rumors are true, those screens might have different point dimensions than what we’ve seen so far. (Maybe. Even if they don’t, we should be prepared for it.)

However, it’s no harder to support different dimensions using layoutSubviews and layout code than it ever has been. There are a few places where Vesper hard-codes screen width at 320 points — but I could fix those in 15 minutes. The Credits screen is written to expect just two specific heights, but it wouldn’t take much work to make it work with variable heights (and it would probably simplify that particular code, actually). No other part of the app expects any particular screen height.

It’s not urgent, in other words, but it’s still important to switch to auto layout.

What’s cool about auto layout isn’t that it allows us to deal with different screens — we can do that the old-fashioned way just fine. All those Mac apps for all those years handled resizing windows and views without auto layout, after all.

What is cool is that we can switch from imperative to declarative style, and that matters. The more we can do of that with our UI code (which is so fiendishly boring to work on) the better.

auto_closure

Apple, Building assert() in Swift:

Auto-closures are a powerful feature because you can conditionally evaluate an expression, evaluate it many times, and use the bound expression in any way a closure can be used.

The End of the Gloomy Source List

I’ve been spending most of my time in Yosemite for a while now. My favorite on-the-surface change is the change to source lists.

The sad-and-blue source list we’ve had for years — first seen in iTunes, iLife, and Mail — has been replaced with a translucent source list. It’s more fun, and I think people are going to love it.

But me, I’m ultra-sensitive to on-screen clutter. (It’s a flaw.) I almost never have files on my desktop. There are relatively few icons in my Dock compared to other people (around 12). I hide apps that are not in active use — at most I’ll have Xcode, Terminal, and Vesper for Mac showing. My desktop background is always a solid color.

So I turn off source list translucency, via System Preferences > Accessibility > Display > Reduce Transparency.

And it looks great. Source lists are a nice very light gray, rather than that wiped-out blue we’re used to.

When I have to go back to 10.9, and have to deal with the old-style source list (in Xcode, especially), I can’t wait to get back to Yosemite.

I’m surprised by how much of a difference this makes to me. It’s a big deal.

Update a few minutes later:

William Van Hecke posts on Twitter:

We’ve long called that sidebar color “corpse blue” around here. It’ll be sad to lose that bit o’ jargon.

New Database

Realm is a new mobile database that I should look at.

While there are many options for server-side databases, for mobile it’s pretty much SQLite. (Core Data uses SQLite.) A few people may be using LevelDB (which I’ve been meaning to look at). Perhaps some people are using Kyoto Cabinet.

I love SQLite. I’ve been using it since SQLite 2.something. I’ve just about made a career out of it.

But if you asked me if we mobile developers should have more options, I’d respond with an emphatic yes.

A Stock Control Won’t Always Do the Job

I wrote about using stock and custom controls the other day, and I was careful to make the point that sometime custom controls are absolutely needed.

Vesper has a bunch of custom controls — far more than in any app I’ve made before. We could probably cut out a few of them, especially now that iOS 7 and 8 added features that we didn’t have when Vesper was first created, but we can’t cut all of them, or even half.

Here’s a small example:

If you’re a Vesper user, you know that tags sit above the keyboard when you’re editing. When you’re not editing, they appear below the end of the text.

The tags move as the keyboard appears and disappears.

You also know, if you’re a user, that tapping a tag gives you a little menu — much like the text editing menu — that lets you copy or remove a tag.

The tags themselves are a UIButton subclass. A fairly elaborate one, but still a UIButton.

That menu, though, is entirely custom. It’s not even a popover, since popovers won’t appear on iPhones until iOS 8. It’s a fake popover, custom from the ground up.

It seems like this is the perfect place to use UIMenuController. And, in fact, if you look at the menu (just tap on a tag to see it), you’ll see a black menu with white text, rounded edges, and an arrow pointing to the tag button.

It looks almost exactly like a UIMenuController menu, in other words. A normal, non-obsessed person wouldn’t notice the difference.

So why not switch to UIMenuController? Delete all that custom code. Great idea. (I love deleting code. Love love love.)

But UIMenuController wants the item attached to the menu — the tag button, in this case — to become first responder.

And, as soon as the button becomes first responder, the text view is no longer first responder, which means the keyboard falls away, and the tag buttons move so that they’re anchored at the end of the text. (And the UIMenuController menu shows and hides real quick, as if it’s been frightened by all the sudden activity.)

So we can’t use UIMenuController in this case.

We could do something entirely different — a UIActionSheet, for instance — but that would be a usability loss in this case. A UIMenuController-like-menu really is the best way to solve this problem.

Which means we have to use a custom control.

It’s possible that, in iOS 8, I could make it a real popover, but I’m not sure I’d have control I need over the appearance. (The corners have to be rounded just so, the arrow has to be the way it is, etc.)

Anyway. That’s show biz for ya.

Update 9:15 pm: Well, it’s possible to keep the keyboard up when using UIMenuController. See Jared Sinclair’s tweet.

I’m not sure that would actually work in my case, since it would hijack typing, which should go to the text view. (I say this without actually trying it, though.)

Archive