Making an Electron App with Ember JS Part #2: MacOS

This article is part of a series. Check the links below if you haven't already!

This is part two in the series of blog posts “Making an Electron App with Ember JS” where I go over how I built my app Snipline for the web, Mac, Windows, and Linux.

This post assumes you’ve read part one, if you haven’t then I highly recommend it. Now, on with the show!

Building for MacOS

Before building the app we need prepare it for code signing. For this you will need to have an Apple Developer Account which if you haven’t already, you can get from the Apple Developer website. Note that this costs a yearly fee of $99.

Why is code signing important? I’m glad you asked! Code signing makes sure the files that your users download hasn’t been tampered with and comes from the developer that you expect. Without it, MacOS and Windows will go warn users about running the app and to a certain extent prevent them from doing so.

You should be able to follow along without code signing for educational purposes but for a production app I would highly recommend it.

Once you have the Developer account set up create a “Developer ID Application” certificate, download and install it on your Mac machine.

In ember-electron/electron-forge-config.js add the following:

// At the top
const path = require('path');
const rootPath = path.join('./');

function getCodesignIdentity() {
  if (process.platform !== 'darwin') {
      return;
  }

  if (process.env.CODESIGN_IDENTITY) {
      return process.env.CODESIGN_IDENTITY;
  } else {
      console.log('Codesigning identity can not be found, release build will fail');
      console.log('To fix, set CODESIGN_IDENTITY');
  }
}

function getBundleId() {
  if (process.platform !== 'darwin') {
      return;
  }

  if (process.env.BUNDLE_ID) {
      return process.env.BUNDLE_ID;
  } else {
      console.log('bundle id can not be found, release build will fail');
      console.log('To fix, set BUNDLE_ID');
  }
}

// Replace electronPackagerConfig with this
"electronPackagerConfig": {
  "packageManager": "yarn",
  name: "Shopper",
  icon: path.join(rootPath, 'ember-electron', 'resources', 'shopper'),
  versionString: {
    CompanyName: 'Acme Ltd',
    FileDescription: 'Shpoper for Desktop',
    ProductName: 'Shopper',
    InternalName: 'Shopper'
  },
  "osxSign": {
    "identity": getCodesignIdentity()
    },
    "appBundleId": getBundleId(),
    "appCategoryType": "app-category-type=public.app-category.developer-tools",
  },

// At the bottom of module.exports
electronInstallerDMG: {
    title: 'Shopper',
    icon: path.join(rootPath, 'ember-electron', 'resources', 'shopper.icns'),
    
    iconsize: 100,
    window: {
        size: {
            width: 600,
            height: 571
        }
    }
},

There’s one extra step before we can run. Code signing On a Mac no longer allows any file in an app bundle to have an extended attribute containing a resource fork or Finder info. This will most likely apply to any assets that you’ve created and you can debug it by running

xattr -lr .

In the Shopper app it only affects the newly created icons. We can fix this by running the following command. In your own apps you will need to use both commands to find and fix any assets. Without doing this your app will build, but code signing might fail.

xattr -cr ember-electron/resources

Now for the fun part. Take the following build command and update the CODESIGN_IDENTITY and BUNDLE_ID variables. The bundle ID should be a unique code, most people use their domain name in reverse with unique subdomain.

Run the command, go grab yourself a hot cup of tea, and when you’re back you should have a .zip in electron-out/make/ file containing the app.

env CODESIGN_IDENTITY="Developer ID Application: <Name> (<ID>)" env BUNDLE_ID="io.exampledomain.desktop" ELECTRON_ENV=production ember electron:make --environment=production 

Unzip it and run it, you should see the new app, dock icon and all!

Creating the DMG installer

An optional nice touch is to create a DMG file which will guide the user into moving your app into their /Applications directory.

For this I use an open source tool called create-dmg. It’s fairly simple to use and will pick up your code signing cert automatically.

cd electron-out/make/
rm -rf Shopper.app
unzip Shopper-darwin-x64-0.1.0.zip
create-dmg Shopper.app ./

What we’ve done so far

We’ve configured the Electron app to generate a code signed MacOS application and bundled it into an easy-to-install DMG file.

In the next chapter we’ll take a look at building for Linux!

Spread the word

Share this article

Next up Making an Electron App with Ember JS Part #2.5: MacOS Notarisation

Like this content?

Check out some of the apps that I've built!

Snipline

Command-line snippet manager for power users

View

Pinshard

Third party Pinboard.in app for iOS.

View

Rsyncinator

GUI for the rsync command

View

Comments