print

NeutronEncyclopedia

The initial version of the encyclopedia was published in 2004 in the form of the CD-ROM "Exploring matter with neutrons". Its many files (.swf, .mov, .html, etc.) were displayed by an embedded FlashPlayer.app (also known as Flash Projector).
Flash being now persona non grata on the web, the goal here was to publish the encyclopedia in the form of a standalone application compatible with Apple's App Store: <https://itunes.apple.com/us/app/pages/id933660286?mt=12>

Things would have been a lot simpler if the many encyclopedia data files could be placed into the "Resources" folder of the Flash Player, Unfortunately, without the original files (e.g. Flash .fla files), there is no way to change the file hierarchy inherited from the CD-ROM. Indeed, the file movie.swf has a hard coded link inside that we failed to change even after a decompilation to movie.fla was performed.

As shown below this leads to NeutronEncyclopedia.app being a bundle with an embedded bundle, and these have to be both signed and sandboxed.

NeutronEncyclopedia.app       <-- main bundle
    Contents
        MacOS
            NeutronEncyclopedia   <-- a small binary that launches Flash Player.app
        Ressources
            many encyclopedia files (.swf, .mov, etc.)
            FlashPlayer.app       <-- secondary bundle initially signed by Adobe
                Contents
                    MacOS
                        flashplayer   <-- the binary
                    Resources
                        movie.swf     <-- the starting point for the encyclopedia
                        many Adobe's files

1. Adobe's permission

Flash Player Projector <https://www.adobe.com/support/flashplayer/debug_downloads.html> is a standalone version of Flash Player for macOS, Window and Linux. Adobe makes it clear that it is is for development only and must not be distributed. In practice,  Adobe never complained about Flash based CD-ROMS which have an embedded Flash Projector.

For NeutronEncyclopedia, the problem was more serious since the Flash Player interface must be modifyed to comply Apple's requirements (see section 5).
Therefore I asked Adobe for the permission to do so. They kindly accepted for free and we had a contact signed. The main difficulty was to reach a Legal Officer since my querry was totally out of scope for the Support (Chat, AI based support or 1st telephonic support).

2. Signing with Xcode

My solution:

  1. Cleanup files for resources and other detritus
    First of all, FlashPlayer.app contains many old files that must be cleaned.
        xattr -cr Flash\ Player.app
  2. As indicated by Apple, the Adobe signature of the embedded FlashPlayer.app must be replaced by the ILL signature. It was 1st renammed "Launcher" not to confuse with any other Flash Player that might be already present on the disk.
    codesign -d --keychain /Users/filhol/Library/Keychains/login.keychain --force --verbose -s "Developer ID Application: INSTITUT MAX VON LAUE - PAUL LANGEVIN (P65398CN49)" /Users/filhol/Development/Dev-NeutronEncyclopedia/Resources/Launcher.app
    Note that --entitlements Launcher.entitlements must be added if you target the AppStore
  3. The main bundle is signed by Xcode with the ILL certificate
    Xcode gives a warning which says that the embedded bundle is already signed.

The resulting application has a Finder icon and name (NeutronEncyclopedia) which are replaced by the Flash Player icon and name when started.
When launching the signed application on an other computer, GateKeeper does not complain but you get two alerts, one for each bundle.
  --> screen captures to be added

Unfortunately enough, I failed publishing this to the App Store as explained in section 4, thus I switched to Application Loader.

3. Publishing to the App Store with Application Loader

Here my solution followed by a detailed description of the steps I had to go through.

  1. the embedded bundle, Flash Player.app, is renamed Encyclopedia-player.app
    This is for not to confuse users at first launch since they will have to successively grant permission for the main bundle (NeutronEncyclopedia.app) and then the embedded bundle (Encyclopedia-player.app)
  2. Embedded bundle: the original bundle ID from Adobe was not accepted
    <key>CFBundleIdentifier</key>
        <string>com.macromedia.Flash Player.app</string>

    I replaced it with a bundle ID registrated in page <https://developer.apple.com/account/mac/identifier/bundle/>

Since the Xcode procedure failed (see section 4) I used the manual procedure below:
Two entitlement files were used:
    Encyclopedia-player.entitlements  <-- embedded bundle
    NeutronEncyclopedia.entitlements  <-- main bundle

  1. Signing the embedded bundle first
    $ codesign -d --keychain /Users/filhol/Library/Keychains/login.keychain --entitlements Encyclopedia-player.entitlements --force --verbose -s "E5560E6BCB17DDCEA3E640CC36E3B71E52C5D09B" NeutronEncyclopedia.app/Contents/Resources/Encyclopedia-player.app
  2. Signing the main bundle
    $ codesign -d --keychain /Users/filhol/Library/Keychains/login.keychain --entitlements NeutronEncyclopedia.entitlements --force --verbose -s "E5560E6BCB17DDCEA3E640CC36E3B71E52C5D09B" NeutronEncyclopedia.app
  3. Creating an unsigned .pkg archive
    $ productbuild --component NeutronEncyclopedia.app /Applications NeutronEncyclopedia.pkg
  4. Signing this .pkg file
    $ productsign --sign "3rd Party Mac Developer Installer: INSTITUT MAX VON LAUE - PAUL LANGEVIN (P65398CN49)" --keychain ~/Library/Keychains/login.keychain NeutronEncyclopedia.pkg /Users/afilhol/Desktop/NeutronEncyclopediaSigned.pkg
    Note that the target folder (signed .pkg) is different from the source folder (unsigned .pkg) because otherwise the file will never show. (Is this a bug?)

