Rejected: For Using UITouch Three20. (Updated)

Shaun, Nov 9

Update: Thanks to @SteveStreza for pointing out this is actually a problem with @joehewitt's famed, but flawed, three20 library.

I'll leave the original blog post up, but Apple had every right to reject us. Sorry Apple!

At this point, hating on Apple's app approval process is old and tired. Everyone knows its broken, Apple even acknowledges it's broken. We all get rejected, usually we continue to go about our business and deal with it (maybe a bit of complaining on Twitter).

This one though, this is an entirely different situation. We just had two applications rejected for using UITouch. Here's a copy of the email we received from Apple: (Screenshot)

Please include the line below in follow-up emails for this request.

Follow-up: [REDACTED]

Dear enormego,

Thank you for submitting [REDACTED] & [REDACTED] Pro to the App Store. Unfortunately it cannot be added to the App Store because it is using a private API. Use of non-public APIs, which as outlined in the iPhone Developer Program License Agreement section 3.3.1 is prohibited:.

"3.3.1 Applications may only use Documented APIs in the manner prescribed by Apple and must not use or call any private APIs."

The non-public APIs that are included in your application are the following undocumented, private UITouch instance variables:

UITouch._locationInWindow
UITouch._phase
UITouch._previousLocationInWindow
UITouch._tapCount
UITouch._timestamp
UITouch._touchFlags
UITouch._view
UITouch._window

Regards,

iPhone Developer Program
***************************

We develop a lot for the AppStore. We have a lot of applications on AppStore, which means we've definitely experienced the cryptic and "WTF?" rejections from AppStore, that everyone else has to deal with. This one isn't cryptic at all, it's very, very specific.

Apple seems to think we're accessing it's instance variables directly. Two thoughts of this:

  1. As far as I know, you can't access private/protected instance variables directly from outside the class. Objective-C's compiler will not let you.
  2. The only way to access these variables, is to do it via the ObjC runtime methods, and at that point, Apple wouldn't be able to detect it, since it's being called at run time.

As to the second point, we're not modifying these ivars at run time (why would we? they're public methods). For the arguments sake, even if we were, they'd need to actually run the app, and according to our server logs, they never once opened it.

However, all of that is moot. We're not accessing the ivars directly, we're using the public Apple provided methods.

To take this a step further and try to be as transparent as possible, here is every single reference to UITouch in our application:

As you can clearly see, the bulk of the code used is from Apple's own example code. Other than that, we use it to detect the correct row index when a UIControl is tapped in a UITableViewCell. There is nothing remotely questionable here. This is standard use of UITouch, and I'm sure there are thousands of apps on AppStore that use this in the exact same way — in fact, just about all of our apps on AppStore use it this way.

We'd have no problem at all sending Apple the entire Xcode project to let them see for themselves that this isn't happening in the apps. However, there's no communication on Apple's part, as everyone knows. In fact, one of these apps showed up as Rejected on iTunesConnect 5 days ago, and we just received the email an hour ago explaining why.

This doesn't make any sense, and Apple really needs to explain itself.

Unless of course, Apple has decided that detecting touches on the iPhone is no longer allowed.

blog comments powered by Disqus