Inside Scoop: How Mediafly Built Their Windows and Mac Apps

By Mediafly | August 6, 2015

Desktop-App-Header_V2

Passing the “go” decision to build the Windows and Mac apps for Mediafly SalesKit and ProReview was one set of challenges. Deciding and refining the feature list was another set. Now comes the fun part: building the application. This post breaks down the decisions that were made at several levels to design and build the newest additions to the Mediafly device family.

Underlying Framework

An early requirement for the application was that it must work on Windows 7+ and later Mac OS X versions. Given this cross-platform requirement, we discovered a number of possible frameworks to assist us. Each of these had positives and negatives, as we’ll describe here:

  1. Adobe AIR: AIR historically has been the leading cross-platform environment to build consumer-focused cross-platform apps. As it stands, Mediafly already has an Adobe AIR app, but given the complexity, significant performance limitations, and challenge for our customers to install and update the AIR runtime, AIR did not make the running for this iteration of our desktop application
  2. Qt: A leading environment for embedded apps. Formerly owned by Nokia, now Digia. The environment is well documented (at least on the surface), but, from our point of view, not very appealing visually. As well, commercial licensing can become expensive as we scale up. Finally, Qt would require a new environment and language to build apps
  3. Titanium Appcelerator: A very strong cross-platform development environment. Originally meant to target everything from PC/Mac to mobile, Appcelerator dropped support for Desktop in early 2012. So, this was not an option
  4. PhoneGap / Cordova: Very successful open-source project, but primarily built to support mobile. We expected that attempting to support desktop environments might be, well, challenging
  5. TideSDK: A legacy project, last updated August 2014. The project references TideKit, a new cross-platform development environment, but TideKit is not currently available for use or license.
  6. Chromium Embedded Framework (CEF): An open-source framework for embedding a web browser engine based on Chromium
  7. node-webkit (now called NW.js): An open source application framework that combines node.js and the Chromium rendering engine.

While initially low on our list, NW.js ended up winning for two, very significant reasons:

  1. We could reuse much of the frontend code we had built for the web viewer we had originally released in 2013. This would cut thousands of engineering hours out of our timelines, as we would have to build and maintain another user interface to simply launch the desktop application
  2. We discovered that other desktop apps that we were impressed with had been built with a basis of NW.js as well

Re-Using the Web Experience

The early tests with node-webkit proved successful, and now it was time to decide how exactly we would enhance the user interface to add desktop-specific nudges. After a lot of conversation, the team settled on the following:

  1. The web app’s web page is compiled as static HTML/JS/CSS and packaged with the desktop application.
  2. At runtime, custom CSS classes are injected into the DOM of the web page so that it is aware it is running as an app instead of a web page, allowing for desktop-specific styling.
  3. The desktop application has the ability to raise window events within the browser context that the web page can listen for and adjusts the UI accordingly.  This mechanism is used for handling desktop-specific events, such as when the application loses connectivity and needs to switch into offline mode. The web page catches this event and uses it to reveal indicators on content so the user knows what is viewable offline and what is not.

Supporting Auto-Update

Another early requirement was that the app must be able to update itself. From our previous experiences, keeping users’ versions up to date is incredibly difficult.

To support this, we attempted to use node-webkit-updater, and ran into a major challenge on Windows: due to the way NPM packages library dependencies, we would experience PATH TOO LONG errors attempting to unpack the update when the application’s hierarchy became too nested. The workaround for this was two-fold.  First, we now hoist deeply nested dependencies up higher in the application’s hierarchy to avoid the error during initial installation.  Secondly, we had to patch the updater to use a different library for the unpacking.  Unfortunately, this library does not handle permissions on Mac properly, so the unpacking is now handled differently for each platform.

Making It Installable

To ensure the Windows application could be packaged as installable.exe, we made use of node-webkit-builder to package the application and NSIS, an open source Windows installer builder, to make the Windows Installer.

We ran into several issues with node-webkit-builder:

  1. We saw the same PATH TOO LONG issue on Windows that we mentioned previously.
  2. NW.js supports two different methods for packaging an application.  The application files can either 1.) be run directly from disk, or 2.) packaged up into a zip file.  The advantage of having the applications zipped (#2) is a smaller application footprint. However, this comes with a performance hit.  Every time the application is run, it needs to be unzipped. This can greatly increase application launch times as the application size grows.  For the desktop application, we were seeing 20-30-second launch times on Windows when bundled this way.  While node-webkit-builder supported both packing methods for Mac OS X, it only supported the zip method for Windows.  Our solution was to handle the packaging for Windows ourselves.
  3. We experienced EMFILE/ENFILE errors while building the Mac OS X application.  node-webkit-builder had a long standing issue where the build would fail if the application had a large number of files.  We eventually surpassed this limit and could no longer build the app.  In digging into the issue, it turned out that the tool was attempting to copy every resource file (over 6,000 of them) simultaneously and relied on one of its libraries to handle the resulting errors gracefully for it.  This method proved to not scale well.  We created a patch capping the number of parallel copy operations in order to work around the issue.

Encrypting All Things

There are many, many layers of security built into the Windows and Mac application. One of the key areas includes ensuring all media and metadata are encrypted at rest on the device. We use nedb as our lightweight document store for all the metadata and encrypt all records with AES-256-CBC as they are serialized.  Media is either encrypted at the server, or encrypted as it is saved to disk, as follows:

  1. Streaming and offline video are encrypted at the server and delivered as Adobe HDS F4M from the server
  2. Documents are (currently) delivered as images over HTTPS. On receiving, they are encrypted and stored onto the disk. On view, they are decrypted on the fly

Supporting Offline

The application must be able to operate without an Internet connection. Users who have downloaded content previously should be able to launch, navigate, and view content while offline. To accomplish this, we built the app as follows:

  1. We built a poller that attempts to reach our servers once every 5 seconds. If the poller cannot reach our servers, the app is switched to Offline Mode.
  2. While online, every request for hierarchy, metadata or content is also cached for offline access in the future
  3. While offline, the app relies on the previously built up cache of metadata and content, and serves that up.

I hope you enjoyed this small taste of our process towards creating the new Mediafly Mac and Windows application. If you wish to learn more about this application, click the link below to request a tailored demo and give it test run!

Request Demo

 


Mediafly Executive TeamJason Shah
CTO
Jason Shah, a “Flyer” since 2010, is responsible for cutting-edge product development and engineering for the enterprise software company. His duties include overseeing all elements of product development, platform and integration engineering, platform security, customer delivery, and product marketing.

Comments are closed.