Associated error messages:

ERROR ITMS-90277: "Invalid Bundle Identifier. The application bundle contains a tool or framework Flash Player [eu.ill.comm.NeutronEncyclopedia.pkg/Payload/NeutronEncyclopedia.app/Contents/Resources/Launcher.app] using the bundle identifier 'com.macromedia.Flash Player.app', which is not a valid bundle identifier.
    —> Note that the problem may have come from the space character in "Flash Player" in the original Bundle ID
    —> I used a new bundle Identifier for the embedded bundle

ERROR ITMS-90237: "The product archive package's signature is invalid. Ensure that it is signed with your "3rd Party Mac Developer Installer" certificate.
    —> The .pkg must be signed

4. My own mistakes and Apple's bugs

  1. Xcode/Organizer nightmare
    The "Upload to App Store" process says it is preparing a .pkg but iTunes complains Xcode is submitting an .ipa.
        “the info.plist indicates a mac app, but submitting an ipa”
    The newsgroups suggestion is "try Application Loader 3 instead !"
     
  2. What is the problem with Xcode ?
    As an alternative I downloaded the signed .pkg created by Xcode (Export "App Store") then submitted it to the App Store using Application Loader v3.0 (see section 3). I got the strange error message below:
    ERROR ITMS-90268: "The 'Bundle OS Type Code' [CFBundlePackageType] in your application bundle's Info.plist file must be 'APPL’."
    I extracted the bundle from that .pkg and found that the Info.plist file contains:
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
    instead of:
        <key>CFBundlePackageType</key>
        <string>APPL</string>
    This is clearly a BUG in Xcode since Export "Developer ID" gives a CFBundlePackageType string correctly set to "APPL".
     
  3. Application Loader
    It can be found here: Xcode/Open Developer Tool/Application Loader (v3.9)
    As suggested by some newsgroup, I used an older version (v3.0)

    1st dialogue: the Apple ID
    2nd dialogue: a password defined here <appleid.apple.com> Security/APP-SPECIFIC PASSWORDS
    Accepted files are:
      signed .pkg (macOS)
      signed .ipa (iOS)
     
  4. Creating an unsigned .pkg suitable for the App Store
    $ productbuild --component NeutronEncyclopedia.app /Applications NeutronEncyclopedia.pkg
    productbuild: Adding component at /Users/afilhol/Desktop/NE/NeutronEncyclopedia.app
    productbuild: Wrote product to NeutronEncyclopedia.pkg
    productbuild: Supported OS versions: [10.8, )
    $

    Simple but ... if you try to use that .pkg, it installs nothing in /Applications
    This is explained here: <stackoverflow.com/questions/19283889/osx-pkg-installer-sometimes-does-not-install-app-file>
    I lost hours before understanding that.
     
  5. Creating a signed .pkg
    The archive must be signed with my "3rd Party Mac Developer Installer" certificate.
    $ productsign --sign "3rd Party Mac Developer Installer: INSTITUT MAX VON LAUE - PAUL LANGEVIN (P65398CN49)" --keychain ~/Library/Keychains/login.keychain NeutronEncyclopedia.pkg NeutronEncyclopediaSigned.pkg
    productsign: signing product with identity "3rd Party Mac Developer Installer: INSTITUT MAX VON LAUE - PAUL LANGEVIN (P65398CN49)" from keychain /Users/afilhol/Library/Keychains/login.keychain-db
    productsign: adding certificate "Apple Worldwide Developer Relations Certification Authority"
    productsign: adding certificate "Apple Root CA"
    productsign: Wrote signed product archive to NeutronEncyclopediaSigned.pkg
    $

    This might seems simple but it is not. As such the command is Okay but no file NeutronEncyclopediaSigned.pkg is produced if the target (last file name) is defined as /Users/afilhol/Desktop/NeutronEncyclopediaSigned.pkg. No file path is accepted for the latter.

5. Complying with Apple's requirements

Apple refused the unmodified Flash Player embedded in the application for two reasons:
    1- neither the name nor the icon of "Flash Player" must show
    2- no URL display on top of the window     <-- this was not feasible, Apple finally accepted it
This required changes in the resources of Flash Player, changes which are strictly forbidden by Adobe's copyright.

