App Store Rejection: "2. 5 Performance" (Status Updates only)


#1

Status Update: Monday 13 March 17h45 GMT

I don’t have any new information to share yet, so I’m going to summarise where we’re at right now:

Situation

  • Some customers are experiencing rejections when submitting new versions of their apps.
  • Some customers have had existing apps pulled from the App Store.
  • Some customers with multiple apps on the App Store have had some apps rejected and/or pulled while other apps have not been effected.
  • Some customers have not yet been affected at all.

Analysis

  • Based on comparisons between customer app configurations, we have found no correlation between the modules used and whether they are being flagged by Apple or not.
  • Apart from a single dynamic lookup (using a static string) for a method call against WKWebView when the Forge framework is run in debug mode (which we removed in 2.5.2) we cannot find any other instances in our code which even remotely matches the profile in the rejection notice.
  • We’ve now almost completed the process of ploughing through a massive code review of all our native modules and any third party dependencies they rely on and have, so far, uncovered nothing.
  • If the problem is reload, we would have expected to see apps built on the other hybrid platforms such as Cordova/ReactNative/Microsoft etc. to have been affected as well but there is currently no evidence that this is the case.

Response

  • The first sign that there was a problem was on 20 February when this thread was started.
  • We released Forge Platform v2.5.2 on 24 February which removed one potential cause of the problem.
  • The first sign that multiple customers were affected was on 8 March.
  • We opened a Technical Support Incident (TSI) with Apple on the 10 March.
  • On 11 March we received a follow up that closed the TSI and asked us to resubmit it using their “Contact the App Review Team” and “request a technical investigation”.
  • Later on 11 Match we received an automated response asking us to submit a rejection appeal form which we subsequently did. We have had no further communication from Apple since then.
  • In a few hours we’ll have completed a full code review of the Forge Platform, Native Modules and all 3rd party dependencies. A process which has, so far, yielded no answers.

It’s now Monday morning in San Francisco and we’re hoping that Apple will respond to our questions soon.


Apple Store Review information request
#2

Status update: 15 March 2017 10h00 GMT

It has now been six days since we first reached out to Apple and we have not yet received a response to our questions.

At this time I would like to make an appeal to all our affected customers to please reply to Apple’s rejection notice and, optionally, submit an appeal to the App Review Board.

The process to do this is as follows:

  1. Login to https://itunesconnect.apple.com
  2. Click on “My Apps”
  3. Click on the “View Issues” link of your affected app.
  4. Enter your reply in the “Reply” text box. You can use the following as a template:

We respectfully request that the review team re-evaluate the rejection of our App binary on the basis that it is not guilty of violating compliance with App Store Review Guideline 2.5.2 nor section 3.3.2 of the Apple Developer Licence Agreement.

Our App is a so-called “hybrid” application which is implemented as HTML, CSS & Javascript code run by Apple’s built-in WebKit framework.

