June 17, 2017 Adem Bilican 14 comments

How to submit an Electron app to the mac appstore?

 

1- Create a Bundle ID for your app

The very first step to be able to send a mac app to the appStore is to create a unique Bundle ID for it:

  • go to your Apple Developer Account
  • click Certificates, IDs & Profiles
  • select macOS in the top-left dropdown list
  • click on App IDs under the Identifiers menu
  • click the + sign on the upper-right part of the screen
  • give a description to your app, choose Explicit App ID and enter a Bundle ID (usually something like com.domain.appname)
  • click Continue and then Register

 

2- Create your developer certificates

You need two types of certificate as a developer to submit an app to the mac appStore:

  • click Certificates, IDs & Profiles
  • select macOS in the top-left dropdown list
  • click on All under the Certificates menu
  • click the + sign on the upper-right part of the screen
  • in the Production section choose Mac App Store
  • in the next page select Mac App Distribution, click Continue
  • create your Certificate Signing Request as indicated, click Continue
  • load your CSR file and download the generated certificate

In addition to the Mac App Distribution certificate, one also need a Mac Installer Distribution certificate. You need to perform the same steps as previously and select Mac Installer Distribution on step 5.
All your certificates should be ready now.
 

3- Package your Electron app

It is now time to prepare your app for the submission. You  first need to install electron-packager. This module will be helpful to create the .app and package everything we need. To install :

npm install electron-packager -g

And then run:

electron-packager . --appname=appName --app-bundle-id=com.domain.appname --version=ELECTRON_VERSION --overwrite --platform=mas --arch=x64 --icon=../appName.icns --prune --out=mas-build --ignore --app-version=1.0.0 --ignore=.+.o$

Change ELECTRON_VERSION to the correct version of Electron installed in your machine (run “electron -v” if you are not sure).
This will create your appName.app in a new folder named mas-build. This is usually enough if you want to distribute your app. However, a few more steps are required to submit it properly to the appStore.
As you can see, you also need the .icns file with the requested icon format. You can check here to see how to prepare the perfect .icns.
 

4- Sign your app

You need then to sign your app, so everybody knows it’s coming from a trustworthy developer 😉
The codesign command already exists by default on mac, you will use it to sign your app. Run the following command by properly adding the name of your certificate and the correct path to your appName.app.

codesign --deep --verbose --force --sign "3rd Party Mac Developer Application: $$$$$ (£££££)" PATH_TO/appName.app
codesign --verify -vvvv PATH_TO/appName.app

 

5-Prepare additional files

5.a- Update the Info.plist

Your app is now signed. The next step is to find your appName.app, right-click and select Show Package Contents.
Go to the Contents folder and open the Info.plist file with a text editor (not Xcode).
Add the following code

<key>ElectronTeamID</key>
<pre><string>TEAM_ID</string>

Just before

...
<code><span class="nt"></dict></span>
<span class="nt"></plist>

Here you need to replace TEAM_ID with your teamID, you can find it on your Apple developer account (click Membership then you’ll see a row named Team ID).
 

5.b- Add child.plist and parent.plist

Create the two following files with the corresponding content:

  • child.plist
<?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.app-sandbox</key>
    <true/>
    <key>com.apple.security.inherit</key>
    <true/>
  </dict>
</plist>
  • parent.plist
<?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.app-sandbox</key>
    <true/>
    <key>com.apple.security.application-groups</key>
    <string>TEAM_ID.your.bundle.id</string>
  </dict>
</plist>

Replace TEAM_ID by your Team ID and your.bundle.id by the unique Bundle ID of your app (we previoudly used com.domain.appname).
 

6- Create a .pkg of your app

Create a new file and name it packageAppStore.sh with the following content.

#!/bin/bash

# Name of your app.
APP="YourApp"
# The path of your app to sign.
APP_PATH="/path/to/YourApp.app"
# The path to the location you want to put the signed package.
RESULT_PATH="~/Desktop/$APP.pkg"
# The name of certificates you requested.
APP_KEY="3rd Party Mac Developer Application: Company Name (APPIDENTITY)"
INSTALLER_KEY="3rd Party Mac Developer Installer: Company Name (APPIDENTITY)"
# The path of your plist files.
CHILD_PLIST="/path/to/child.plist"
PARENT_PLIST="/path/to/parent.plist"

FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks"

codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Electron Framework"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libffmpeg.dylib"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libnode.dylib"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/Contents/MacOS/$APP Helper"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/Contents/MacOS/$APP Helper EH"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/Contents/MacOS/$APP Helper NP"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/MacOS/$APP"
codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH"

productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH"

You need to do some changes on this file on the first lines:

  • l4: change YourApp.app by the name of your app (with the .app extension), in our case appName.app
  • l6: change /path/to/YourApp.app to the path to your appName.app
  • l8: change ~/Desktop/$APP.pkg to the directory where you want to save your final .pkg, don’t modify the $APP.pkg part
  • l10 and l11: Enter the corresponding names of your two certificates
  • l13: change /path/to/child.plist to the path to your child.plist file
  • l14: change /path/to/parent.plist to the path to your parent.plist file