Adobe's permission was asked in January 2018 and finally obtained in October 2019.
B.H. Director Business Development, 9 Oct 2018, "Yes – you can consider this as a permission".
Several month later a contract was signed with Adobe.

Thus I performed the following modifications:

1- Apple no longer accept neither 32bit code nor fat code
    lipo -remove i386 NeutronEncyclopedia.app/Contents/Resources/Encyclopedia-Player.app/Contents/MacOS/Flash\ Player -output /Users/afilhol/Desktop/Flash\ Player
    Then replace the "fat" Flash Player of the bundle by the one the above command created on the Desktop
2- The bundle name must be "NeutronEncyclopedia"
    <key>CFBundleLongVersionString</key>
    <string>NeutronEncyclopedia - Adobe Flash Player   32.0 r0</string>
    <key>CFBundleName</key>
    <string>NeutronEncyclopedia</string>
3- The Icon must not be the Flash Player icon
    <key>CFBundleTypeIconFile</key>
    <string>NeutronEncyclopedia.icns</string>
    <key>CFBundleIconFile</key>
    <string>NeutronEncyclopedia.icns</string>
4- "About"
   Added a file Credits.rtf to each .lproj. It will take the precedence over "StandalonePlayerLocalizable.strings"
   The latter is kept to satisfy Adobe.
5- Application's ID change
    One ID for the main application: <eu.ill.comm.neutronencyclopedia>
    One ID for the player:
      <key>CFBundleIdentifier</key>
      <string>eu.ill.comm.NeutronEncyclopediaP</string>
    This ID is registrated in <https://developer.apple.com/account/mac/identifier/bundle/>
6- Version numbers for both NE and Flash Player
Info.plist
    <key>CFBundleShortVersionString</key>
    <string>3.0.1 (Flash 14.0.0.125)</string>
    <key>CFBundleVersion</key>
    <string>3.0.1 (Flash Player 14.0.0.125)</string>
The two are shown in the About dialogue via Credits.rtf
    =>  3.0.1 (Flash 14.0.0.125) 3.0.1 (Flash 14.0.0.125)
however only the 1st one shows in the Finder, thus the second was deleted.
7- Modified Menus
In the interface, any occurance of "Flash Player" must be replaced by "NeutronEncyclopedia-player" and any out of scope menu item must be removed.

The original resource file "MainMenu.nib" of Flash Player is in a very old format which cannot be edited by modern tools. It must be unlocked and converted.

To make it editable place it inside a bundle as follows:
Non-editable ressource file:
    MainMenu.nib    <— the Finder command "Show package contents" is disabled
Ressource package that Xcode can edit:
    MainMenu.nib            <— "Show package contents" enabled
        designable.nib
        keyedobjects.nib    <— renamed MainMenu.nib

One solution to edit the editable .nib is the following:
1- NibUnlocker.app : this app converts the non-editable .nib into an editable .xib
2- Modify the .xib with Xcode
3- convert the .xib into a .nib
     Xcode 10 shouts that this is an old format and crashes when saving. Use an older Xcode.
4- replace old .nib in both folders en.lproj and fr.lpro, located in the folder Resources of the Flash Player bundle (now renamed NeutronEncyclopedia)

8- Binary hardening
The binary hardening is a new Apple's requirement which implies that binaries be compiled with the extra option:
     -mmacosx-version-min=10.10   (10.6 is the minimum supported version)

A library can be checked :
     otool -l <library path> | grep -B 1 -A 3 LC_VERSION_MIN
With an output such as:
     Load command 8
         cmd LC_VERSION_MIN_MACOSX
     cmdsize 16
     version 10.6 <-- Minimum macOS version
         sdk 10.11

The following codesign option is also associated with binary hardening:
     codesign --options runtime ...

6. Problems with Apple procedure

iTunesConnect support proved to be very efficient once I managed to pass its 1st level. I was even called by Cork. In short I had both distribution profile problem and a build number selection.

Each attempt to publish with iTunes Connect gave the error message:

We identified one or more issues with a recent submission for your app, “NeutronEncyclopedia”. Please correct the following issues, then upload again.

I would have found by myself if the error message was more informative:

We identified one or more issues with a recent submission for your app, “NeutronEncyclopedia” build nber xxx uploaded xx/xx/xxxx. Please correct the following issues, then upload again.

In other words the error message did not explain that, while I uploaded many builds but was always intending to publish the same 1st build updated long ago.

Furthermore, to my point of view, the procedure is ambiguous:
    - each time a build is submitted, the button "Submit" of iTunes Connect turns grey or vanishes
    - for each new upload, either Application Loader or the server says a new build number is compulsory
thus the user may reasonably think that both iTunes Connect will never submit gain a build that was already submitted, and that the last upload is the one which is submitted by default.
In practice, a new upload makes the "Submit" button reappear but the last uploaded build is not the one selected in iTunes Connect, :-(   I lost days !