This video is available to students only

OS level drag and drop

This will be the last part of our course, and is by far the most complex, as we will look into how to emit events from the native side and listen for them in JavaScript, as well as implementing drag-and-drop in the OS level for our status bar item. This is something that I have seen no other app do before and you could create a whole slew of new apps with this. Think about file uploaders or file converters.... the sky is the limit!

In this lesson we will start with just the native side of things.

OS quirks#

Before we start we should talk a bit about drag-and-drop. Maybe you have implemented this in your web apps before. There are many libraries out there and the browser abstracts some of the work for you, but we are going to have to deal with the native APIs directly, and they work a bit differently.

We are going to register a list of supported types. This list is not only limited to files - we can register listeners for strings, files, specific image types and so on. So, here we will encounter the first difference: when you drag and drop a file from the computer file system, we will get not a blob but rather a URL, and it is then up to us to do something with this URL. We will create a copy in our app sandboxed document folder.

Another important difference happens when you drag an element out of another program, for example, dragging an image out of your browser. Here we will not get a URL or a file blob, but a promise object. We need to handle this promise and tell macOS where to download it.

There are many types you can register the app to listen for, so we need to be able to handle each case (more or less).

Registering our app for drop events#

We will start by registering our status bar button to be a droppable element. In AppDelegate add/change the following lines:

We first start by creating an array of valid types for dropping into our app (they have the NSPasteboard.PasteboardType type). For now we will register the URL, fileURL, png and string types. On the next line we create a type for the type of Promises you get when dragging complex objects (we mentioned dragging images from a browser). We finally put all of them into a single array.

Then when we create our status bar button, we call the registerForDraggedTypes function with our array of types.

Creating extensions for native classes#

We are going to create some extensions (and constants) for the base classes provided by Swift and XCode. An "extension" is a mechanism for adding functionality to classes without sub-classing them. For JavaScript developers this is similar to modifying the prototype chain of an object.

In our lib directory, create the following files:

URL.extension.swift

We are going to extend the native URL object to make it a bit easier to distinguish passed URLs. One useful thing is to know if the URL is an image (so we can display it) or if it is a localFile so we can copy it to our app's internal directory.

FileManager.extension.swift

We are also going to extend the FileManager class. The extractWhereFrom method does spelunking in the internal metadata of a file to extract where it was copied from. This could be the local disk or maybe a website, can be useful to display to the user where this file came from.

 

This page is a preview of Building React Native Apps for Mac

Start a new discussion. All notification go to the author.