Search code examples
iosiphoneapp-storestorekit

SKReceiptRefreshRequest not working the second time it is called after a cancel


My app starts and checks for the receipt. Because it is sandbox, the first time the app runs from Xcode, it needs to ask the App Store for the receipt. So I use SKReceiptRefreshRequest to request it.

A window pops up, asking for the App Store credentials. If I type the credentials, then the app loads the receipt, I validate it, and the app runs fine.

The problem starts if I cancel that credential window.

Then I have the first problem. At this time the app has no receipt, so I cannot validate to see if the copy is pirate. What to do? I tried the following approach: instead of disabling the application, when the user tries to use the app, I show a window saying "could not validate the application, type OK to validate now".

When the user types OK, I trigger SKReceiptRefreshRequest a second time. Again a credential window pops up, I type the valid credentials and nothing happens. After 2 or 3 minutes of nothingness, a windows pops up saying "cannot connect to App Store".

The strange part is that none request:didFailWithError: or requestDidFinish: methods of SKReceiptRefreshRequest delegate are called during this failure. Receipt retrieval fails without triggering any delegate method and yes, the delegate is assigned.

The code for the receipt retrieval is the traditional one, that is

SKReceiptRefreshRequest *refreshReceiptRequest = [[SKReceiptRefreshRequest alloc] initWithReceiptProperties:nil];
refreshReceiptRequest.delegate = self;
[refreshReceiptRequest start];

- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
  NSLog(@"ERROR");
}

- (void)requestDidFinish:(SKRequest *)request {
  if([request isKindOfClass:[SKReceiptRefreshRequest class]])
  {
    NSLog(@"App Receipt exists after refresh");
  } else {
    NSLog(@"Receipt request done but there is no receipt");
  }
}

Solution

  • Apparently this is a bug of SKReceiptRefreshRequest. If the user cancels the first credential box, the application will not able to retrieve the receipt a second time, at least not in sandbox mode. Because this will not work on sandbox mode, you cannot test and this will also not work when Apple review your app and your app will be rejected.

    Also, killing the app from the task bar will not help to make the credential box appear a second time.

    The only solution is to present an alert, telling the user to remove and download your app again from the store and to not cancel the credential box when the app asks for the apple ID/password.