appStoreReceiptURL on mainBundle always returns nil

This method appStoreReceiptURL is the replacement for the deprecated transactionReceipt method on SKPaymentTransaction. And everyone says to just use this call instead:

NSURL *theURL = [[NSBundle mainBundle] appStoreReceiptURL];

This is supposed to return a url to a receipt if there is one. But for me there isn’t one, as this value is nil, and as far as I can tell it shouldn’t be. I’m running on iOS 7 and have done a few in-app purchases (sandbox on the device). Now I’m trying to add another in-app purchase, an auto-renewing subscription, and I need to dig into the receipt to get the subscription expiration date. But I can’t get past this simple step because the value is simply always nil.

  • NSFetchedResultsController is loading all rows even through I have batch set
  • Change Height of UISegmentedControl
  • cannot assign to immutable expression of type anyobject
  • How to wait in NSThread until some event occur in iOS?
  • How to add regular string placeholders to a translated plurals .stringdict in swift ios
  • Can't put a single quote before the year in NSDateFormatter
  • Does anyone know why?

    2 Solutions Collect From Internet About “appStoreReceiptURL on mainBundle always returns nil”

    A bit late, but it may be of use to someone:

    -(void) someMethod {
        NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
        if ([[NSFileManager defaultManager] fileExistsAtPath:[receiptUrl path]])
        {
    
            NSData *ios7ReceiptData = [NSData dataWithContentsOfURL:receiptUrl];
            //Do stuff
    
        } else {
            NSLog(@"iOS 7 AppReceipt not found %@, refreshing...",iapID);
            SKReceiptRefreshRequest *refreshReceiptRequest = [[SKReceiptRefreshRequest alloc] initWithReceiptProperties:@{}];
            refreshReceiptRequest.delegate = self;
            [refreshReceiptRequest start];
        }
    }
    
    - (void)requestDidFinish:(SKRequest *)request {
        if([request isKindOfClass:[SKReceiptRefreshRequest class]])
        {
            //SKReceiptRefreshRequest
            NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
            if ([[NSFileManager defaultManager] fileExistsAtPath:[receiptUrl path]]) {
                NSLog(@"App Receipt exists");
                //Do stuff
            } else {
                NSLog(@"Receipt request done but there is no receipt");
    
                // This can happen if the user cancels the login screen for the store.
                // If we get here it means there is no receipt and an attempt to get it failed because the user cancelled the login.
                //[self trackFailedAttempt];
            }
        }
    }
    

    `

    It’s now iOS 8.4 and Xcode 6.4 so maybe history is different, but I find this method call always returns nil when running in the simulator. On a real device it works as documented by Apple: The path to where the app receipt is intended to be stored is returned — with no guarantee that either there is a receipt there nor that it is a valid receipt.