Apple is a harsh mistress
I’m a fanboy. There. I said it. I’ve never said that before in my life, but if you look at my history with Apple products, there is no doubt about it. I grew up in a PC family. I played Chess Wars on a PC my dad helped me build when I was 10. Luckily, I grew out of that. I bought my first used iBook (a used clamshell) circa 2000, before I’d even graduated high school. I’ve never owned a PC since then.
When the iPhone first came out, I wanted it. Bad. I saved until I was finally able to buy one “for myself”, for Christmas that year. It was awesome. I didn’t care that I couldn’t develop for it — it just worked. Like everything else Apple did. When the SDK was finally announced, I didn’t have an Intel based machine to work with. So I went out and bought a Mac Mini to replace my old 17” Powerbook G4. Just so I could start working with the SDK — a couple of months after it was released. I loved it. I loved learning Objective-C, and let’s be honest: it as a hell of a learning curve. I loved that I was inspired by Apple to be a better developer.
I’ve always had mixed feelings about the app store review process. It has a purpose and it serves it. It’s not necessarily a bad thing - it *does* help edit the storefront, and let’s be honest: without a curator, what kind of gallery would it be? Up until these last two weeks, I considered myself “lucky”. The only rejections I’d had were completely valid. Legitimate, certified bugs.
That all changed when Apple started scanning for private API usage. It just so happened that the popular three20 framework included code that, well, used private APIs. No way around that one. And that’s fine. Private API usage is and always has been in violation of the contract that we all agreed to. Silly me for trusting external frameworks to not use private APIs. My bad.
Over the last two weeks though, that scanning seems to have taken a turn for the worse. It’s now picking up “false positives” for method names that are, apparently, the same as internal “private” methods.
Example: TouchXML by Jonathan Wight.
Example: Zynga, Zynga #2 by Amanda Wixted. Notably, this one was accepted after emailing the app reviewer.
Example: more three20 rejections
Let’s be frank about this: it’s bullshit. We now have *no idea* what is and isn’t acceptable. No clue. That’s scary and incredibly disheartening. Just last week, apparently Apple started sending handslaps rather than rejections, but that’s not the entire story there either. I had a clients application accepted with a handslap. For using an older version of three20. Less than 12 hours later, my own personal application, Boxcar, was rejected for using that exact same version of three20.
I have yet another client application that was rejected for using private APIs this week. Actually, who knew that SBFormattedPhoneNumber was private. Not me. Nor did anyone else, because it’s the most commonly accepted, and well, only way to retrieve the users phone number if it’s even set for that particular users device. It’s not reliable, it’s not even always there, but it’s the closest thing we were given to a “me” card in the users Address Book.
Explain to me how SBFormattedPhoneNumber can be abused any more than just sending the users entire Address Book to a remote server. It can’t. If I were to build a malicious piece app, I’d be much more interested in the Address Book’s contents than I ever would the users single phone number.
But that’s beyond the point. Apparently as of November 5th, SBFormattedPhoneNumber is now private. Sorta. It’s still publicly accessible, using public methods, it’s just off limits. Unfortunately, this particular clients application was built and submitted well before November 5th. It’d just been rejected twice already, and then finally a third time this last week. The other two rejections were related to private API usage via three20. Each time with each rejection, the problem was fixed. We resubmitted and waited. Waited. And, waited some more.
Speed is really the secondary problem here. As stated earlier, the app reviewal process serves a purpose. It’s not inherently evil. It’s just slow. Up until these last few weeks, if an application was rejected we would only know “one” reason why. The review would stop after the reviewer found a problem, and we’d resubmit, get back into the queue, then wait only to be rejected 2 weeks later for yet another issue. Here lately we’ve been receiving multiple reasons (if necessary) in the same email. Yay, change. So you fix those problems, then resubmit. And wait. Then once your turn in line came up again, you find out that something else is now being checked for. It may be completely invalid — your own method names matching private names by Apple, not even in the same class. Oops, back to the end of the line for you.
And so that’s how it goes. You wait and wait some more. That’s the part that screws everyone.
So here’s a simple fix for it. Give us a 24 hour grace period after a rejection. Let us resubmit a new binary, with the fixes in place for the rejection reasons, and not have to go to the back of the line again. At least let us have a semblance of a chance of maintaining a release schedule. As it is now, we can’t. We don’t know what you are or aren’t looking for now, valid or invalid.
I’m not the first nor will I be the last person to write something about how badly the app review process is broken. Schiller, you can champion it all you want. The fact is: it sucks. These latest changes are completely in the wrong direction. Check for private APIs all you want, but at least be certain that’s what they are.