Review Crashes - Invalid Product Identifier

I submitted an app with a single non-consumable IAP upgrade. It crashed all the Review Teams devices (but works wonderfully on my devices).


After I symbolicated the crash log (from the Review) the app crashed for them when my singleton Store handler (added as the Store observer in App Delegate didFinishLaunching) called requestStoreProductList (from my main view controller) and the delegate method productsRequest: didReceiveResponse: was called (in the custom object) but the response.products array was empty and when I tried to do anything with the array (e.g. objectAtIndex:0) the app crashes.


This happened to me during development as I had put the wrong identifier in iTunes Connect, but that was corrected, but then my test Sandbox user still wouldn't recognize the change and the failed delegate method showed the corrected identifier as "invalid". So, I deleted that test user and created a new one, and then everything worked (the product was returned). And it has worked for me ever since and I have NO crashes on my device or for any simulator device (not like the Review team).


So, this seems like something wrong internally in the iTunes Store with maybe the old (wrong) identifier hanging around??? And why will it work fine for me and not with the Review Team?


Thanks for any insights and solutions.

Answered by in 14832022

From time to time, App Reviews of in app purchase apps will fail when the SKProductsRequest is made to preflight (validate) the in app purchase identifiers. Specifically, the identifiers will not be returned in the response.products field, but instead in the response.invalidProductIdentifiers field.


I suspect that in your case, the app did not check that the identifiers were not returned in the response.products field, but instead assumed that they were valid and continued to the addPayment method. Such use can result in a crash.


The application should check the response result in the didReceiveResponse delegate method and either alert the user if the in app purchase identifiers are returned as invalid, or not offer them for purchase. A best iAP practice is to make the SKProductsRequest once, so as to verify that the identifier is valid and to obtain the current pricing and description information. There is no need to make this function all before making the addPayment call.


Now to the real issue here - it appears that the SKProductsRequest call failed in App Review. App Review will always review in app purchase apps on devices with a valid network connection. For whatever reason, the SKProductsRequest can fail in the App Review environment. It shouldn't, assuming that the in app purchase identifier is valid.


For anyone who is sure that the App Review failure resulted from a failure by SKProductsRequest to validate the in app purchase identifiers, one suggestion is that you submit a DTS incident. DTS will review the App Review rejection response and if the failure condition appears to be caused by an SKProductsRequest failure, DTS can request a second review of the app on the newly restarted device.


rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI

Accepted Answer

From time to time, App Reviews of in app purchase apps will fail when the SKProductsRequest is made to preflight (validate) the in app purchase identifiers. Specifically, the identifiers will not be returned in the response.products field, but instead in the response.invalidProductIdentifiers field.


I suspect that in your case, the app did not check that the identifiers were not returned in the response.products field, but instead assumed that they were valid and continued to the addPayment method. Such use can result in a crash.


The application should check the response result in the didReceiveResponse delegate method and either alert the user if the in app purchase identifiers are returned as invalid, or not offer them for purchase. A best iAP practice is to make the SKProductsRequest once, so as to verify that the identifier is valid and to obtain the current pricing and description information. There is no need to make this function all before making the addPayment call.


Now to the real issue here - it appears that the SKProductsRequest call failed in App Review. App Review will always review in app purchase apps on devices with a valid network connection. For whatever reason, the SKProductsRequest can fail in the App Review environment. It shouldn't, assuming that the in app purchase identifier is valid.


For anyone who is sure that the App Review failure resulted from a failure by SKProductsRequest to validate the in app purchase identifiers, one suggestion is that you submit a DTS incident. DTS will review the App Review rejection response and if the failure condition appears to be caused by an SKProductsRequest failure, DTS can request a second review of the app on the newly restarted device.


rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI

In addition to requesting a review through DTS you could also do it directly with App Review.


But first - did you remember to include the IAPs with the binary somewhere in iTunes Connect (I forgot exactly where you need to do that) and might there be an issue with validating the receipt not in the production environment?

Peter makes an excellent point - the best course of action should be to first ask App Review to review the app once more and specifically request that the reviewer restart the device before doing a second review. If the app is reviewed a second time, the app should pass the SKProductsRequest. However, in some cases, an App Reviewer may still find that the problem persists, which is where DTS can be an advocate for the developer on this issue. In many cases, I've been able to secure a re-credit to the incident, but I'm not going to guarantee that this is going to happen. All DTS incidents are handled on a case by case basis.


rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI

Hey, thanks for the quick reply, advice on how to respond to App Review in the future (but your response was timely and has been more helpful than ANY correspondence I have EVER received from App Review), but I have some followup questions/comments.


> "From time to time, App Reviews of in app purchase apps

> will fail when the SKProductsRequest is made"

My first urge is to file a radar but I'm certain they will ask for a sample app and there's no way I can reproduce this error (because somehow magically it works for me after I created a new Sandbox user). I have literally lost a day or two of work when this behavior first appeared during development, and since the App Review, where I did everything they directed me to, and then to find out this is a known issue/bug that needs to be elevated by filing radars.


