Modern Code for Mac App Store

Please forgive me, but I’m tearing my hair out with this.

I have an old project that was on the Mac App Store. For a variety of reasons, that project was not updated for a number of years. However, I have finally been able to spend some time on the project to update for Big Sur/M1 compatibility and am working on getting it resubmitted to the App Store.

The project builds and code-signs correctly (using App Wrapper 4.2.1). Awesome! However, when I test my installer package, my receipt-checking code is failing with a NilObjectException. I have not touched this code since 2017, at least and it worked fine then. I have to assume that something has changed since then that my code is not accounting for. I am using code to test the App Store receipt that uses MBS.

I’ve done many searches—both of this forum—and with Google and I can’t find anything in recent years that doesn’t refer to MacOSLib, MBS (which I was using) or Sam Rowlands’ ReceiptTester, which doesn’t seem to be publicly available anymore.

Here is the code I was using to test the receipt:

dim a as new AppReceiptVerificatorMBS
dim f as FolderItem = app.ExecutableFile.Parent.Parent.Child( "_MASReceipt" ).Child( "receipt" )

if f = Nil then
  Valid = False
  declare sub exit_ lib "System" alias "exit" ( code as Integer )
  exit_ ( 173 )
  dim r as AppReceiptMBS = AppReceiptMBS.receiptForFile(f)
  a.bundleIdentifier = kBundleIdentifierAppStore
  a.bundleVersion = App.ShortVersion
  if a.verifyReceipt(r) then // <-- NilObjectException is happening here.
    // App Store receipt is valid.
    Valid = True
    // App Store receipt is invalid.
    Valid = False
    declare sub exit_ lib "System" alias "exit" ( code as Integer )
    exit_ ( 173 )
  end if
end if

Any thoughts as to what I’m doing wrong?

Thank you!

Idea #1: It appears you aren’t checking if the file exists, only nil. It’s possible the receipt file is missing.

Idea #2: You aren’t setting Apple’s Root Certificate, which is a file you download from Apple PKI - Apple (“Apple Inc. Root Certificate”) and include in your Resources folder, and set it with:

AppReceiptMBS.setAppleRootCertificate(File as FolderItem)

Function: Sets the file of the Apple Root certificate that will be used to verifiy the signature of the bundle receipt.
If none is provided, the resource AppleIncRootCertificate.cer will be used. If no certificate is available, no signature verification will be performed.
file: The folderitem of the Apple Root certificate.

1 Like

Make sure the application is in the “Applications” folder and was signed with the App Store identities.

When you loop through is “a” or 'r" nil?

I apologize for the delay in my response. I ended up working 65 hours at my “day job” this past week and haven’t had the time or energy to come back to this until this evening.

Idea 1- You are right. I wasn’t checking if the file existed. Shame on me for that. The interesting thing is, as I said, that’s the same code that’s been in place since at least 2017. Never heard of an issue with it otherwise. But, that said, I went ahead and checked to see if f.Exists.

Idea 2- I’m going to go ahead and completely admit my ignorance here. The code I posted above has worked fine for years. I’ve never set Apple’s Root Certificate before (although I have it). Is this a newer requirement in the last few years?

However, all this got me thinking. I went and checked the copy of my application that was installed in /Applications by the .pkg (using sudo installer -store -pkg -target /) and I see that there was not a “_MASReceipt” folder in the App Bundle. That would explain the NilObjectException I was getting (and why it’s important to check to see if the file exists :slightly_smiling_face:). I don’t know why I didn’t think to check this before. This should have been one of the first things I checked.

So, I deleted the copy of my app from /Applications and tried installing again (from the same .pkg as before). Same problem.

So, I built a new copy of the app (with the only change being adding the f.Exists check). Ran it through App Wrapper 4. Installed with the new .pkg and it works exactly as expected! I also double-checked and the _MASReceipt folder is in the App Bundle.

So, I’m not sure what happened. I can’t imagine just adding the f.Exists check would change how the .pkg installer works. Maybe something just went wrong the first time.

I’m still very interested in hearing about the Root Certificate thing though. If this is something I should be paying attention to going forward, I’d like to better understand.

Thank you for your suggestions!

1 Like

As I said in my response to Jason_Cox, it ended up being “r” that was Nil because the _MASReceipt folder wasn’t in the App Bundle. I added in a f.Exists check to catch for that. But, I’m not sure why that folder wasn’t there in the first place.

1 Like

The trouble is, the process is opaque and automatic.
Unless you have console open and capturing any messages relate to your app at the time, it can be very difficult to see if any of the various Apple frameworks involved in this process, might have logged an issue, with an even slimmer chance that it may have logged the reason, and an even slimmer chance that reason isn’t <private/>.

When troubleshooting an App Store issue last summer, I ended up sending 18GB of log data to Apple, it took the engineer nearly a whole day to see the one important line, which basically proved what I was saying, was actually happening. There was not any data recorded to explain why it was failing, just that it was.

It then took nearly 3 months for the issue to be fixed.

Forum for Xojo Programming Language and IDE. Copyright © 2021 Xojo, Inc.