Copy link to clipboard
Copied
Has anybody put together a tutorial on publishing a Flex/AIR application for distribution as an OSX desktop app, either through Mac App Store or just using the Developer ID certificate?
In my time as a Flex developer, I've seen some things documented well and some that you had to dig for, but finding clear instructions on this is really difficult! I would have thought publishing your Flex/AIR app as a stand-alone (captive runtime) application either through the Mac App Store or to users directly (signing with an Apple Developer ID certificate) would be something many people are trying to do. But most of the helpful posts out there are dated or incomplete as well as being specifically targeted towards iOS. Furthermore, each time the AIR SDK changes it seems many of the past posts are no longer valid at some step.
Big thanks for anybody who can provide pointers or suggestions!
I have it working!!! Woooohoooo!
DHL83's correspondence with Apple and reference to the Electron thread on Apple's Developer support site provided me with some ideas for googling whether entitlements could be added for apps produced by 3rd party tools such as the Flex SDK. After a lot of trial-and-error, I worked out what entitlements are required.
Here are the steps in addition to the signing script I posted above:
1. You need to create an Entitlements file which will look like this:
<?xml vers
...Copy link to clipboard
Copied
The official doc page on Mac App Store submission was updated just over two months ago given some recent changes needed in recent SDKs:
http://helpx.adobe.com/flash-player/kb/posting-air-app-mac-app.html
It should be current, though I think I see a typo in one of the commandline calls that mentions 'textcodesign' when it should just be 'codesign'
Copy link to clipboard
Copied
Thanks for the link Jeffrey. Good resource, although I wish it had more detail for the slower devs like me not completely familiar with the process of packaging for OSX.
When you publish your .app with captive runtime do you use the same Apple certificate (that you later use with codesign)?
Copy link to clipboard
Copied
Yes, you typically would to be safe, though I think technically the process of actually using codesign later again on the commandline (after removing and modifying some .app files) essentially acts as a re-signing of the app and replaces any previous use of certificates you would have done during the publish of the app.
Copy link to clipboard
Copied
Ok, thanks Jeffrey, I'll give that a shot. I'm actually trying to do this process with a Developer ID, i.e. not for App Store but rather for general distribution but in accordance with Gate Keeper. Please do post any tips if you think of them and have time. Many thanks.
Copy link to clipboard
Copied
The official doc resource mentioned by Jeff helps, but is not specific to publishing your app with a Developer ID for distribution outside the Mac Store. What parts of this step should change for Developer ID? Hmm...
So I found another posting in the forum that suggests signing your app in the following way:
codesign -f -v -s "Developer ID Application: Company Inc" "Install My App.app/Contents/Resources/MyApp/Contents/MacOS/MyApp"
codesign -f -v -s "Developer ID Application: Company Inc" "Install MyApp.app/Contents/MacOS/Install MyApp"
codesign -f -v -s "Developer ID Application: Company Inc" "Install MyApp.app"
where the switches used are (from the codesign docs) :
-f, --force
When signing, causes codesign to replace any existing signature on the path(s) given. Without
this option, existing signatures will not be replaced, and the signing operation fails.
-v, --verbose
-s, --sign identity
Sign the code at the path(s) given using this identity. See SIGNING IDENTITIES below.
So immediately you're asking yourself
- what happened to the 'entitlements' arguments mentioned in the official Adobe doc?"
- the path "Install My App.app/Contents/Resources/MyApp/Contents/MacOS/MyApp" doesn't look like a valid path. My swf lives at MyApp.app/Contents/Resources/MyApp.swf, there is no Contents subdirectory at this level."
- why sign three different times?
- what about my 'installer' certificate?
More grist for the mill can be found in this forum posting, where a user posts his build script for signing a Flex/AIR desktop app for the Mac App Store
cp Info.plist myapp.app/Contents
cp Icon.icns myapp.app/Contents/Resources
rm myapp.app/Contents/Frameworks/Adobe\ AIR.framework/Versions/Current/Resources/WebKit.dylib
codesign -f -v -s "My name" myapp.app/Contents/Frameworks/Adobe\ AIR.framework
codesign -f -v -s "My name" myapp.app/Contents/Frameworks/Adobe\ AIR.framework/Versions/1.0/Resources/AdobeCP15.plugin
codesign -f -v -s "My name" myapp.app/Contents/Frameworks/Adobe\ AIR.framework/Versions/1.0/Resources/Flash\ Player.plugin
codesign -f -v -s "My name" myapp.app/Contents/Frameworks/Adobe\ AIR.framework/Versions/1.0/Resources/adobecp.plugin
codesign -f -v -s "My name" --entitlements entitlements.plist myapp.app
productbuild --component myapp.app /Applications myapp.pkg --sign "My name"
But ..sigh...once again we non App Store believers are left out. Which steps are relevant and don't we need to sign the file in Contents/MacOS/ like in the first post? Also, here the user is signing AdobeCP15.plugin and adobecp.plugin, which according to the official doc can be deleted if you're not using DRM.
I'll report back when I find out more...
Copy link to clipboard
Copied
For a native installer this approach may work.
However we currently use an Air installer instead, which creates the myapp.app during install.
I tried signing my installer but this doesn't reflect on the installed application.
Signing the app after it has been installed with codesign works, but this is not a solution.
Is it possible to sign your application during installation with badge install or air installer on OSx?
Or is a native installer the only solution?
Copy link to clipboard
Copied
Hi Vincent,
Not sure about that. Not being able to sign the AIR installer (and thus having troubles with GateKeeper) is one of the reasons I'm trying to get this native build working.
What follows is the current state of my build script for trying to make an .pkg installer for my captive runtime .app (as exported by Flash Builder) in a way that makes GateKeeper happy. Because GateKeeper wants to be happy.
#REMOVE ALL NON-NECESSARY FILES
# Not needed if you're not using DRM, so remove the following to reduce file sice (per Adobe doc)
rm MyApp.app/Contents/Frameworks/Adobe\ AIR.framework/Versions/1.0/Resources/Adobe\ AIR.vch
rm MyApp.app/Contents/Frameworks/Adobe\ AIR.framework/Versions/1.0/Resources/adobecp.plugin
rm MyApp.app/Contents/Frameworks/Adobe\ AIR.framework/Versions/1.0/Resources/adobecp.vch
rm MyApp.app/Contents/Frameworks/Adobe\ AIR.framework/Versions/1.0/Resources/AdobeCP15.plugin
# Don't need webkit and if we ever publish to the Mac Store we can't have it included
rm MyApp.app/Contents/Frameworks/Adobe\ AIR.framework/Versions/1.0/Resources/WebKit.dylib
# SET PERMISSIONS
#Per this article: http://pigsels.com/2012/04/air-app-store-publishing-guide/
echo -e " Setting permissions ..."
chmod -R 777 MyApp.app/
# SIGN PARTS
echo -e "\n Signing AIR.framework ..."
codesign -f -v -s "Developer ID Application: (My Company)" MyApp.app/Contents/Frameworks/Adobe\ AIR.framework/Versions/1.0
echo -e "\n Signing Flash Player.plugin ... "
codesign -f -v -s "Developer ID Application: (My Company)" MyApp.app/Contents/Frameworks/Adobe\ AIR.framework/Versions/1.0/Resources/Flash\ Player.plugin
#Do I need this part?
#echo -e "\n Signing Contents/MacOS/MyApp ..."
#codesign -f -v -s "Developer ID Application: (My Company)" MyApp.app/Contents/MacOS/MyApp
#Final part..sign the actual .app file
echo -e "\n Signing MyApp.app ..."
codesign -f -v -s "Developer ID Application: (My Company)" MyApp.app
#BUILD INSTALLER
echo -e "\n Creating installer..."
productbuild --component MyApp.app /Applications MyApp.pkg --sign "Developer ID Installer: (My Company)" --identifier "MyApp" --version "3.0.0"
This is giving me an installer that at first blush seems to work.
However, still wrestling with a couple issues:
- How to use a distribution.xml to customize the look of the final installer. This probably means understanding better how productbuild works...
- Wondering if I still need to add and configure an entitlements file even though I'm not submitting to the Mac App Store (just yet).
FWIW,
Daniel
Copy link to clipboard
Copied
Hello Daniel,
Thanks for the reply.
For another app we are already using native installers.
I don't have the exact details for you, but this is what the build script does in general.
- Build air application
- Package app in dmg installer
- Sign the application executable inside the dmg with our "Developer ID Application: (My Company)" certificate.
Gatekeeper will then accept the installation, except for the warning that the app was downloaded from the internet.
We also do not plan to release it to the app store.
- Vincent
Copy link to clipboard
Copied
Hi, are their any updated steps for this? I'm trying to do exactly what you are doing -- publish a Mac app outside the App Store that is Gatekeeper-approved -- but I'm still having trouble. I'm doing everything noted above and it looks like it works, but when I test it, Gatekeeper flips out and says the file is damaged and should be trashed. Any current info would be greatly appreciated!!
Copy link to clipboard
Copied
This is the best post on this issue I could find in the Adobe Forums, kudos DMcQ!
That being said, I concur with the other commenters. There are still way too many loose and outdated suggestions. Adobe sorely needs to step up and produce something comprehensive, something far better and more up-to-date than the Post Adobe AIR app to Mac app store page. AIR developers need two detailed documents with explicit environment/SDK version details:
1) Packaging an OS X Adobe AIR app for independent distribution
2) Packaging an OS X Adobe AIR app for Mac App Store distribution
I am struggling to properly codesign my OS X AIR app for independent distribution and have not yet succeeded in creating an app bundle that passes a clean circa OS X 10.9.5 v2 certificate Gatekeeper test: spctl -a -t exec -vv Foo.app.
This returns one of the following, depending one what approach I take:
- rejected
- nested code is modified or invalid
- a sealed resource is missing or invalid
Just some of the many questions and concerns I have regarding some provided suggestions in this manual re-packaging and codesign process:
- Doesn't removing contents of the bundle after it is built invalidate the included resources and jeopardize subsequent codesigning?
- Performing a brute force chmod -R 777 MyApp.app seems to set the executable bit on enclosed items willy-nilly which seems counterproductive.
- What exact enclosed items need to be codesigned (directories, plugins, binaries), and in what order?
- What about non-App Store distributed applications that need to rely on WebKit?
- What about sandboxing entitlements?
- If entitlements need to be created, provide examples on typical AIR application entitlements and how to craft the file.
- Should the codesign --preserve-metadata option be used, and if so, with what parameters?
- Doesn't AIR 15 [latest beta] support the large icon sizes in the application descriptor and obviate the need to manually edit the icns file?
Copy link to clipboard
Copied
I wish I could say I got my process to work, but I'm stuck here with the same issues you're seeing, stolennickname. Since I can't figure this out myself, I'm wondering who to turn to. Seems like nobody knows exactly how to make an AIR captive runtime app work on OSX without the GateKeeper silliness.
Couple that with spctl's almost mystic "a sealed resource is missing or invalid" message which makes me want to shout "WHICH?!!" so I can at least start to figure out what's happening.
I'm hoping against hope that somebody comes out with an article or blog post that details exactly what you need to do to take your captive runtime .app and make it run without issues.
Copy link to clipboard
Copied
This will either be a lot of repeated info or cryptic (because they are my personal notes), but these are the steps that I use for getting CameraSim to work with OSX Gatekeeper:
Hope that helps. Good luck...I feel lucky every time I get through this mess.
Copy link to clipboard
Copied
Thanks JonArnold, these are some excellent detailed steps!
For other struggling through this, here is some additional vital information about certificates I've discovered through exhaustive reading on Apple's developer site. Changes in OS X 10.9.5 mandate some measures that aren't reflected in most guidelines for packaging and codesigning, including Adobe's post linked above, and all the other links.
It turns out that there is a different type of certificate for signing apps for submission to Apple for Mac App Store distribution than the certificate needed for independent distribution. Despite the fact that some of Apple's documents say that certificates issued by legitimate third parties can be used for codesign, despite the fact that a certificate can pass internal certification and be marked OK for codesign in Keychain Access, it seems that only a proper certificate issued from Apple's developer program will do the trick.
For submission to Apple for distribution to the Mac App Store, you will need to manually codesign your AIR app properly using a Mac App Distribution certificate. In Keychain Access, this certificate will have a "3rd Party Mac Developer Application:" prefix.
For independent distribution, you will need to manually codesign your AIR app using a Developer ID Distribution certificate. In Keychain Access, this certificate will have a "DeveloperID Application:" prefix.
Tip: Because of very inconsistent labeling of certificates (differing names in the online portal, filename when downloaded, name in Xcode, name in Keychain Access), I recommend clearly renaming downloaded .cer certificates by appending a clear description as well as the date of expiry to match that in the development portal.
When performing a manual codesign on an app destined for Mac App Store distribution, spctl and Gatekeeper will reject the resulting app! It is only after Apple approves your submission and publishes the app on the Mac App Store that it will pass spctl and Gatekeeper test.
I’m still getting our development team setup for the Developer ID provision and will report back with details when I go through this process.
Copy link to clipboard
Copied
I'm also struggling with this - trying to build an installer for independent distribution. There are some non-AIR posts about difficulties signing with 10.9.5, which led me down the path of trying to sign the components, as well as app, then package. I'm still not having success. I suspect the problem is with Apple, but there's got to be a way around it... My attempt includes the following, maybe something here triggers someone else to make progress. Feels like we're all stumbling around in the dark together!
Sign everything in sight, even some things twice (order is important here for AdobeCP)...
sudo codesign -fv -dv -s "Developer ID Application: CompanyName" "CompanyApp.app/Contents/Frameworks/Adobe AIR.framework/Versions/Current/Resources/Flash Player.plugin"
sudo codesign -fv -dv -s "Developer ID Application: CompanyName" "CompanyApp.app/Contents/Frameworks/Adobe AIR.framework/Resources/adobecp.plugin"
sudo codesign -fv -dv -s "Developer ID Application: CompanyName" "CompanyApp.app/Contents/Frameworks/Adobe AIR.framework/Resources/Flash Player.plugin"
sudo codesign -fv -dv -s "Developer ID Application: CompanyName" "CompanyApp.app/Contents/Frameworks/Adobe AIR.framework/Versions/1.0/Resources/adobecp.plugin"
sudo codesign -fv -dv -s "Developer ID Application: CompanyName" "CompanyApp.app/Contents/Frameworks/Adobe AIR.framework/Versions/1.0/Resources/Flash Player.plugin"
sudo codesign -fv -dv -s "Developer ID Application: CompanyName" "CompanyApp.app/Contents/Frameworks/Adobe AIR.framework/Versions/Current/Resources/adobecp.plugin"
sudo codesign -fv -dv -s "Developer ID Application: CompanyName" "CompanyApp.app/Contents/Frameworks/Adobe AIR.framework/Resources/AdobeCP15.plugin/Contents/MacOS/AdobeCP"
sudo codesign -fv -dv -s "Developer ID Application: CompanyName" "CompanyApp.app/Contents/Frameworks/Adobe AIR.framework/Resources/AdobeCP15.plugin"
sudo codesign -fv -dv -s "Developer ID Application: CompanyName" "CompanyApp.app/Contents/Frameworks/Adobe AIR.framework/Versions/1.0/Resources/AdobeCP15.plugin/Contents/MacOS/AdobeCP"
sudo codesign -fv -dv -s "Developer ID Application: CompanyName" "CompanyApp.app/Contents/Frameworks/Adobe AIR.framework/Versions/1.0/Resources/AdobeCP15.plugin"
sudo codesign -fv -dv -s "Developer ID Application: CompanyName" "CompanyApp.app/Contents/Frameworks/Adobe AIR.framework/Versions/Current/Resources/AdobeCP15.plugin/Contents/MacOS/AdobeCP"
sudo codesign -fv -dv -s "Developer ID Application: CompanyName" "CompanyApp.app/Contents/Frameworks/Adobe AIR.framework/Versions/Current/Resources/AdobeCP15.plugin"
All good. Then attempt the framework...
sudo codesign -fv -dv -s "Developer ID Application: CompanyName" "CompanyApp.app/Contents/Frameworks/Adobe AIR.framework"
CompanyApp.app/Contents/Frameworks/Adobe AIR.framework: bundle format is ambiguous (could be app or framework)
Everything goes downhill after this 😞
Copy link to clipboard
Copied
I remember trying to sign everything in sight, but it never worked for me. See my previous post; I just sign two things, and I have my app in both the Mac App Store as well as a stand-alone Mac installer that Gatekeeper is happy with (note the process I describe above is for a Mac stand-alone; creating a Mac App Store version is a slightly different process). I've done this successfully several times now, most recently last week, so I know it works.
Also, I notice you have a lot of files in your .app package that I remove, but maybe you have a reason for them (?).
Copy link to clipboard
Copied
Thanks, JonArnold1172!
I cleaned up the components, and now I'm able to sign without error, however the signing is invalid. I recall this is why I tried signing everything in sight previously. I'm running on OS X 10.9.5 (13F34). Commands are:
chmod -R 777 CompanyApp.app/
sudo rm -rf CompanyApp.app/Contents/Frameworks/Adobe\ AIR.framework/Versions/1.0/Resources/Adobe\ AIR.vch
sudo rm -rf CompanyApp.app/Contents/Frameworks/Adobe\ AIR.framework/Versions/1.0/Resources/adobecp.plugin
sudo rm -rf CompanyApp.app/Contents/Frameworks/Adobe\ AIR.framework/Versions/1.0/Resources/adobecp.vch
sudo rm -rf CompanyApp.app/Contents/Frameworks/Adobe\ AIR.framework/Versions/1.0/Resources/AdobeCP15.plugin
sudo rm -rf CompanyApp.app/Contents/Frameworks/Adobe\ AIR.framework/Versions/1.0/Resources/WebKit.dylib
sudo rm -rf CompanyApp.app/Contents/Frameworks/Adobe\ AIR.framework/Versions/1.0/Resources/Flash\ Player.plugin
sudo rm -rf CompanyApp.app/Contents/Frameworks/Adobe\ AIR.framework/Versions/1.0/Resources/AdobeCP15.plugin
sudo codesign -fv -dv -s "Developer ID Application: CompanyName" CompanyApp.app/Contents/Frameworks/Adobe AIR.framework
sudo codesign -fv -dv -s "Developer ID Application: CompanyName" CompanyApp.app/Contents/MacOS/CompanyApp
sudo codesign -fv -dv -s "Developer ID Application: CompanyName" CompanyApp.app
packagemaker...
sudo codesign -fv -dv -s "Developer ID Application: Active Mind Technology" CompanyApp.pkg
spctl -a -v --type install CompanyApp.pkg
CompanyApp.pkg: rejected
source=obsolete resource envelope
Sigh...
Copy link to clipboard
Copied
Just for kicks, can you try --deep on the line
sudo codesign -fv -dv -s "Developer ID Application: CompanyName" CompanyApp.app
I've had luck signing just the AIR Framework, the Flash Player plugin and the .app itself. However, I had to include ---deep to get that last part to work. Not sure why.
Also, I was always under the impression that the Flash Player plugin was what the AIR runtime uses to run the swf. So I was surprised, Jon, when you posted how you take it out. That's really interesting. I'd like to do the same, but now I'm wondering 1) what part of the captive runtime build *does* run the swf and 2) why is the Flash Player plugin packaged in the first place?
Copy link to clipboard
Copied
Thanks, DMcQ!
I tried, but unfortunately same result (I even remembered to repackage! 🙂 I guess it was a long shot - according to TN2206, "While the --deep
option can be applied to a signing operation, this is not recommended. We recommend that you sign code inside out in individual stages (as Xcode does automatically). Signing with --deep
is for emergency repairs and temporary adjustments only."
I went back and signed another .dylib which I found lurking, but still no luck.
Thanks for your help!
Copy link to clipboard
Copied
@flataddressspace, I've not been successful yet in getting a properly signed .pkg installer for non-Mac-App-Store...I've only been able to do a .dmg (and for that I use an app called "dmgCreator"). It's not as elegant of an install for the user IMHO, but it's not bad and most importantly it works, so I'm living with it. It also looks like you're using slightly different flags in your code signing commands...no idea what the diff is, I just know that mine work for me.
Copy link to clipboard
Copied
Thanks, JonArnold1172!
Actually, I tried spctl on the signed .app, and that passed, so maybe packaging into a .dmg is worth a shot - it's only when I test the signed .pkg that I get failure. I know our product manager won't like a plain .dmg, but I think I need to give that a whirl, at least as a worst-case-scenario resolution.
Thanks!
Copy link to clipboard
Copied
Still banging my head against this - it's more complicated than I thought (and I'm not the original developer, who has long since gone...)
We have an ANE component, as well as a launcher to copy and register, so a simple .dmg doesn't appear to work.
Maybe the ANE is the problem, since there are executable components required under CompanyApp.app/Contents/Resources/META-INF/AIR/extensions/com.company.extensions.app/META-INF/ANE/MacOS-x86/app.framework -- if I move the contents of the AIR directory under CompanyApp.app/Frameworks (which seems to be the best place according to Apple's guidelines for location of executables), the AIR app won't run 😞
Anyone had experience of signing successfully for v2 with an ANE component?
Thanks!
Copy link to clipboard
Copied
Hi, I found this post really helpful and have now finally got my app in the osx app store (Garden Planner ) as well as having a gatekeeper friendly version on my site.
I thought I'd share my steps in case it helps anyone.
first up I create the swf and then create the app on my mac with adt
the adt command looks like this AdobeAIRSDK/bin/adt -package -keystore mycert.p12 -storetype pkcs12 -target bundle gardenPlanner.app gardenPlanner-app.xml gardenPlanner.swf
then to create a version for download from my site that gatekeeper is happy with I just code sign the frameworks
codesign -f -s "Developer ID Application: your name (XXXXXXX64)" "gardenPlanner.app/Contents/Frameworks/Adobe AIR.framework"
then sign the app
codesign -f -s "Developer ID Application: your name (XXXXXXX64)" gardenPlanner.app
then product build
productbuild --component gardenPlanner.app /Applications --sign "Developer ID Installer: your name (XXXXXXX64)" gardenPlanner.pkg
and that seems to work. Note you dont have to change the icons or delete stuff from the framework - its probably good practice to at least put in higher res icons, but you dont have to and I wanted to show the minimal steps.
Copy link to clipboard
Copied
David, are you creating a captive runtime with ADT?
Copy link to clipboard
Copied
@FuriousCoder, Yes, Since david doull adt command include -native bundle option to represent the inclusion of AIR captive runtime