Finally, run the following command to generate your appName.pkg :

./packageAppStore.sh

 

7- Launch Application Loader and load the .pkg

If you already installed Xcode, you should also have an application called Application Loader. Launch Application Loader and login with your account. You might need to get an app specific password, for this connect to appleid.apple.com and click Generate Passwords… on the APP-SPECIFIC-PASSWORDS section. Enter a Label (for example Application Loader) and copy paste the code to the Application Loader app.
Click Choose and select the freshly generate appName.pkg. This should automatically identify your app based on the Bundle ID.
Finish the whole process of uploading your app.
 

8- Complete your app information

You app build should be available on your iTunesConnect account soon. In the meantime, you need to complete the information about your app. Once done, you can select the build that you want to upload to the appStore and click Submit.
 

9- Some potential issues

If you submitted the .pkg file but it does not appear on itunesConnect, check your email. If you received something like:

Invalid Signature – The executable at path appName.app/Contents/Resources/app/node_modules/robotjs/build/Release/robotjs.node has following signing error(s): code object is not signed at all In architecture: x86_64 . Refer to the Code Signing and Application Sandboxing Guide at http://developer.apple.com/library/mac/#documentation/Security/Conceptual/CodeSigningGuide/AboutCS/AboutCS.html and Technical Note 2206 at https://developer.apple.com/library/mac/technotes/tn2206/_index.html for more information.

You need to sign the different modules mentioned in this email. For that, just do as follow for each module:

electron-osx-sign appName.app appName.app/Contents/Resources/app/node_modules/robotjs/build/Release/robotjs.node

Voilà 🙂 You can now enjoy some coffee while waiting for the review. Congratulations!

Source: https://electron.atom.io/docs/tutorial/mac-app-store-submission-guide/


We can work together

Share this post on social media:

