How to upload a macOS app that contains ANEs to the Mac store
- Download the air SDK
- When it is still in the download folder unlock the security restriction on the SDK by running this commant on terminal:
xattr -dr com.apple.quarantine ~/Downloads
This will remove the quarantine flag from all files in Downloads.
If not, you will get this error while running adt comands:
"naip" can't be opened because apple cannot check it for malicious software.
this software needs to be updated. contact the developer for more information.
Safari downloaded this file today at 23:45
show in finder --- OK
For more info:
https://hiringengineersbook.com/post/disable-quarantine/
- Now copy the Air SDK folder to the Applications folder or else you will
get this error message when running the adt commands:
Error: Unable to access jarfile ./../lib/adt.jar
- Install the right certificates on your system:
A. Some certificates, like the Developer ID certificates has to have an intermediate certificate to back it up, and the intermediate certificate has to have a root certificate to back it up, the certificates are chained to one another, each is drawing its authentication from the other, so you have to download all the additional certificates that go along with your certificate and install them on your mac computer. They are listed on Apple developer website on the bottom when you start the process of creating a new certificate, pay attention and write them down, to download them.
B. Every certificate has to have a privet key attached to it in the keychain, check to see every certificate you plan on using has one.
- Check to see what certificates are registered on your mac system:
use this command line on Terminal:
security find-identity -p basic –v
Put your AppName.swf file and the AppName-app.xml file (the descriptor file) in a folder we are going to work on. let's call this folder "Mac". If your project is on Flash Builder you can find the swf file in the "bin-debug" folder. You can also find the AppName-app.xml file in this folder but this is not the one you want to use. Take the AppName-app.xml that is located in the "src" folder located in your project, but you have to add the name of the swf file to it, in this line:
<content>[This value will be overwritten by Flash Builder in the output app.xml]</content>
Change it to this:
<content> AppName.swf </content>
Now copy it to the "Mac" folder, and copy to the same folder all the folders in your project you need for the build, like:
ane, assets, icons etc.
Add to the "Mac" folder 2 provision profiles. You have to create these provision profiles on Apples site, one for development and one for distribution:
AppName_mac_dev.provisionprofile
AppName_Mac_Dis.provisionprofile
To created these provision profile you have to have a Mac Development certificate for macOS platform, and a Mac App distribution certificate for macOS platform. You might as well create a Mac Distribution Installer certificate for macOS platform, we will need this certificate later to create the package for the app.
You could use an air file created by Flash Builder on a Windows system, copy it to a Mac computer, and use it to make the MacOS application like this:
Put the air file in a folder and open this folder in Terminal, run this command to create the macos app:
bash /Applications/AIRSDK_MacOS/bin/adt -package -target bundle AppName.app AppName.air
But this only works if your app doesn't contain ANEs. Air files cannot contain ANEs so if you need to use ANEs in your application you have to create the app from a swf file with an adt command on a Mac computer.
In the "Mac" folder Create a mac batch file named "build_dev.command". This file will be a batch file you execute by double clicking on it, on your mac computer to create a developer version of your app. The content of the file should be:
#!/bin/bash
cd "$(dirname "$BASH_SOURCE")" || {
echo "Error getting script directory" >&2
exit 1
}
bash /Applications/AIRSDK_MacOS/bin/adt -package -storetype KeychainStore -alias "3rd Party Mac Developer Application: CompanyName, Inc. (XXXXXXXXX)" -target bundle -provisioning-profile AppName_mac_dev.provisionprofile -storetype KeychainStore -alias "3rd Party Mac Developer Application: CompanyName, Inc. (XXXXXXXX)" "AppName.app" AppName-app.xml -extdir ane AppName.swf assets sounds classes data icons
Of course you have to change the names of the company and the application name, in the command line, to match your app and company names. The company name is part of the certificate name so copy it from the list of certificates installed on your system, you get when running the command line: security find-identity -p basic –v on terminal.
Every time you double click this batch file it will automatically create the developer version of your app, so you can do your testing on it, but you have to:
Install the provision profile on your mac computer by double clicking on the provision profile you downloaded from Apple site.
Right click on the "Mac" folder that is now on your mac computer, and select services on the bottom of the menu, then select "New Terminal at Folder", you only have to do this once on every folder, to make the batch files in this folder run when you double click them.
Now create a batch file to create a Distribution app you can upload to the App Store or sell directly to users. Put this batch file in the "Mac" folder and call it "build_dis.command", the content of the file should be:
#!/bin/bash
cd "$(dirname "$BASH_SOURCE")" || {
echo "Error getting script directory" >&2
exit 1
}
bash /Applications/AIRSDK_MacOS/bin/adt -package -storetype KeychainStore -alias "3rd Party Mac Developer Application: CompanyName, Inc. (XXXXXXXXX)" -target bundle -provisioning-profile AppName_Mac_Dis.provisionprofile -storetype KeychainStore -alias "3rd Party Mac Developer Application: CompanyName, Inc. (XXXXXXXXX)" "AppName.app" AppName-app.xml -extdir ane AppName.swf assets sounds classes data icons
- Once you have the app created with the adt command open the app content folder
Add the following lines to the Info.plist file, after the <key>NSHumanReadableCopyright</key> entry
<key>CFBundleDisplayName</key>
<string>App Name</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.education</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
Of course, you should select the right category for your application, and replace "App Name" with your app name.
Now for the signing process and creating a package file.
There are 2 channels in which you can sell a product, either on the app store or you deliver it to your clients directly, in the latest case you only have to pass the gatekeeper software that blocks unrecognized application from installing on a Mac system.
We will create 2 folders inside the "Mac" folder, in one of them we will put all the batch files needed to sign the distribution app we have previously created, and package it, and verify it before we upload it to the app store. In the other folder we will put all the batch files we need to sign the distribution app we have previously created, so that it can be sold outside the app store.
We will call one folder: "pkg - App Store", and the other "pkg - free selling".
In both folders we need to put a file named: app.entitlements containing this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>
- Now we add a group of batch files, we are about to create, to the folder "pkg - App Store":
We will start with a batch file, which is signing the developer version of the app. I don't know yet, how to test the in-app-billing process with a MacOS app. With an iOS app it is easy, once you create it, and sign it with a developer certificate, and a developer provision profile, it automatically running on the sandbox environment, so you can test the purchasing process, without doing an actual purchase.
Run the batch file that creates a developer version of your app: "codesign-Dev.command", and once the app is created, put it in the "pkg - App Store" folder.
The content of the "codesign-Dev.command" batch file should be:
#!/bin/bash
cd "$(dirname "$BASH_SOURCE")" || {
echo "Error getting script directory" >&2
exit 1
}
codesign --entitlements app.entitlements -f --options runtime --strict --timestamp -v -s "Mac Developer: YourName (XXXXXXXX)" --deep "AppName.app"
Double click the batch file and it will sign your developer app. Now you can run the app to test it, but once you are done, delete it, because if you don't, and you install the packaged version, it will install it in the same folder where your app is currently saved. To make the package install it in the Application folder, as it should, you need to delete all the instances of the app from other folders.
Test your developer app until you are sure everything works fine. Now create a distribution app on the "Mac" folder, by running "build_dis.command" batch file, and fixed the Info.plist file as shown before.
Move the distribution application you have created to "pkg - App Store" folder. The previous developer version of the app will be overwritten, because it has the same name.
Now sign the app.
Create a new batch file, in the pkg - App Store" folder, for signing a distribution app, call it: "codesign-Dis.command". this is the file content:
#!/bin/bash
cd "$(dirname "$BASH_SOURCE")" || {
echo "Error getting script directory" >&2
exit 1
}
codesign --entitlements app.entitlements -f --options runtime --strict --timestamp -v -s "3rd Party Mac Developer Application: CompanyName, Inc. (XXXXXXXXX)" --deep "AppName.app"
Double click the distribution signing batch file you created and let it sign the distribution version of your app.
- Now we will create a batch file, in the pkg - App Store" folder, that creates a package file for your application, and can be uploaded to the app store. The package file has to be signed with a different certificate then the application it contains. You need to create an installer certificate and install it on your mac. Call the packaging batch file "productbuild.command", and this is its content:
#!/bin/bash
cd "$(dirname "$BASH_SOURCE")" || {
echo "Error getting script directory" >&2
exit 1
}
productbuild --component "AppName.app" /Applications --product "AppName.app/Contents/Info.plist" --sign "3rd Party Mac Developer Installer: CompanyName, Inc. (XXXXXXXXX)" "AppName.pkg"
- Now before you upload your app to the app store you want to validate it, to make sure it will be accepted, and in case it will not, you want to know in details what needs to be fixed. To do that you create a new batch file, in the pkg - App Store" folder, called: "validate.command", this is its content:
#!/bin/bash
cd "$(dirname "$BASH_SOURCE")" || {
echo "Error getting script directory" >&2
exit 1
}
#xcrun altool --validate-app -f --verbose "AppName.pkg" -t macos -u YourAppleAccountUser@gmail.com --password XXX-XXX-XXXX-XXX
xcrun altool --validate-app -f "AppName.pkg" -t macos -u YourAppleAccountUser@gmail.com --password XXX-XXX-XXXX-XXX
The first version of this command is commented because it is the one that gives you much more details and you might not need too many details at first, to figure what is wrong, but in case you do need a higher level of details, you comment the second command line and uncomment the first command line.
The password used in this batch file is called "App Specific Password".
You generate an app specific password by going to:
https://appleid.apple.com/account/manage
Click on app-specific passwords
Generate an app specific password
Use it in the command line.
Once the app is validated you can upload it to the mac store with the Transporter app.
In case you want to take the other path, of creating a package file you can distribute directly to the client without the app store:
Create a distribution app as described previously, and put it in the "pkg - free selling" folder.
Put the app.entitlements file, in the "pkg - free selling" folder.
On Apple site create a Deverloper ID Application certificate, for macOS platrom, and a Deverloper ID Installer certificate, download these certificates and install them on your mac computer.
Create a batch file, in the "pkg - free selling" folder, and name it: "codesign Dev ID App.command". The content of this file is:
#!/bin/bash
cd "$(dirname "$BASH_SOURCE")" || {
echo "Error getting script directory" >&2
exit 1
}
codesign --entitlements app.entitlements -f --options runtime --strict --timestamp -v -s "Developer ID Application: CompayName, Inc. (XXXXXXXXX)" --deep "AppName.app"
Run this batch file to sign the distribution App.
- Create a package file for the app by creating a new batch file, in the "pkg - free selling" folder, named: "productbuild Dev ID Ins.command", the content is:
#!/bin/bash
cd "$(dirname "$BASH_SOURCE")" || {
echo "Error getting script directory" >&2
exit 1
}
productbuild --component "AppName.app" /Applications --product "AppName.app/Contents/Info.plist" --sign "Developer ID Installer: CompanyName, Inc. (XXXXXXXXX)" "AppName.pkg"
Run this batch file by double clicking on it, with the app signed and in the same folder. You will get a new *.pkg file in the folder.
- Now you need to notarize the pkg file so it will not be stopped by the gatekeeper on the mac computer you want to install it on. Create a batch file that does the notarization, in the "pkg - free selling" folder, call it: "notarize.command".
The content is:
#!/bin/bash
cd "$(dirname "$BASH_SOURCE")" || {
echo "Error getting script directory" >&2
exit 1
}
xcrun altool -type osx --notarize-app --primary-bundle-id com.XXXXXXX.AppName --username AppleAccountName@gmail.com --password XXXX-XXXX-XXXX-XXXX --file "AppName.pkg"
Run it, and wait until you get a message in your email box, notifying you that the app was notarized successfully.
The app is ready for independent distribution.
: