@Thomas Tempelmann Its exactly what Im doing.
- Its an in-app purchase
- After they buy it they have to explicitly ask to install it
- The app launch the screensaver and the installation is processed by macOS, which also ask the question
The reviewer made it clear that installing from the app is forbidden (guidelines 2.4.5(ii).
The guideline says “cannot install code or resources in shared locations” - that’s probably the rule you’re breaking, as you said you’re opening the saver so that it gets installed, i.e. copied somewhere else.
Now, at least with other kind of helpers in an app bundle, they do NOT need to be copied (i.e. installed), because macOS automatically finds them inside your app bundle and can use them from there. That’s true for spotlight importers and login items, for instance.
Are you sure your saver can’t run from inside the app? Maybe you tried to install it on wrong assumptions that you need to do so? Otherwise, have you looked for help in the apple forum or on StackOverflow about embedding screen savers in your app?
Oh – but even if I am right - you don’t want that. You want to allow access to the saver only after the IAP. And that requires hiding the saver initially (so that it’s not automatically accessible) and then copy it somewhere else so that it can be used. Tricky.
No they can’t.
Screen savers are now kind of plugins that are ran by ‘legacyScreenSaver’.
of course I did, not helpful
I don’t have to hide it, it will show ‘buy screensaver’ as long as they don’t buy the IAP.
I’m now trying to sign and notarize the screensaver separately and let the user save it (via save dialog) where he wants before installing manually.
Out of curiosity: How do you prevent a user from simply opening it from your app bundle, without paying for it, then? Is the saver’s code checking your main app’s receipt to tell that it’s been paid for? If so, how do you locate the correct copy of the main app? By using launch services?
I’m using an application group container in both the app and the screensaver. There’s a file in this container containing a flag set by the IAP purchase or restore process in the app.
If the flag is not set the screensaver just ask to buy the IAP.
Ah, thanks. I had not known it could work like that.
I have no experience with group containers (nor sandboxing, as all my apps in the MAS are not sandboxed). Does that mean that there’ll be a folder named after the group inside the user’s Library/Containers folder, and the App Store stores the receipt (or is there a special IAP file for this?) there, instead of in the app’s bundle as it usually happens? And I assume you still have to parse the IAP receipt yourself to check for this flag? Or are there macOS framework functions for this by now (it’s been 9 years since I handled receipts).
The folder will be in the user’s Library/Group Containers
No. And in fact I don’t store or process receipts. I only check that buying (or restoring) IAP succeeded and set a flag in a kind of preferences file within the group container.
I’m using MBS StoreKit (in MBS MacCloud Plugin).
Thanks for sharing, Olivier. I do something similar in Find Any File to allow people who purchased the app in the MAS to use the “indie” versions, such as betas, from my website: The MAS version sets a flag in the prefs that the user has purchased it, and then the indie version doesn’t ask again for a purchase.
An in iClip, I store the actual MAS receipt in the App Support folder, so that the indie version of iClip can validate it, too.
That makes it possible that users test my betas even if they purchased the app in the MAS.