Workflow to Retrieve Movie Data as MarkDown Text

Last week, I used up an iTunes gift card to get copies of Workflow and Editorial for iOS. In order to become familiar with the iOS Workflow application, I gave myself a little assignment to create a workflow that would retrieve the IMDB information for a movie, create some markdown text and create a new draft in Drafts. I then created this blog post completely on my iPad using Editorial , thanks to Federico Viticci’s excellent primer and actions.

You can get my movie workflow here.

Using the Movie workflow

The workflow requires you have Drafts on your device.
User steps:

  • Enter the movie Title;
  • Optionally enter the year.
  • Optionally rate the movie.
  • Select some descriptive movie tags for the entry.

The Drafts app will open, containing a new draft with markdown text for the movie. You can then use a drafts action to create a entry in DayOne or a note in Evernote.

Variations on a theme

My original goal for the workflow was to directly create a DayOne entry. I had a bit of trouble with Open X-callback URL (see below), and well, I rationalized that creating a draft is more flexible.

From Drafts, one can define an action to create a DayOne entry or create an Evernote note, or an action that does both. It is simple enough to modify the last step to call the appropriate Drafts action.

Another varient I wrote grabs the title from the clipboard and works as an extension. So for example, you could highlight the name of a movie in Safari and run the workflow from the Sharing menu. This is a pretty straight forward change to the begining of the workflow, and as such, is left to the reader1.

Finally, I have added this workflow as an action in Launch Center Pro. Whether I come across a #MovieToWatch later or one I just saw an want to remember and rate, I simply slide to the LCP action.

Details of the Movie workflow

This section represents notes to myself on the workflow implementation. My main intention was to discover how Workflow works, you may find some of what follows useful, or not.

The workflow is made up of the following sections:

  1. Capture Title and Year
  2. Query IMDB for Title and Year
  3. Parse JSON data in a dictionary
  4. Get user rating and tags
  5. Store IMDB data in variables
  6. Create markdown text
  7. Create text in target (Drafts)

Capture Title and Year

This is pretty straight forward prompt for each and store the strings in variables. A varient would be to get the title from the clipboard and not prompt for it, this avoids query errors from user typos.

Query IMDB for Title and Year

Use URL to create the query string and then Get Contents of URLs to call the web-service. The result of the IMDB query is JSON data, and stored in the variable imdbJson. If the query failed, the result will contain “Response”:“False”, in which case the user is promted to continue or not.

Parse JSON data in a dictionary

The result of the IMDB query is JSON data, a series of “key”:“value” substrings. Get Dictionary from Input parses imdbJson into a dictionary variable, imdbRes. The other string variables are initially cleared out.

Parse JSON data into a dictionary

Get user rating and tags

This section of the workflow provides examples of using Menu and List . Menu prompts the user to choose a path of execution. In this case, it is to rate the movie or not. A List of possible ratings is presented and a single rating is select using Choose from List and simply stored in a variable.

Menu and single item selection from list

For the movie tags a List of tags is presented, this time with the Select Multiple option in Choose from List To capture all of the selected movie tag values, iterate of the list and append it to the movieTags variable. The key here is to realize that Input holds the value of the current iteration of Repeat with Each; I found it helpful to “think like you are a processing stack”. At the start all of the values are pushed onto a stack. In each iteration Input becomes the top of the stack holding the value of one item. Each step of the loop concatenates movieTags with Input using Combine Text and stores the result in the accumulator/variable movieTags. At the bottom of the loop, the stack is “popped” and the next value on the stack is set to Input. N.B. if you would assign to a variable after the Repeat with Each block the value is the last item of the list, that is the last value of Input2.

Iterate over list and concatenate values

Store IMDB data in variables

Rather than scan the string directly returned by the web service, imdbJson, use dictionary variable, imdbRes to lookup values for each key . Get Value for Keyfinds a key in the dictionary and returns the associated value which is then stored in a similarly named variable.

Lookup keys in dictionary imdbRes

Create markdown text

Pretty straight forward concatenation of variables and markdown text.

Create text in target

I would like to take the resulting markdown text and use it as Input to a block to create an entry in another application. For Drafts it is pretty simple to use Create Draft. Specify a Run Action or to Edit in Drafts, either works well.
Markdown text to Drafts

For DayOne, I formed a URL using dayone://post?entry=Input and invoked DayOne via Open X-callback URL. This creates an entry in DayOne, but Open X-callback URL never returns and the workflow never ends. Perhaps I am missing something here.

x-callback failed to return

For Evernote, I thought I would convert the markdown to Rich Text and create a new note in Evernote, but Make Rich Text from Markdown crashed the Workflow app. These issues are why I have settled on creating a draft and running an action it.

More ideas

I am not sure what is possible here, so the next experiments for me :

  • Make the code that parses the IMDB string as a separate workflow. Then chain that with separate “input” and “output target” workflows.
  • Detect different ways the workflow was invoked and if as an extensiopn getting title from clipboard, otherwise prompt for title.

Thoughts on the Workflow UI

I have always cringed a little with a drag and drop UI to create control programs. This goes back to working with similar applications running on an Amiga. I get the idea that these applications are targeted for non-programers, allowing them to quickly become productive. I have no problem with that, well at least until the workflow needs to be “production quality” and grows in complexity. My sample is a quite long linear string of instructions and I found pretty hard to maintain.

The paradox of an intuitive, simple UI is that it can sometimes be perplexing. Often when scrolling screen through the workflow, my stubby, slightly arthretic fingers ended up moving an instuction and in effect unintentionally editing my workflow. When I did want to move something like a long IF control containing many steps in its “clauses”, the screen jumped around wildly and I felt as if I had no control of where the block would end up. In fact most often I had no idea to where it actualy moved. I found myself frequently sharing the workflow to Evernote, so that I could recover from accidental edits.

Really I am not complaining, just recording issues with which I had to deal. This was meant as a discovery exercise and was heavily influenced by some personal bias. I also recognize that there are other apps with more sophisticated programing/scripting capabilities. I think the Workflow app provides a great means to combine and control iOS apps. I think this has tremendous utility and power in it.

Some feature suggestions

  • Allow locking a workflow against edits, or have a “view mode” and “edit mode”.
  • Provide means to duplicate a workflow.
  • Provide a means to locally backup a workflow under development
  • Provide a way to collapse long nested blocks to promote readability and moving them.
  • Provide a way to add comments.3

  1. You can take the math teacher out of the classroom, but you cannot take the teacher of the mathematician. 
  2. There is an easier way to find the last item however. 
  3. Old-school stuff I know, but this is a control language, not self-documenting object code.