Converting a Node.js Script Into a Desktop Application

This is the story of how a simple script became a beautiful desktop application

Jesus Nieves
Better Programming

--

Code on a laptop
Photo by Christopher Gower on Unsplash.

This is the story of how I put some basic UI design concepts, knowledge of Node.js, JavaScript, Swift, HTML, and CSS in an electron container to create a great-looking application that allows iOS developers to convert those old XIB files to Swift code.

To explain how this tool was born, I will use Christopher Nolan’s Batman movies (I love this trilogy).

Begins

Creating the core

No, there was no tragic accident involving someone’s parents here. But there is a story about how something great was born.

It all started as practice to learn how an XIB file is built. When you open a Storyboard or XIB file, sometimes Xcode will magically change some properties even if you haven’t touched it yet. I was very curious about that and wanted to know about the content of these XIB files and why they change.

The core

The first thing I did was create a script to convert the XML file into a JSON file and give the object a better and more visual representation. I wrote this script in JavaScript using Node because I was previously a full-time Node developer and still have some skills. It’s like a guy named Raʼs al Ghul passed those skills on to me.

First of all, I found that the values ​​that generally change are some kind of keys that Xcode uses to identify those elements. But my curiosity went a little further.

As I was looping through the JSON object of the converted XML file, I was seeing some kind of patterns and started writing some functions to group those objects together. Then I realized I had already grouped all views by type.

At that moment, I thought, “Hey, I can do a lot of things with this.” I started writing a map class that would take that array of objects and convert them into UIKit elements.

That’s how the core of this tool was born.

Mapper code
This is how the mapper looks

The name

After creating this script, I started using it in some views that I had to migrate to Swift code. To use the tool in the terminal, I had to give a name so that it would be easier for me to remember the command to execute every time I wanted to run the script. I called it xtos, which is an acronym for Xib to Swift.

Using xtos in the terminal
Using xtos in the terminal

The Dark Knight

Building the UI

A lot of people think that the Joker was just a villain with a mask. Others believe he was the representation of something else. Some developers think UI designers are some kind of villain, but I really think they are the representation of what our users want.

After using the script for some time, I thought it would be nice if it had some interface and thus not have to be running the script in the terminal and changing parameters.

When I started to think about how my application should look, I first started looking for some kind of inspiration. I found many different types of conversion tools. Some had a full-screen format and some had a fixed size, taking up the minimum space required. I preferred to go with the fixed size because I believe that screen space is something that all desktop developers should take care of. We must allow the user to have more than one tool open on the same screen at the same time. This allows for better usability when the initial input of our app is through dragging and dropping a file.

So I started by drawing a view that had only what was necessary: a section to drag the XIB file, some section for some kind of branding, and maybe some description. This was the first draft:

First draft
xtos first draft

After drawing what I wanted, I already had something to start with, so I created three wireframes of what could be the face of my tool:

xtos wireframes
xtos wireframes

After I had drawn the wireframes and had a more graphical representation of what my application would look like, I decided to go with the last variant because I found it to perfectly fit with what I wanted my application to be.

The identity

After choosing the wireframe, I needed to create the UI and give some identity to my application.

In this step, I started by opening Adobe XD and beginning to build the component library and the interfaces, always using the selected wireframe as a reference.

First, I chose a color palette that was in line with what I was doing, so I thought about things like the Xcode background, the XIB files’ icon color, and the Swift logo color. I already had three colors. Add a couple of colors for the text, the success screen, the error screen, and the buttons. For the text, I chose the Roboto font.

Roboto font

For the logo, I hired a designer. The logo has an S with a particle effect, but why the particles? In my head, one of the most representative things of a conversion are those chemical conversion processes that we saw in high school.

xtos logo
xtos logo

Now with the logo, wireframe, and visual library, it was time to build the UI, so I created three states for the app:

  • Default: It is the initial state of the application (when I open it and have not processed any files yet).
  • Success: This status is for when you have already processed a file and everything was successful.
  • Error: All applications must have an error screen. It is the universal concept of error handling.
Three states for the app

The Dark Knight Rises

The rise of something bigger

Many developers create small scripts to help them with their tasks. Many of the tools we use today are from those developers who brought that script from dark to light. As Bane said, “You think darkness is your ally? But you merely adopted the dark. I was born in it. Molded by it.”

I started making the application with pure HTML and CSS. I know, you’re saying, “Why?” Well, I’d love to say it was done with React, Vue, or something more professional, but the truth is I was just making a tool for my personal use, so I just put a couple of divs, added some JavaScript, and that was it. It only took a day to build the UI with that horrible plain HTML code, but it worked.

As I was writing the HTML code, I realized that the background was too flat. That was something I could not allow. To solve this, I added a div with a class called particle-js that gave the app an animation of particles while it is open.

HTML code
This is all the HTML code required for the xtos user interface.

Putting all together

Once I had the HTML code for my interface, it was time to put all the pieces together and prepare the tool to be used like any other application.

But how? Well, this is where Electron comes on stage.

It was very easy to take all the code and put it inside an Electron container. I just had to enable a few settings that allowed me to run the node inside the HTML, but that was it.

First, I added the listener to the drop zone div to allow the required behavior that lets the user leave some document here. After doing that, I just grabbed the document and internally called the xtos core to do the conversion. It was really easy to put those pieces together.

To export the file, I used the showOpenDialog function from the Electron API and wrote some code using the fs lib to copy the file to the destination path selected by the user.

So after all this process of programming, identity creation, interface design, and compilation, this Dark Knight rises.

Final version of xtos
xtos

The last step was to publish the tool.

To publish it to the store, I had to sign in and then upload it. I used electron-builder with the package type MAS and then sent it to the store.

And that was all. Now I have my tool available for everyone.

You can download xtos on the App Store.

What’s Next?

There is a lot of work to be done. I need to add constraint support, support for non-CocoaTouch XIB files, buttons, action connections, and a few more things.

Another good thing is to enable a SwiftUI conversion option. Can you imagine converting your XIB files directly to a SwiftUI class? Well, I hope I can do this soon.

For now, I am not planning to make this code open source because it is a bit messy. I am migrating the core from JavaScript to TypeScript and using React for the user interface. Then I plan to use a slightly more optimized electron boilerplate.

If you have any ideas to improve the tool, let me know in the comments.

--

--

✖Member of the @xteam, 👊🏽Software Engineer at @riotgames 👨🏽‍🏫Mentor at @FrontEndCafe 📢Speaker at @fundacionjaa ✍🏼Writer at @medium