0
votes

I am attempting to distribute a Catalyst app for beta testing. Since there's no Test Flight for Mac, my intent is to distribute a signed archive in order to minimize the amount warnings my users receive about running the app. I did the following:

  1. Archived for MyMac,
  2. Selected the archive from the "macOS Apps" list in the organizer,
  3. Clicked "Distribute App,"
  4. Chose "Developer ID."
  5. Selected "Upload"
  6. Selected "Automatically manage signing"

I expected it to be submitted for notarization, but instead received an error:

Provisioning profiled failed qualification. Profile doesn't include the com.apple.developer.default-data-protection entitlement.

I subsequently checked the Mac OS Provisioning profile via developer.apple.com. I have a profile that's labeled "XC OSX:" (assuming that means Xcode auto-generated) with a type field of "Developer ID Application." Sure enough, although it shows iCloud, in app purchases, etc., in the "Enabled Capabilities" section it does not have Data Protection.

But, in Xcode, when I select the target and go to "Signing and Capabilities," Data Protection is already listed. When I click the information "i" button next to the MacOS provision profile, it says com.apple.developer.default-data-protection is enabled. (it actually shows that for both the IOS and the MacOS provisioning profile).

enter image description here

Next, I looked at the Bundle Identifier on developer.apple.com and see Data Protection listed under capabilities:

enter image description here

I tried removing and re-adding Data Protection in Xcode, but the error still occurs.

I tried manually creating a Developer ID profile on developer.apple.com, but the resulting profile still lacks Data Protection.

I tried removing and re-adding Data Protection under the identifier on developer.apple.com. This successfully invalidated the existing profiles (both Xcode's and the one I created). When I again attempted signing, a new profile was created but it still lacks Data Protection and the error still occurs.

What am I missing here? What else do I have to do to enable Data Protection in the provisioning profile?

3

3 Answers

1
votes

As you figured out, the problem here is that the Data Protection entitlement is not available for MacOS.

If you still want to use this for your iOS version of the app, you need to use a different .entitlements file for your MacOS build to your iOS build.

Firstly, duplicate your current .entitlements file. The easiest way is to hold the Alt key while dragging the .entitlements file slightly. It will make a copy. Rename it to something like Original Name-MacOS.entitlements.

The next step is to open your Build Settings and type entitlements into the search bar.

You'll see your original entitlements file showing for both Debug and Release builds. Select the Debug row, then click the + button. Click on Any SDK and change it to Any macOS SDK. Now change the name of the entitlements file to your MacOS variant.

Repeat the process for the Release build so it looks like below.

enter image description here

The final step is to remove the offending entitlement from your MacOS .entitlements file. This has to be done manually as the Signing & Capabilities tab will only show the entitlements from your original iOS file. So click you MacOS .entitlements file and delete the Data Protection entry.

Clean your project, Build & Run, Export etc.. and you should be good to go.

0
votes

Burned a support ticket and found the answer. I read the message as:

You failed. You don't have Data Protection (but you need it)

But per Apple, it actually means:

You failed. You want Data Protection (because you turned it on) but don't have it (because it's not supported in this config).

So, the solution for "Data protection is missing" was... turn Data Protection off.

0
votes

On MacOS, data protection APIs are not currently functional.

If you try to use them like this,

try data.write(to: fileUrl, options: .completeFileProtection

the code will compile and execute but the data is not being stored securely on the file system.

If you need to store data securely, there are several options available to you. Passwords and related data can be stored in the Keychain and FileVault will encrypt all of the files on the disk transparently.

But if that's not sufficient for your needs. You can use the AES.GCM encryption API in CryptoKit to encrypt your content before writing it to disk.

let key = SymmatericKey(size: .bits256)
let sealed = try AES.GCM.seal(data, using: key)

Source: WWDC 2019 Introducing iPad Apps for Mac