Specifically, the platform we have chosen to implement our App is Trigger.IO Forge (https://trigger.io)

To the best of our and Trigger.IO’s knowledge neither our App nor the Trigger.IO Forge platform “Includes any code which passes arbitrary parameters to dynamic methods such as dlopen(), dlsym(), respondsToSelector:, performSelector:, method_exchangeImplementations(), and running remote scripts in order to change app behavior and/or call SPI, based on the contents of the downloaded script.”

If we or Trigger.IO are in error, we ask that you please provide us with further information we can use to determine why our App could be triggering a false positive with the review guidelines and allow us to rectify the situation immediately.

To assist in this process Trigger.IO has agreed to share the source code of their platform with the review team should you request this (or any other) information in the course of your investigation.

If you should require access to the Trigger.IO source code please provide us with a https://bitbucket.org/ account name that we can forward to Trigger.IO.

We are eager to work with the review team to resolve this as swiftly as possible and look forward to your response.

All the best,
[your name]

If you like, you can also click the “Submit an appeal to the App Review Board.” link to file a formal appeal.

I’m uncertain whether this will be more effective than just replying to the rejection notice as it may trigger a separate process within Apple that will take longer to result in a response.

Finally, I’d again like to thank everyone for your ongoing patience, feedback and support as we navigate an event which is entirely unprecedented in the five year history of Trigger.IO.


#3

Status Update: 15 March

Let’s try it.

I’ve just pushed a new platform version v2.5.3 to production that removes the iOS implementation of reload in its entirety.

To test it:

  1. Update your src/config.json to "platform_version": "v2.5.3"
  2. Remove all references to reload from the core.general section of your apps src/config.json file.
  3. Make sure you don’t have any calls to forge.reload.* API’s in your App source code as they will fail with a “This method is not available on this platform” error.

Let us know what happens!


#4

Status Update: 16 March 2017 15h45 GMT

It’s now Day 8 since this blew up and I know we’re all starting to despair a little at the utterly random behaviour we’re seeing from Apple’s review process.

That said, here are two reasons for optimism:

  1. It’s become clear, beyond a shadow of doubt, that there exists no pattern as to whether apps will be accepted or rejected. If there was a problem with either the Forge platform or customer code then multiple apps with identical native configurations and customer code would ALL be rejected, but this is not the case.
  2. We’ve received the first confirmation that Apple are aware of our repeated attempts at communication.

Following a a long phone conversation with Apple Developer Program support last night (Tx @mknox81!) we received this email today:

It’s a pretty typical Apple communication, acknowledging your feelings without responding to any of your concerns, but after we decode it with our SecretSteveDecoderRing™ it basically reads:

  • Apple acknowledge that we have made multiple attempts to talk with them.
  • Apple confirm that there is a formal review in progress.

This is good.


#5

Status Update: Saturday, 18 March 07h38 GMT

  • We’ve received a response to our appeal from Apple which provides a new fragment of information around the permissible uses of respondsToSelector and performSelector:

  • If our interpretation of it is correct I’ll provide a more in-depth analysis later but the short version is there’s a slim possibility that an integrity check performed by our Javascript/Native bridge to protect against the exact behaviours Apple are trying to prevent may be responsible for the rejections.
  • I’ve pushed a new platform version v2.5.4 to Production which removes this check.

Current Recommendation

  • If your app does not use the pushwoosh module, custom native modules developed in-house or reload, can you please resubmit your app for review after rebuilding it against Forge Platform Version v2.5.4 and let us know what happens?

#6

Status Update: Monday, 20 March 19h30 GMT

  • Our test app built against Forge v2.5.4 is still waiting for review.
  • We’ve heard back from one customer who has resubmitted using v2.5.4 and had their app rejected after review.
  • There was no new information in the rejection notice and I’m adjusting our current recommendation to temporarily exclude any modules that rely on 3rd-party code outside of Trigger.IO’s control.

Current Recommendation

  • If your app has been rejected after resubmitting with v2.5.4 and contains any of the following modules:

  • apptentive

  • barcode

  • bolts

  • facebook

  • flurry

  • kumulos

  • parse

  • pushwoosh

  • segmentio

  • urbanairship

  • Any custom modules which are not listed on the official module catalog at: https://trigger.io/modules/_/all/

  • Please remove these modules (temporarily!) from your app’s configuration and rebuild before resubmitting.

  • Even if removing the modules breaks your app it will tell us a lot if a subsequent rejection notice complained about broken app functionality rather than the “Performance - 2.5.2” rejection.


#8

Status Update: Thursday, 23 March 10h30 GMT

  • More customers are reporting that their apps are suddenly passing review.

  • We’ve made some headway with our efforts to pass information on to the App review team via unofficial channels. (Tx @goodgravy !)

  • Another one of our test apps has been rejected but, this time, on the basis that the reviewer found the app description lacking. This is good :slight_smile:

  • It’s now been over 36 hours since our primary test app entered “In Review” status. Highly unusual and it leads me to hope that someone at Apple is starting to pay attention.

Current Platform Recommendation

  • I have released v2.5.5 of the Trigger.IO platform which re-enables Reload.

  • If your app relies on Reload or you have a non-critical app submission pending we’d be very interested to hear about the outcome if you’re willing to take a chance on submitting a v2.5.5 build.

  • Otherwise, probably safest to stick to v2.5.4 for now.

Current Modules Recommendation

  • We have released v2.9 of the request module which removed a dependency on the 3rd-party AFNetworking framework. AFNetworking itself is not problematic but we’re in the process of removing outdated dependencies from the codebase to make future code reviews easier.

  • If your app has been rejected after resubmitting with v2.5.4 or v2.5.5 and contains any of the following modules:

  • apptentive

  • barcode

  • bolts

  • facebook

  • flurry

  • kumulos

  • parse

  • pushwoosh

  • segmentio

  • urbanairship

  • Any custom modules which are not listed on the official module catalog at: https://trigger.io/modules/_/all/

  • Please remove these modules (temporarily!) from your app’s configuration and rebuild before resubmitting.

  • Even if removing the modules breaks your app it will tell us a lot if a subsequent rejection notice complained about broken app functionality rather than the standard “Performance - 2.5.2” rejection.


#9

Status Update: Thursday, 30 March 08h30 GMT

  • We believe everyone’s apps are now passing review, if your app is still being rejected please get in touch with me at support@trigger.io.

Current Recommendation

  • We have bumped the latest stable release of the Trigger.IO platform to v2.5.5 and recommend that everyone use this version for future app submissions.

  • We will be temporarily maintaining v2.5.4 of the platform which is identical to v2.5.5 with the exception that Reload has been removed from the codebase.

  • We are lifting the recommendation to avoid the following modules:

    • apptentive
    • barcode
    • bolts
    • facebook
    • flurry
    • kumulos
    • parse
    • pushwoosh
    • segmentio
    • urbanairship
  • We still haven’t received any explanation from Apple for either the recent spate of app rejections or why previously rejected apps are now suddenly being accepted.