14 thoughts on “How to submit an Electron app to the mac appstore?

  1. codesign –deep –verbose –force –sign “3rd Party Mac Developer Application: $$$$$ (£££££)” PATH_TO/appName.app

    Which certificate should i replace it with ? If i have a certificate named mac_app.cer, how do i use this command ?

    Thanks

    1. You need to double click to your .cer file, which will open it with the Keychain Access app and show you the name of the certificate.

  2. Hi

    First – thanks for this detailed post- which helped me in packaging the app !

    HAve few questions: I am newbie to APP store development

    1. Once we do codesign –> the app is no longer executable right ? As I was able to run the app just fine before codeSign
    2. Can we just install the .pkg packager in the same development machine? I couldn’t, is it expected
    https://developer.apple.com/library/archive/qa/qa1884/_index.html

    3. Once we have .pkg packager, I was stuck at this step–> ` Launch Application Loader and load the .pkg `, where Application Loader not accepting the password, tried both APP-SPECIFIC-PASSWORDS and also regural password

    any suggestions here?

    1. Hi, you are welcome 🙂
      Regarding your questions:
      1. You should still be able to run the app after codesign as that is the version that your users will have access to.
      2. I have installed several times the pkg to my own machine (which is my development machine) and it worked fine.
      These 2 issues you are having (1. and 2.) with codesign are probably not related to Electron itself, it looks like something at the system level.
      3. Can you check the version of Application Loader you are running? You maybe need to update it. If it still does not work you can alternatively add your app to itunesconnect first and then load the pkg there directly.

  3. The instruction is useful, BUT, you missed the most important thing. For example, the problems that any program developer will encounter when sending to MAS are .icns icons. Anyone who has flooded knows these problems thoroughly.

  4. Hello Ademcan,
    Thanks for the instructions…I encountered a problem that you may be to help me with. I get the following email when I upload the app. I tried using step 9 to fix the issue with no luck. Am I missing something?

    `Dear Developer,

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

    Invalid Signature – The main app bundle Marks at path Marks.app has following signing error(s): code object is not signed at all In subcomponent: /Volumes/data01/app_data/dstr/mz_6652398793794542504dir/mz_3070721419243036662dir/com.henry.grades.pkg/Payload/Grade.app/Contents/child.plist . Refer to the Code Signing and Application Sandboxing Guide at http://developer.apple.com/library/mac/#documentation/Security/Conceptual/CodeSigningGuide/AboutCS/AboutCS.html and Technical Note 2206 at https://developer.apple.com/library/mac/technotes/tn2206/_index.html for more information.

    Unable to Sign – This package doesn’t meet the current code signing requirements. For more information, see the Code Signing and Application Sandboxing Guide and Technical Note 2206.

    Specifically, codesign generated the following error:

    com.henry.grades.pkg/Payload/Marks.app: code object is not signed at all
    In subcomponent: com.henry.grades.pkg/Payload/Grade.app/Contents/child.plist
    Best regards,

    The App Store Team`

    1. Hi Henry, sorry for the late reply…
      What I mention in step 9 is about some npm packages, usually in the node_modules folder.
      However, in your situation it is complaining about Marks.app, what is that?

  5. 1 package(s) were not uploaded because they had problems:
    /var/folders/lh/k6991gb17ssd0gg0yplqc0240000gn/T/C86F57E3-1269-4627-8ECA-31A6B73D0DE5/1464202398.itmsp – Error Messages:
    ERROR ITMS-90296: “App sandbox not enabled. The following executables must include the “com.apple.security.app-sandbox” entitlement with a Boolean value of true in the entitlements property list: [( “com.favercrm.macos.pkg/Payload/favercrm.app/Contents/Library/LoginItems/favercrm Login Helper.app/Contents/MacOS/favercrm Login Helper”, “com.favercrm.macos.pkg/Payload/favercrm.app/Contents/MacOS/favercrm” )] Refer to App Sandbox page at https://developer.apple.com/devcenter/mac/app-sandbox/ for more information on sandboxing your app.”

  6. I tried the same but when i tried to upload the .pkg file on apple app store its shows two error. Basically i am using the combination of electron and angular can you please help me to figure out the issues which i am going to mentioned.
    ERROR ITMS-90236: “Missing required icon. The application bundle does not contain an icon in ICNS format, containing both a 512×512 and a 512×512@2x image. For further assistance, see the Apple Human Interface Guidelines at https://developer.apple.com/macos/human-interface-guidelines/icons-and-images/app-icon

    ERROR ITMS-90296: “App sandbox not enabled. The following executables must include the “com.apple.security.app-sandbox” entitlement with a Boolean value of true in the entitlements property list: [( “com.htf.myapp.pkg/Payload/myapp.app/Contents/Frameworks/myapp Helper (GPU).app/Contents/MacOS/myapp Helper (GPU)”, “com.htf.myapp.pkg/Payload/myapp.app/Contents/Frameworks/myapp Helper (Plugin).app/Contents/MacOS/myapp Helper (Plugin)”, “com.htf.myapp.pkg/Payload/myapp.app/Contents/Frameworks/myapp Helper (Renderer).app/Contents/MacOS/myapp Helper (Renderer)”, “com.htf.myapp.pkg/Payload/myapp.app/Contents/Frameworks/myapp Helper.app/Contents/MacOS/myapp Helper”, “com.htf.myapp.pkg/Payload/myapp.app/Contents/Library/LoginItems/myapp Login Helper.app/Contents/MacOS/myapp Login Helper”, “com.htf.myapp.pkg/Payload/myapp.app/Contents/Resources/app/release-builds/myapp-darwin-x64/myapp.app/Contents/Frameworks/Electron Framework.framework/Helpers/chrome_crashpad_handler”, “com.htf.myapp.pkg/Payload/myapp.app/Contents/Resources/app/release-builds/myapp-darwin-x64/myapp.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Helpers/chrome_crashpad_handler”, “com.htf.myapp.pkg/Payload/myapp.app/Contents/Resources/app/release-builds/myapp-darwin-x64/myapp.app/Contents/Frameworks/Electron Framework.framework/Versions/Current/Helpers/chrome_crashpad_handler”, “com.htf.myapp.pkg/Payload/myapp.app/Contents/Resources/app/release-builds/myapp-darwin-x64/myapp.app/Contents/Frameworks/Squirrel.framework/Resources/ShipIt”, “com.htf.myapp.pkg/Payload/myapp.app/Contents/Resources/app/release-builds/myapp-darwin-x64/myapp.app/Contents/Frameworks/Squirrel.framework/Versions/A/Resources/ShipIt”, “com.htf.myapp.pkg/Payload/myapp.app/Contents/Resources/app/release-builds/myapp-darwin-x64/myapp.app/Contents/Frameworks/Squirrel.framework/Versions/Current/Resources/ShipIt”, “com.htf.myapp.pkg/Payload/myapp.app/Contents/Resources/app/release-builds/myapp-darwin-x64/myapp.app/Contents/Frameworks/myapp Helper (GPU).app/Contents/MacOS/myapp Helper (GPU)”, “com.htf.myapp.pkg/Payload/myapp.app/Contents/Resources/app/release-builds/myapp-darwin-x64/myapp.app/Contents/Frameworks/myapp Helper (Plugin).app/Contents/MacOS/myapp Helper (Plugin)”, “com.htf.myapp.pkg/Payload/myapp.app/Contents/Resources/app/release-builds/myapp-darwin-x64/myapp.app/Contents/Frameworks/myapp Helper (Renderer).app/Contents/MacOS/myapp Helper (Renderer)”, “com.htf.myapp.pkg/Payload/myapp.app/Contents/Resources/app/release-builds/myapp-darwin-x64/myapp.app/Contents/Frameworks/myapp Helper.app/Contents/MacOS/myapp Helper”, “com.htf.myapp.pkg/Payload/myapp.app/Contents/Resources/app/release-builds/myapp-darwin-x64/myapp.app/Contents/MacOS/myapp” )] Refer to App Sandbox page at https://developer.apple.com/documentation/security/app_sandbox for more information on sandboxing your app.”

Leave a Reply

Your email address will not be published. Required fields are marked *