Saturday, November 21, 2009

Shine: Your Mac Indie Business in a .zip

Last week I released SimCap, my first OS X application. This entailed — in addition to the whole 'designing and coding and testing' part — setting up the infrastructure necessary to sell it. Of course, I did all this at the very last minute, with SimCap sat there ready to go and the absolute minimum of advanced planning. That minimum planning was the decision to use Shine.


Shine is an application management dashboard, written by Tyler Hall and designed around the basic workflow of your average Mac Indie developer: taking payments via PayPal, generating licences with AquaticPrime, and pushing updates using Sparkle. I first heard about Shine on The MDN Show (epsiode 11) (which was — sorry, Scotty — the first episode I'd listened to in a long time). One of the things about iPhone development is that Apple does take care of most of the business side of things for you. While Shine doesn't exactly sit you down with a hot cuppa and tell you not to worry your pretty little head about all those nasty numbers, it certainly makes things easier, especially if you're starting out from scratch. Assemble components to fulfil the same roles Shine does would probably taken a few days.


I'm afraid that this won't be a complete Shine "how to" guide, but instead a collection of my thoughts on the process of setting the dashboard up, scribbled down while the experience is still fresh in my mind.


Firstly, did you notice that "especially if you're starting out from scratch" bit above? I mention it because Shine is rather inflexible in what it does. You can replace the AquaticPrime portion with your on licence generator, but otherwise the workflow is pretty-much locked down. Payment info comes in via PayPal's IPN service, so if you use a different payment processor you'll either need to write your own handler or look for another solution. Likewise, updates are stored in and downloaded from Amazon S3, without, say, the option to store them on your local server. In this last case, I decided that the ease of using Shine would probably outweigh the cost of using S3. (And I think I was right: this week's thousand downloads have cost me about 20 cents.)


Shine is basically a set of PHP scripts (available from the link above, either directly via Git or in the archive format of your choosing). Installation is just a matter of copying them to your server. The config file allows you to configure the exact same code for both your test and production servers. Documentation is minimal, basically amounting to the comments in the source code — but then this is aimed at Indie developers, who can probably be expected to feel comfortable diving into the code and figuring things out that way.


But just in case you aren't, or you've stumbled across this post looking for help... You build the MySQL database shine needs by running the .sql file from the archive using MySQL'a source command. You'll then have to create your own entry in the users table. There's an entry for using encrypted passwords in the config file, and if you set it, don't forget to also provide a string of random characters as salt. I ended up inserting random echo statements into the hashing function (on my test server) to see what value I should enter into the database as a password, but I'm almost certain there's a simpler way of doing it.


I can't personally say that installing Shine on my production server was a breeze, but none of that was Shine's fault. The code is neatly modular, which means that you may only encounter a problem with your server configuration the first time you go to use a particular feature. For instance, the first time I tried to test the PayPal IPN, I discovered that Shine needed libcurl, which I didn't have installed. (What followed was a couple of days of server re-imaging and mod_php re-compiling — but I'm sure that your mileage will vary. Especially if you have a grown-up looking after your servers for you.) As far as I can tell, the not-really-at-all-exotic-although-some-Linux-distros-seem-to-think-so modules you'll need are libcurl (for PayPal IPN), libjson (for everything(?)), and bcmath (for AquaticPrime — and this can only be added to PHP at compile time... sigh). A little pre-flight test script to check for these and warn of any potential nasty surprises might be an idea (and I guess if someone who knows their way around PHP doesn't write it then I'll have a go...).


Once you get this far, another little gotcha is that Shine will only process IPN messages with "Completed" status. Which makes perfect sense and is how you want it to behave, but can easily catch you out. If, like me, you're selling in a different currency to that of your bank account, you'll want to throw the "accept and convert" switch (it's under "Profile > Payment Receiving Preferences") to have transactions automatically completed. And while you're there, you'll also probably want to disable accepting eCheques, since transactions using them also won't complete straight away.


I've dwelt on the cons of using Shine because a post saying "use Shine, it's simply amazing" would be a little dull. But, honestly, I really can't recommend it enough. It has made the business side of launching an OS X application about as painless as you could hope. (And I haven't even mentioned it's integration with Tyler's OpenFeedback framework.) There are a couple of extra features which I'd like to see — some indication of the sample size used to calculate your Sparkle stats (did I mention Shine will also collect statistics from Sparkle?), for instance, and maybe auto-response and notification e-mails for OpenFeedback submissions — but otherwise Shine does everything it needs to so you don't have to. Get it and use it: it honestly is that much of a no-brainer.



Saturday, November 14, 2009

Apple Does Love Me!

I'm sorry if I ever doubted you guys.

Is the App Store Broken?

You could say that these are Interesting Times to be an iPhone developer — although you could easily have said the same thing at any point since the announcement of the SDK. It seems that time and again we get weeks like this, where the number of "App Store Evil" stories in the press suddenly swells and it looks like matters are coming to a head. There have certainly been some happenings recently. The more public events you've doubtlessly heard of from Gruber, so I'll start with what's been going on behind the iPhone Dev Centre log in.


Trouble in Store


If you're a frequent browser of the App Store you may — or more likely, may not — have noticed something a little funny about the listings; in particular the "Recent" lists. Apple has introduced a new updates policy for the App Store. It used to be that whenever an update to an app was released it would be bumped back up to the top of the relevant list. This is no more. Now this list only shows newly released v1.0 applications. To say that this change is unpopular among developers would be an understatement.



For many developers, frequent small updates — and their accompanying bump in position with attendant spike in sales — was their main (or only) business plan. (I can certainly attest that the only times Lexical has seen any number of sales were after initial release and after the 1.1.) Cue much wailing, gnashing of teeth and cries of "sod this, I'm off to Android", interspersed with pragmatic — and somewhat exasperated — messages which basically boil down to: "Oh FFS, you can't rely on Apple to do all your marketing for you, why don't you try a little advertising, I hear it works wonders in every other single business ever."



As a side effect of these changes — or, more likely, of cracking the App Store open and tinkering with its workings — we get the messed-up listings. Apps released last year are suddenly reappearing at the top of lists, accompanied by other apps which won't be released until next year. On the plus side, you no longer have to manually adjust your release date once your app has been approved, but at this moment that seems like a very small comfort. It's been over a week now and things finally seem to be settling down. Presumably it's taken so long because those whose job it is to fix it — and who made the mistake in the first place — have been nailed up in the lobby of their building on Infinite Loop — alongside the rotting corpses of the old MobileMe team — as a warning to others.



(Playing armchair App Store manager for a moment, I'd suggest a two-track approval process for updates. When the developer submitted their update they'd check one of two options: "Bug fix" or "Feature Update". Bug fixes would be fast-tracked — let's say there's a semi-guarentee of under five days — but would not receive a list position bump. Feature Updates would be subject to the same fourteen-days-if-you're-lucky process as new apps — and as we get by default now — but would benefit from top-of-the-list exposure. But since I do not, have not and probably never will run a international application download service it really doesn't matter two hoots what I think should happen.)



What's in a Name?


Meanwhile, TUAW reports that a number of developers have been sticking the word "edge" into their app names as a protest against the actions of the owner of the trademark "Edge", who has been busy enforcing it — with Apple's help — in the App Store. I suppose it's good to see that, despite their world collapsing around them, iPhone developers can find the time to have a little silly fun. The word "edge" isn't the only one to be proscribed in this way. "Memory" is also now verbotten, although it seems on Jeff Lamarche has reported on this. So should we take this as another sign that the App Store is broken? No. In this case, Apple is responding to a legal request in the only way it can. Whether or not that request is fair is not their decision.



I'm Going Home and I'm Taking My Toys with Me


We've had a couple of high profile hissy-fits in recent days. I'll include that Facebook guy under "high profile", even though I'd never heard of him before. But we shouldn't be too surprised by his departure. If he works for Facebook then he's going to be rather limited in the type of apps he's gets to work on (hint: it will mostly be Facebook clients). The Facebook iPhone app has been around long enough that it probably does everything it needs to, so there's no point wasting your rock star developer on maintaining it. Might as well get yourself some free publicity with a spectacular walkout and then hand the day-to-day upkeep to some lacky.


And then we have Mike Ash and Rogue Amoeba. The Aitfoil Speakers Touch saga is being held up as the latest great failing of the review process and of how the rule reviews enforce are arbitrary, obscure and inconsistent. (Although at least no-one seems to be blaming this on "out-sourcing" and "off-shoring" any more. Those terms rank alongside "UK-only call centres" for making me want to stab people in the face.) But just for the sake of being contrary, I'm going to disagree. I think the — admittedly unspoken — rule is very clear: Apple is asking iPhone developers, "Please do not let users think that your application is our problem".



The Airfoil problem boils down to this: Rouge Amoeba want it to show (a) a Mac OS X application icon, and (b) an image of a Macintosh computer; Apple don't. Rogue Amoeba's first argument is that neither icon nor image are distributed with the app, but are instead accessed using public API calls on the host machine. Doubtless true, but still beside the point. If I try to release XXX iHardcore iPorn I shouldn't be surprised if it's rejected, no matter how loudly I complain that the content isn't included in the app but is downloaded using public APIs. A high proportion of the time, the icon which Airfoil displays will be from an Apple product. 100% of the time it will display one of Apple's images of a Mac. When an application does something 100% of the time arguments about how it does it are nothing more than weasel words.



The second argument is that the first version of Airfoil did exactly the same thing and was both accepted and remained available for the whole time. Which is where — and I'm just speculating wildly here, but then so are you, so shut up — the unspoken "Please do not let users think that your application is our problem" rule comes in. Maybe the person whose job it is to trawl through the support logs found an abnormal number of requests which went something like: "I'm having terrible problems with your iPhone application X and if you don't fix it right away I'm telling my lawyer" "But sir or madam, X is not an Apple application" "Oh no you don't fool me that easily, it has your a picture of [random Apple product] in it so it must be yours". Airfoil need not even have been the product mentioned. We already know that you cannot use images of the iPhone in iPhone apps. Images of any Apple product seems like a natural extension of this. And since we've all seen the App Store evolve over time, it's not an enormous leap to assume that this new tightening of the policy was instigated sometime between the release of the original Airfoil and the submission of the update.



The iPhone and iPod Touch are not Macs, and not only from a technical point of view. They are consumer electronic items in a way that computers never really have been. As such, they have a different user base (although admittedly with a lot of crossover). Let's try a little experiment. Find a non-Apple-devotee iPhone user. Take their iPhone and pull up the home screen. Now ask them to identify which of the apps listed there come from Apple and which don't. Product support costs money. Yes, Apple makes great margins, but they don't do it by paying their staff to explain time and again to customers why the problems caused by that app showing a picture of a Mac and the iTunes logo isn't actually anything to do with them. (After all, Apple is more than capable of causing its own bad publicity, thank you very much.)



Let me try a different metaphor. You may be familiar with the "advertising feature" which you occasionally find in magazines and newspapers: an advert formatted to look like editorial. Now, I'm willing to bet that your average journalist hates these more than an over-zealous expenses auditor. Because you may have the smartest readership in the world, but when they're curled up on the sofa with your publication, defences down, flicking away, there's a good chance that a least a few of them may be tricked into thinking that it's actually you or your colleagues who are recommending that they install Super-Dooper Virus Smasher 2012. I'm sure that Apple views apps that appropriate their content in exactly the same light.



And... I think that's more than enough for now.



Friday, November 13, 2009

Plaques + SimCap = A Busy Week

It's like the tired old joke about buses: I wait months (no, years) to release any applications, and then suddenly along come two at once.



First, on — I think — Monday, late, my second iPhone application Plaques, eventually limped into the App Store. Where it was promptly buried on page 4 by a slew (correct collective noun) of near-identical travel guides. Since then its sold a couple of copies but generally not done very well.



And then today we have SimCap, my first proper grown-up OS X app. It's a deceptively simple little application which does some eye-wateringly nasty stuff with window buffers and uses an NSOperationsQueue and everything. (In my spare time I've been trawling StackOverflow for questions about NSOperations being either delayed or cancelled, so I can chime in and suggest the poster checks for typos, because it sounds like they've accidentally sub-classed NHSOperation... this is actually a very funny Cocoa coder joke.) I'm really very happy with the way this has turned out.



So all in all a pretty busy week. I know, it's really amazing the lengths I'll go to to avoid my NaNoWriMo obligations.