Electron “Open With” for Mac OSX

Roy Segall
May 24 · 5 min read

Prologue

I love Apple products but mostly, what I use every day for making money, is an operating system. I love Mac OSX, I think it’s one of the best OS for web development. No, Microsoft Windows is not good enough IMO for web development. One of the things that doesn’t exist on the Mac OS is a proper image gallery.

Yes, in the new versions of Mac OS you can see images in a different way from the finder or maybe use the default image viewer, but that’s kind of lame. I tried to find something in the App Store but most of the other solutions felt to me like:

This is how I feel about the other solutions

So, what are the options? Well, that depends - are you the guy who talks or are you the guy who takes action? I’m usually the guy that takes action and decided to create a desktop app for that. Don’t get me wrong, this awful situation in which there is no good image gallery is been like this for years but only now I decided to do something about it.

Weapon of choice

So, as a web developer, I’m going to use Electron and since I’m pretty much a VueJS guy and the combination of the two looks OK. Yes, I’ve seen posts about Electron which people wrote it’s bad and not the best solution. But, if we will look at the bigger picture — Electron and VueJS for a web developer should achieve a quick solution. Since we going to access local files we don’t need any kind of database or some HTTP request library (ahem, axios, ahem).

A small disclaimer: I’m not going to build in this blog post the components nor the architecture. In this blog post, we going to see how to access only the files that were selected and handled by the “Open With” option:

In case you don’t know what is the “Open With” — here is a reminder.

It’s time to build an app

So, let’s start and scaffold an app - We can use electron-vue. In the readme section we have an explanation on how to set it up but, let’s write it here, just to be clear:

The process above created for us a full fledge electron application with a nice design and information that isn’t so relevant for us:

After setting up the app, we get this nice view.

Since we want to show the selected files we can remove a lot of code and keep a clean page:

For now, we will start with a welcome message.

The code should look like this:

Quick Electron architecture introduction

There are two parts: the main file, which is in the main.js, AKA the main process, and the rendering part, AKA render process, which is the section that our Vue JS app lives in which in our case its the render folder. The main process gets info from the OS and then creates the main browser window that loads our vue JS.

How to know which files were selected?

We can use a channel that sends data from the main process to the render via Electron IPC. Sounds good, what next? We need to know which file(s) were selected by the “Open With” option. We can do that by using the open-file event.

Now you probably saying to your self — let’s connect between the events and we can move on, right? The short answer is — no, we cannot do that.

The answer is pretty complex so stay with me: The open-file event is being triggered very early in the bootstrap process of our Electron application and the process which loads the application itself, which called ready, triggered after that. Both of the events may not be aware of each other thus leave our application without the important data — which files were selected.

There are a couple of solutions — you can set up a server that runs in the background and then we can pull it with an HTTP request. But that’s a lot of moving parts that we need to corporate and maintain.

A simple solution would be to write to a file. The open-file event is being triggered for each file so we would need to concatenate them into a single array:

At the ready event we will write the array of the files into a file:

Now, we need to read the file in the main VueJS app. Our only component should only display the files in a list and nothing more:

Notify the OS that we can handle files

We need to notify the OS that our application can handle images. We would do that in the package.json files under the build section in the mac property:

"build": {
"productName": "open-with",
"appId": "com.example.yourapp",
"directories": {
"output": "build"
},
"files": [
"dist/electron/**/*"
],
"dmg": {
"contents": [
{
"x": 410,
"y": 150,
"type": "link",
"path": "/Applications"
},
{
"x": 130,
"y": 150,
"type": "file"
}
]
},
"mac": {
"icon": "build/icons/icon.icns",
"category": "public.app-category.photography",
"fileAssociations": [
{
"ext": [
"jpg",
"jpeg",
"png",
"PNG",
"tiff"
],
"description": "Image files",
"role": "Viewer"
}
]
},
"win": {
"icon": "build/icons/icon.ico"
},
"linux": {
"icon": "build/icons"
}
},

Proluge

Next, we need to build our application using:

npm run build # Or yarn run build

The application will be compiled into the build directory and you’ll see the dmg file that you’ll install your app with:

The install dialog

Now, when the user will use the “Open With” option the application will appear:

The open-with application is there!

If you can’t see the application, you might want is to use the “Other…” option at the bottom of the list.

Bonus

Since you read all the blog post and got here, have a look at two repositories;

First, the repository with the example code you saw in this amazing blog post: https://github.com/RoySegall/electron-open-with-demo

Second, If you’re looking for the app you can get it here: https://github.com/RoySegall/imaginary

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade