Note: Update for macOS 12/Monterey and Xcode 13. For Xcode 12 and older, see this blog post.
With Monterey (macOS 12), it’s highly recommended that you notarize applications distributed over a public network. A significant number of developers transfer their applications using a connected storage device or via file-sharing; notarization isn’t required in these cases where the user already trusts the developer. Notarization aims to assure users that the application isn’t malicious and is only required for applications downloaded from a website.
Using our built-in signature feature when building your applications with 4D v18, your application is ready to be notarized. This process is conducted outside of 4D. It involves adding an electronic signature to your application and submitting your signed application to an automated inspection service. Here’s everything you need to know:
PREREQUISITES
XCODE
Notarization requires Xcode 13 or later and macOS 12 or later.
If you have more than one version of Xcode installed on your Mac, you can use the Xcode-select utility to choose the appropriate version:
sudo xcode-select -s /path/to/Xcode13.app
Even when you usually don’t use Xcode directly, you should launch it at least once. If it alerts about “Developer Tools” to download, accept it.
If it asks to confirm license conditions, accept them.
It is not a bad idea to repeat this step after installing a newer version of Xcode. Usually, you need to accept license changes; otherwise, notarization will fail.
In some cases, you need to login to https://appleid.apple.com/account/home to accept new Apple Store conditions; otherwise, notarization might fail (even if you do not want to publish to the App Store).
TWO-FACTOR AUTHENTICATION
You’ll also need to have activated two-factor authentication on your Apple ID.
If you’re not sure, you’ve set up two-factor authentication, sign in to your Apple ID account page, search for the two-factor authentication option in the Security section and see if the feature is on or off.
Process overview
A setup is required for notarization. This needs to be done only once. Then for every build, you need to zip, upload, wait for results, stamp, and zip again. And this applies to every application (Client, Server, Single User, component) and every build.
This blog post first describes every step in detail to help understand the process and finally explains how to use a 4D method to fully automate the job.
Single Time Setup
You’ll need the following for notarization:
- Your Apple ID account, usually your email
- Your Apple company team-id. See below “Get team-ids” how to retrieve it
- For an app-specific password, see below how to retrieve it
With this data, we can register the password in the key chain. This will allow us to notarize using the command line (or automatically from 4D) without providing the password in cleartext.
Generate app-specific password
- Sign in to apple.com.
- In the Sign-In and Security section, click App-Specific Passwords.
- Click Generate an app-specific password or click “+,” then follow the steps on your screen.
- You might want to name the new password “notarytool.”
- Copy the displayed code.
Get team-ids
You should have already requested and registered Apple certificates to codesign your application. There are usually two of them (four including iOS) when you do so. One starts with Apple Development: your name(user-id), the other with Developer ID Application: company name(team-id).
Launch the Apple keychain, select certificates, and check if you see Developer ID Application: company name. If yes, the number between parentheses () is your id.
If not, run the following in the Terminal:
xcrun altool --list-providers -u "AC_USERNAME" -p secret_2FA_password
replace AC_USERNAME with your Apple Account user name your email address, and enter the copied code/2FA password from above.
The Terminal will answer with your team-id.
More details here.
Store credentials
In the Terminal, run the following:
xcrun notarytool store-credentials "notarytool" --apple-id "AC_USERNAME" --team-id <WWDRTeamID> --password <secret_2FA_password>
Keep the quotes (just replace the content), but don’t use the <> signs, just the id or password.
Build / Zip / Notarize / Stamp
Now, after the (one time only) preinstallation process, it’s time to do the real build job.
Use the BUILD APPLICATION command or dialog and build your component or application. Use the certification feature to automatically sign the created application. If the build fails because of a signing error, you need to fix that first. Notarization will fail for unsigned applications.
If the component includes executables in the resource folder or the application contains components or plugins, they need to be valid, signed upfront.
Zip
When the building is finished, the next step is to zip the application:
In the Terminal, enter the following:
/usr/bin/ditto -c -k --keepParent "$APP_PATH" "$ZIP_PATH"
The easiest way to enter correct paths is to copy and paste them into the Terminal:
/usr/bin/ditto -c -k --keepParent "
Note: There is a space after keepParent and the single quote sign
Now drag and drop the application or component into the Terminal and add another quote character to get something such as:
/usr/bin/ditto -c -k --keepParent "/Users/thomas/Documents/4D/Komponenten/FileTransfer_Curl_Build/Components/FileTransfer.4dbase"
Add a space, quote character, drag and drop the target folder, then type the name of the requested zip, followed by a space.
The final line should like look this:
/usr/bin/ditto -c -k --keepParent "/Users/thomas/Documents/4D/Komponenten/FileTransfer_Curl_Build/Components/FileTransfer.4dbase" "/Users/thomas/Documents/4D/Komponenten/FileTransfer_Curl_Build/Components/FileTransfer.zip"
Press Enter to execute the command and get the zip.
Important: do not do this with other zip tools, including the Finder. To make notarization work, you need to use the ditto command.
Upload
In the Terminal, enter the following (reminder: you can drag and drop the file path to make it easier):
xcrun notarytool submit /Users/thomas/Documents/4D/Komponenten/FileTransfer_Curl_Build/Components/FileTransfer.zip --keychain-profile notarytool --wait
The answer you get is as follows:
Conducting pre-submission checks for FileTransfer.zip and initiating connection to the Apple notary service…
Submission ID received
id: 2071ae83-6660-4d84-afaf-97ea34e945c5
Successfully uploaded file
id: 2071ae83-6660-4d84-afaf-97ea34e945c5
path: /Users/thomas/Documents/4D/Komponenten/FileTransfer_Curl_Build/Components/FileTransfer.zip
Waiting for processing to complete.
Current status: Accepted…………..
Processing complete
id: 2071ae83-6660-4d84-afaf-97ea34e945c5
status: Accepted
If the status is “Invalid,” you can ask for the reason by typing:
xcrun notarytool log fb4a2e8f-e2fe-4689-b38f-f6a840abfeb6 --keychain-profile "notarytool" developer_log.json
The number behind the log is the id from the submitted answer. The last name, developer_log.json, is the name or path to a result file on your disk, chosen as you like.
It answers with:
Successfully downloaded submission log
id: fb4a2e8f-e2fe-4689-b38f-f6a840abfeb6
location: /Users/thomas/developer_log.json
Check the reason for the failure with:
cat /Users/thomas/developer_log.json
Automate the process
This job needs to be repeated for every build; it makes sense to automate it. Right? Here is everything you need to do so:
- Copy and paste the class “_build” into your application: https://github.com/ThomasMaul/Classes/blob/main/Project/Sources/Classes/_build.4dm
- Documentation: https://github.com/ThomasMaul/Classes/blob/main/Documentation/Classes/_build.md
- Example of how to use it to build Client/Server: https://github.com/ThomasMaul/Classes/blob/main/Project/Sources/Methods/Example_build.4dm
Another use case is component building. Components compiled for Silicon Macs must be notarized, making publishing components via Github uncomfortable.
The component: https://github.com/ThomasMaul/FileTransfer_Class includes a method “_buildComponent,” which compiles, builds, signs, notarizes, staples, and zips the component. All of it is automatic upon execution.
The last step is to upload the zip as “Releases” to GitHub.
Hope this tip helps you notarize your next application. Don’t hesitate to contact us on the 4D forum if you need further assistance.