> "the app did not check that the identifiers were not returned

> instead assumed that they were valid and crashed"

Correct.


> "The application should check the response result

> and either alert the user if the in app purchase identifiers

> are returned as invalid, or not offer them for purchase."

Yes, I considered to check for an empty array (and looking at the invalid identifier), but I don't know how an alert would help any user who experiences this. Yes, an alert is better than a crash, but what would the alert say? "Sorry, something is wrong within the App Store and you can never upgrade this app."? The upgrade is my only IAP product. Is the alert ONLY for App Review folks? What would you say in the alert? Asking a brand new user to restart/power down a device is NOT a good user experience (if that even works) and they of course will blame my app for the issue regardless.


You said that App Review should reset their test device (they said it failed with 5 or 6 test devices!). When I first encountered the no-valid-identifier-even-though—there-is-a-valid-identifier issue in development (after I corrected a wrong product identifier in iTunes Connect), I tried powering down/resetting my iPhone, stopped/started Xcode, restarted my iMac, etc. (all several times). So after Googling, I found that others had this same issue and the only solution I found was that "test users" sometimes go "bad", so delete the "bad" user, and create a new one. That's what I did, and magically it has worked ever since with my testing and even with my archived ipa after the rejection.


> "make the SKProductsRequest once"

In my main view controller's viewDidLoad, I check a key in a shared group to see if there has been an upgrade. The product request is made only if there has not been an upgrade, and all IAP calls, e.g. addPayment, restorePurchase, are done via a singleton IAP handler in another view controller (where the cached IAP info is displayed from the singleton). I also check that setting in the action extension but do not do anything whatsoever with IAP or the IAP framework.


So, yesterday when I decided to spend even more hours looking for anything at all that could cause the issue from my end (and before your comments), I looked again at the IAP section for my app in iTunes Connect. I found a notice that said my In-App Purchase had been "returned" to me and that I had to change something (Developer Action needed). And I thought that maybe that happened before the review (or something), and so I added a space to the product description, saved it, and resubmitted the app without changing the binary.


I'm planning on another rejection in a week or two, and I would appreciate your comments on what an alert should say to real users, and how they should fix the problem from their end if that is even possible (without changing their Apple ID). Thanks.

"In response to your comments and questions -

Comment - "My first urge is to file a radar but I'm certain they will ask for a sample app and there's no way I can reproduce this error (because somehow magically it works for me after I created a new Sandbox user)."

Response - For any matter where an unexpected issue is observed I always suggest that a bug report be submitted - even if the issue can't be replicated - for example - topic - App Review reports that the SKProductsRequest fails when this does not occur when in my development release". Evidence of the issue may be impossible to provide, but if a number of developers report the same issue, the problem consideration may change from the individual occurrence to that of the volume of reports being submitted on the same issue.


Comment - "Yes, I considered to check for an empty array (and looking at the invalid identifier), but I don't know how an alert would help any user who experiences this."

Response - I would prefer an app that doesn't crash to one that does. As to what an alert might say - one suggestion - "there was a problem in connecting with the iTunes Store - Please check your connection". For example, suppose the user has connected to a WiFi network which isn't connected to the internet, this issue might happen. In addition, by providing this feedback, the App Reviewer might have taken a moment to consider that their device might have an issue. If the app crashes, this won't happen.


You then raised comments about App Review - My response - I can well understand the frustration that developers feel when encountering a situation that appears out of their hands. Something to consider - App Reviewers do want to approve apps. It's additional work on their part to reject an app. However, these issues occur. I continue to work with App Review management to suggest ways to improve their review process.


You commented - "So, yesterday when I decided to spend even more hours looking for anything at all that could cause the issue from my end (and before your comments), I looked again at the IAP section for my app in iTunes Connect. I found a notice that said my In-App Purchase had been "returned" to me and that I had to change something (Developer Action needed)."

Response - this is something better addressed by someone on the iTunesConnect team, but it appears to me, that this response occurs because the app was rejected. To my knowledge, "fixing" the issue and resubmitting the app should be sufficient, but I would review the iTunesConnect page for the state of the in app purchase identifier following the app resubmission.


rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI

You wrote: "So, yesterday .... (Developer Action needed)."


App Review needs to do something with an IAP that has not passed review. They can't approve it. If they reject it then the productIdentifier is forever lost and the binary needs to be recoded with a new productidentifier. So they do this 'developer action needed' thing. Adding the sapce and saving (and then, for completeness, removing the space and saving) works fine. I believe this confirms that the IAP was, in fact, submitted with the binary - one possible error that would cause of this problem. Actually, failing to do that 'add space thing' can cause your error on the next submission because the IAP will not appear for App Review.


Regarding the warning - I use a "Unable to find the IAP at the App Store at this time. Please try again later." That's the truth. And it will be accurate if you remove the IAP from sale for a week.

Review Crashes - Invalid Product Identifier
 
 
Q