Remembering Steve Jobs

October 5th, 2011

I remember being at the Linotype-Hell users conference in Arizona where Steve Jobs was to give a speech at the opening night dinner. This was back in 1993 and Linotype was releasing a really cool pre-press system that could only have been created on NeXT computers. The company I co-founded at the time was also there, showing off some clever publishing software we created. The NeXT computer had been famously referred to as “the best machine for desktop publishing” by industry pundit Jonathan Seybold. We were all psyched.

Up until the last moment before the appointed time of Steve’s speech, our colleagues at NeXT were visibly nervous. They didn’t know if he would even show up. In the end he did, but for several minutes before starting his talk, he put everything on hold to play with his young son Reed, making shadows in the projector light. It was a perfect father/son moment, one that stood in marked contrast to the steely Linotype execs who were at that moment probably wondering what they’d gotten themselves into. Little did any of us know that the following Tuesday, NeXT hardware would be discontinued on what became known as Black Tuesday.


I have loved every minute of the roller-coaster ride that is being a software entrepreneur. It is a career option that like so many others, would not have been remotely imaginable without the amazing tools made by Steve Jobs and his genius colleagues. A few years back at a Stanford Business School event, I had the chance to personally thank Steve for all he has given the world. It was an awkward, fleeting moment, and I was completely tongue-tied. Later that evening I sent him an email in an attempt to better express my feelings. To my utter surprise and delight, he replied, saying: “Thanks John, all the best.”

No. Thank You Steve Jobs, you are my hero.

Traveling With MemoryMiner

April 6th, 2011

I caught the travel bug way back in the early ’80’s when I went on a high-school student exchange trip to a small seaside town in France called Les Sables d’Olonne. At the time, everything about France and the students I spent time with seemed so different: the fashion, the music, the food all so delightfully “foreign”. Fast forward nearly 30 years, and things seem much less different. The French in particular have long been concerned with preserving the “Frenchness” of their culture, but in the Internet age, that’s a hard battle to fight. Franglais is a durable cultural phenomenon, and its analog exists in most other non-English speaking cultures as well.

These days, wherever I go, I’m fascinated by the signs all around me of one big global cultural re-mix, and that’s exactly the type of stuff I love to document then present using MemoryMiner. I recently returned from a trip that took me to greater metropolitan Mortimer (outside Reading, UK), London and Paris. During this time, I was that annoying person who was constantly taking pictures, recording audio and shooting video. I drive my wife crazy when we’re walking down the street, and I’ll just stop for no apparent good reason. Good thing she wasn’t with me for this trip.

Why do I do this? Mostly because I can’t help myself: I’m fascinated by signs, graffiti, street art, mainstream commercial marketing, and how they all borrow from, and re-shape each other. As a result, when I take pictures, I tend to favor the oddball and the ephemeral. There are no fewer than 1.4 billion photos of the Eiffel Tower on Flickr and other similar sites. Am I going to take a better one? Probably not. The funny sticker attached to a trash can, or a bit of insightful graffiti? Now that’s what I’m talking about! I like to pretend I’m an archaeologist from the future trying to make sense of the culture whose artifacts I’m digging up.

Culinary Culture Clash

My favorite neighborhoods in any city tend to be those where you have different cultures butting up against one another. Edgware Road in London is one such place. There are lots of Lebanese restaurants and shops, competing for your attention with McDonald’s, KFC and other well-known global brands. If you were walking down Edgware you might notice a neon sign offering you “Pizza, Rice & Curries”. It looks like this:

Pizza Rice & Curries

Viewed from across the street, it’s immediately apparent that it’s actually a Subway shop: an American franchise known for its deli-style sandwiches (if you’re in the middle of nowhere and have no other option, you could do far worse).

Subway: My favorite place for Curry

After taking this picture I had to wonder about what motivated the folks who decided to offer curries at this particular franchise location. Were they trying to offer options for an older generation of immigrants whose teenage kids want to eat what their peers are eating? Were they trying to offer a “safe” place for American tourists to try something “exotic”?

The Reveal

Working on MemoryMiner has forever altered the way I take pictures. When I’m looking through the view finder, I’m constantly thinking of how I might zoom in to a specific area of a photo in order to play around with people’s perceptions of what they’re looking at. This is why the MemoryMiner Web Viewer starts by showing each photo zoomed-in to a specific selection area (if one has been defined), then zooms out when the user clicks on the image itself. It’s all about the reveal.

Another way in which I’ve changed the way I shoot, is that I often shoot short video clips, which don’t need editing (other than just a quick trim) which I’ll then attach to a photo. By now, all consumer cameras shoot at least decent video, while the iPhone 4 produces amazingly good video, especially for a device that you almost always have with you.

I put together a collection of photos and video that I recently shot and assembled in MemoryMiner. I hope you’ll find it interesting and will perhaps even inspire you a little bit. I encourage you to look through the photos one at a time, using the arrow keys on your keyboard to advance from one to the next. Several of the photos have attached videos or web links, which give a some additional depth and context: look for the white dot underneath the paper clip icon on the tool bar below each photo. (By the way, if you’re reading this post on a Windows machine, I hope you’re using Firefox or Chrome. If you’re on the Mac, the best experience is with Safari.)

Go ahead, have a look, I’ll wait…

Call for Participation

When I’m out taking pictures in public, I try to be discreet, asking for permission in advance whenever possible. However, it is a fact of life that in most urban areas, we’re all being recorded, whether we like it or not. In enclosed spaces like a subway (the mass transit, not the sandwich shop), or a crowded market, I’m sensitive to invading peoples’ sense of personal space.

Which brings me to an idea I’m working on for a MemoryMiner project for which I’d like your help. I’d like to document the varying experiences of riding mass transit in cities around the world. I’m specifically interested in having pictures of the types of advertising being shown, and to have audio recordings of the train, subway or bus moving in a sequence from one stop to another. Why? My best explanation is that I often wonder what goes through peoples’ minds while they’re in a crowded bus or train, stuck next to strangers and bombarded with advertisements of other beautiful worlds, such as a sunny beach. Anything to get their mind off what can oftentimes be a fairly unpleasant experience.

Here’s are two examples from the NYC Subway (the # 3 train, to be precise):

On the opposite side of the same train, you see this:

Meanwhile, you’re hearing this:

So, what are you supposed to think? “Man, being on this crowded train sucks, I need to get drunk/go on vacation/watch the game/do something else?”

Have you ever wondered about this, or am I the only strange one among us. If you take public transit and would be willing to send me some photos and an audio recording or two similar to the above, I’d love to include them in a future MemoryMiner collection. In addition to my gratitude and full citation credit, I can offer a free copy of MemoryMiner for Mac to anyone who participates.

If you’d like to join in this project, and/or have questions, please send me an email: john at memoryminer dot com.

I look forward to hearing from you as well as reading whatever feedback you have for this post.

Academic & Institutional Uses for MemoryMiner

November 19th, 2010

When I first created MemoryMiner, I was scratching my own itch. I’ve told the story many times, but in case you’re new here, you can read all about it, or watch this presentation. While I had mostly been thinking in terms of personal stories from my life, and the lives of my friends and family, I’d always imagined that the way in which the software shows the intersection of people across place and time could be useful in many different scenarios.

Indeed, when I first showed the software at Macworld in 2006, I had a number of people come up and say, “This would be perfect for X” where X is anything from ethnography, police tracking of gang activity, musical education, etc. etc. Over the years, I’ve enjoyed hearing about some interesting uses to which my humble creation has been put. I therefore hope you’ll indulge me a little paternal pride in my software…

MemoryMiner at Duke University

This past Spring, I began working with Brenda Neece, a professor at Duke University who curates the Duke University Musical Instrument Collection (that’s DUMIC to you and me). MemoryMiner was used in one of her courses where the student assignment was to tell the story of various musical instruments along with the composers and performers most associated with them. Here’s an example piece about the tuba. I particularly like videos that were used as attachments. Some were of the student demonstrating the instrument, others of famous performers in a wide variety of styles.

Brenda is working working on a new series of projects, including one on the Duke Chapel Organ, which I look forward to sharing with you soon.

Remembering a Lost City

My last post about localizing the web viewer talked about one of my favorite testers who put together a fantastic series of historical photos capturing the history of the city of Karvinná, a Czech town whose original old buildings disappeared due to the ravages of heavy coal mining. I particularly like the way in which individual buildings are highlighted: it really shows the value of being to step inside a single photo and thus make multiple assets from a single item. I often get the question, “Can I treat objects as People?” which this collection does very nicely.

If your Czech is better than mine, you might enjoy reading this landing page taken from the Czech National Archives which talks about the Resting easily project:

Karvinná Fotokronika

The Value of Open Data Formats like RSS

Using MemoryMiner definitely requires effort: it takes time and care to put together quality collections. I’ve worked hard to match the efforts of my users by continually improving the software, both on the Mac desktop and on the web. When publishing to the web, an RSS feed is created, which can be continuously updated. In fact, there’s a great screencast on the Support Section on working with collections which demonstrates this nicely.

For the last few months, I’ve been at hard at work with Marcello from Wrinkly Pea to create a really beautiful viewer application for iOS (that means, iPhone, iPad, iPod Touch) which can read the very same RSS feeds created for use by the web viewer. Here’s a sneak peak:

MemoryMiner Viewer iOS: DUMIC Collection

The User Experience is really smooth, and takes maximum advantage of the hardware’s performance along with the natural feel that comes from touch interfaces. I can’t wait to get it on the App Store. Feedback from early testers has been overwhelmingly positive.

The Digital Humanities Are Hot!

A recent New York Times Article on the “Digital Humanities” gives a fine overview of the different ways in which software technology is bringing new life to the study humanities in all its many forms. I couldn’t be more pleased to have MemoryMiner contribute to this movement. To that end, I’m super excited to have a couple of projects underway, including one with the fine folks from THATCamp Bay Area, along with another one with some crazy-cool filmmakers I met at the Los Angeles Idea Project recently. Tomorrow, it will be my honor to participate at a convening held The Oakland Museum of California to discuss ways to get the most out of a major new collection of political posters they’ve acquired.

I’ve got my hands full, so it’s back to the coal mine for me. I promise not to let it ravage me like the city of Kavinná.

Adventures in Localizing a Cappuccino Application

July 7th, 2010

One of my favorite beta testers for MemoryMiner 2.x is a Czech language speaker named Marek. Shortly after the release of 2.1—with its greatly improved web viewer—he whispered in my ear (loudly!) about the need to create a localized version of the web viewer. As he put it in an email:

“Just to explain: My MemoryMiner projects are focused on archival photographs and looking at a lot of mainly older people who can not even English …” [sic]

Prior to the Cappuccino version of the web viewer, he customized the template by modifying an HTML file. The index.html file in the Cappuccino version is merely a shell: all the magic is performed in Obj-J, and a good chunk of the user interface is archived away in .cib files. In other words, there was no chance for him to do the work himself.

Last fall, while working on the MemoryMiner Web Application, I noticed that in all the code samples I’d seen, people were using hard-coded strings, which is a huge no-no. At the time, I was too busy exploring to care too much. At some point, I innocently asked on the Cappuccino IRC channel to see if there was anything like NSLocalizedString() which is what one uses in Cocoa to work with localized strings in code.

Ask and you shall receive: I was pointed to this github gist created by Nicholas Small for CPLocalizedString():

I tried it out, and it works as advertised, with only one problem: it only supports one localization at a time. It also doesn’t address the need for localized .cib files.

Not wanting to leave poor Marek in the lurch for too much longer, this week I decided to revisit the issue. The first task was to come up with a way of supporting multiple localizations while providing a mechanism to determine the best match for a given user. Since web browsers can tell you which language they’re using, I used that as a starting point.

Here’s how I’m getting the browser’s language:

Using the language code (e.g “fr”), you can then enumerate a list of available localizations, each one identified by a key. To store the list of available localizations I added this key/value pair to the application’s Info.plist:


But, what if the user wants to use a language that’s different from the language they’ve set in their browser? This is particularly important since, for example, a French user might understand German better than English. To handle this case, I allow for a user language preference to be passed to the method that determines the locale to be used for the application:

Here’s the method I created:

For now, I’m getting the user’s preferred language from a URL argument, (e.g. “…&language=de”), but in the future it would be nice to create a graphical language picker and maybe store the preference in a cookie.

So, now that strings can be localized, here’s how you can (dare I say should) use them in code:

[sharingWindow setTitle:CPLocalizedString("sharingOverlayWindowTitle",
                                      "Share this MemoryMiner Story")];

If you read through the original gist, you’ll see that CPLocalizedString takes two arguments, the key, and the comment. On OS X, you can use a command line tool called genstrings which automatically generates strings files from your code. These files are given to a translator, a single entry for which looks like this:

/* Formatter for creating labels like "Item x of y" in Person/Photo Picker */
"itemCountFormat" = "Item %i of %i";

Again, noting the original gist, a final processing is used to convert the strings file into an XML property list. You could just as well hand the XML based property list to your translator (or better yet create an app for editing them!).

The end result? The images below show two different localizations, in German and Czech. You can click on either image to view the actual localized web viewer:

What about localized .cib files?

I’ve mentioned several times in previous posts that the Cappuccino framework is improving at very fast clip. Anyone who’s started their project anytime within the last year or so surely has a bunch of code for programmatically creating UI elements and placing them within views. The 280 Atlas application can radically reduce the amount of tedious coding to create your app’s UI since you work can work graphically with actual “freeze-dried” objects (e.g. windows, buttons, sliders, image views, etc.).

When localizing into certain languages (I’m looking at you German!) the length of a string translated from English can oftentimes be quite a bit longer. For this reason, the placement of text labels, or the size of your buttons may need to be adjusted. If you chose to create multiple cib files with different localizations, then it sure would be nice to have a standardized way to load them.

Here’s what I did:

* Create a simple convenience for getting the full path to a localized resource that would live in ~Resources/x.lproj where “x” is your language code such as “en”:

* Create a method for loading a localized cib file.

Here’s the code:

Now, in order to support localized .cib files, you simply create them in your language-specific *.lproj folders (e.g. ~Resources/fr.lproj/MainMenu.cib). Since the Atlas editor is pretty mature, I’m hard-pressed to return to creating my user interfaces in code, if I can at all avoid doing so.

A shortcoming of the localized .cib loading method at this point is that, unlike with Cocoa, it doesn’t gracefully recover if a localized .cib file is not found (i.e. it doesn’t load the default language .cib file). This could be done, but it’s a bit trickier. On the desktop, it’s fast, easy and cheap to determine if a resource is available on your local hard drive. To determine if a resource on the web is available is a bit more involved, but certainly doable in a future refinement.

Parenthetically, the topic of how best to localize .xib files in Cocoa applications has been much discussed. One very interesting approach is to programmatically localize at run-time, a practice used by the wildly popular Delicious Library software. The technique is discussed at length in this post by Wil Shipley:

I’d love to see a similar approach in Cappuccino. In many cases, it’s possible to configure your user interface to handle even the longest strings used for labels, etc. In some cases, though, it can look rather awkward. As a developer who cares about having localized applications, and knowing full well what a lot of work it is to produce them, I’m happy to have as many options as possible to make the job as painless possible. Most importantly, I’d like to see proper official” localization be baked right into Atlas and the Cappuccino source code.

I’m sure this will happen, but in the meantime, I’m happy to offer a complete gist with all the code and updated ReadMe, with the hope that it will be useful to others. Feedback and improvements are greatly appreciated:

The road to MemoryMiner 2.1

June 4th, 2010

I’m incredibly happy to report that MemoryMiner 2.1 is out the door. This release builds on hard-won learnings from the past six months, including a rather interesting project at Duke University which I’ll write about in a separate post. I had two major goals for this release. The first was a radical improvement in the Web Viewer to take advantage of the very latest in HTML5 technology. The second was the creation of a “soft landing” mechanism to help first-time users have a better “out of the box” experience with the application.

Web Viewer: Flash without the Flash

I’ve already written about using the Cappuccino framework to create the current generation of the web viewer. One of the great benefits of using this framework is that I was able to concentrate on refining the user experience while spending a minimum of time worrying about the vagaries of different browsers.

My partner in crime for this effort was Marcello Luppi, of Wrinkly Pea Design. Working with him was a pleasure. The general idea was to create a set of iconography and UI widgets that are clean and unobtrusive so as to make the photo be the hero:

New Web Viewer

Note how white dots are used to indicate the existence of annotation layers, such as maps, attachments and captions for each photo.

Embedded YouTube Video Playback

Note also how YouTube video is displayed using an overlay rather than in a separate browser window.

The great thing about the new web viewer is that just like on the desktop, you can pan & zoom between the various selection markers used to highlight certain areas of a photo. On Safari, which has hardware accelerated CSS transitions, the pan & zoom performance is equal to that of the desktop version of MemoryMiner. It’s absolutely better than anything I was able to do with Flash. In Firefox, the performance is not quite as good as using Flash, but quite good nonetheless. Hopefully, we’ll soon see hardware accelerated graphics in other browsers.

To see for yourself, click on the embedded photo shown below which opens a new window. When the first photo loads, click on it (or use the arrow keys). Click on the “i” button to view a short help text which highlights the keyboard and other shortcuts.

In order to make sharing easier, there’s a new option to get HTML code which uses an iFrame to embed a graphical representation of a specific photo in your story, just like you see above.

I particularly love this then & now picture-within-a-picture that I took of Steve “Scotty” Scott, the founder of the Mac Developer Network, who for more than a year now has been dumb enough to have me as his co-host on the MDN Show podcast.

The “Soft Landing”: providing a warm welcome for first-time users

The biggest challenge I’ve faced in marketing MemoryMiner is how to give a sense of what the application is all about within the first few minutes of contact with a new user. Those who view one of the screen movies tend to get excited by the app and therefore have a frame of reference when they first start using it. Those who simply download the application and stare at an empty library can easily get lost and frustrated.

To solve this problem, I created a simple HTML page which is displayed in a window when the user first runs the application. It looks like this:

MemoryMiner Welcome Panel

Users can now load a sample library which has a good number of carefully annotated photos, people, places and collections. As with a cooking demonstration, you want to give people an idea of what they’re trying to create. When loaded, the library looks like this:

MemoryMiner Demo Library

I believe this library does a good job of showing how MemoryMiner’s core function is capturing memories for the purpose of telling stories. I tried to include a variety of distinct photo types, each with some backstory that wanted to be told. My favorites are in the “Know Your Indie Developers” collection which reveal some choice tidbits about the lives of my fellow Indie developers.

If you’re an existing MemoryMiner user, you can get the upgrade to 2.1 using the usual Sparkle update mechanism. If you’re new to MemoryMiner, give version 2.1 a try.

Be sure to let me know what you think.

Stepping Inside a Painting With MemoryMiner

April 1st, 2010

Readers of this blog will know that I’ve enjoyed a longstanding and fruitful collaboration with Francesco Spagnolo from the Magnes Museum in Berkeley. Recently, he sent me a small MemoryMiner library containing an annotated painting. He told me he had used the full-screen editing feature during some presentations in order to highlight the various people and objects portrayed within the painting. Such work is what MemoryMiner is all about, so I was happy to hear that my humble little creation was useful in this context.

Here’s the painting in question:

In addition to the people in it, there a several important, recurring objects that are worth noting, which of course is easy to do using selection markers with small captions. Here’s an example:

When working on major new features in any software, it’s common practice to create a little “sandbox” application so that you test various features in a brand new, “clean” environmnent. While developing MemoryMiner 2, I created such an app which I called StepInside, and maybe one day I’ll officially release it. StepInside is somewhat like a “lite” version of MemoryMiner in that it simply lets you create annotations on photos. However, instead of storing the annotation data in a database, the annotations are stored in the photo files themselves using the most excellent Adobe XMP standard. You can seamlessly move photos between StepInside, MemoryMiner, and other XMP-savvy applications, and the all-important annotation work is preserved along the way.

This of course underlines one of the core ideas behind MemoryMiner which is that whatever annotation work you do, you should be able to take advantage of it as widely as possible. The Magnes has taken this idea to heart: MemoryMiner is used to create thoughtful collections of well-annotated photos and documents which are then published to Flickr, as well as to the MemoryMiner Web Viewer. This has been a great way for them (and other institutions who have have been inspired by the Magnes’ work) to expand their reach from physical museum spaces to virtual exhibits on the web.

By way of example, here’s the same annotated painting as it appears on Flickr:

All this is great, but what about using MemoryMiner in physical gallery spaces? During a recent visit to the Contemporary Jewish Museum in San Francisco, I noticed that one of the docents was passing around a magnifying glass so that people could get a better look at the pages exhibited in the extraordinary (and highly recommended) Our Struggle: Responding to Mein Kompf exhibit. There were so many details to be seen in these pages, and indeed, many of the details themselves made reference to some cultural phenomena that may not be obvious to any given viewer. The discussions amongst the viewers in reaction to the exhibit were fascinating in their own right.

So, what if you could combine the expertise of museum docents and the sheer intimacy of seeing physical objects in the company of other human beings with the unlimited resources of the web? The technical aspects of this, i.e. selection markers on images, hyperlinks, attachments, audio/video recording, etc. is something I’ve been working on for a while now.

My imagination thus sparked, I recalled one of the interesting bits of R&D I did last Summer which was embedding a web server into the StepInside application. Why would I do this? To be able to remotely control the application of course! The idea is that you could use an inexpensive Mac Mini to drive a High Definition video projection system and allow people to step inside high-def imagery using a simple remote-control software. On the back-end, only a few commands are needed: essentially, show next/prior image and show next/prior marker and some type of “get info” about each image. The remote-control app could be written as a native iPhone app or even as a simple web page: it just needs to be able to locate the web server which is easy to do using the “Bonjour” networking technology that’s been around for a few years now.

When you launch StepInside, the web server starts up automatically. Safari on both Mac and Windows lets you easily find local network web servers that advertise themselves using Bonjour. On the Mac, here’s the menu item:

If you click on the book mark, a very simple web page appears, which has a series of hyperlinks which demonstrate the remote control of the StepInside application. To see it all working together, I’ve put together a quick and dirty screen movie (no audio):

I think it’s time to get this technology out of the lab and into some museums or other institutions. I have two projects underway, and am always looking for others. If you’re interested, please do get in touch: john at memoryminer dot com.

I look forward to seeing where this goes.

PS For more background on MemoryMiner at the Magnes, have a look at the video about the Memory Lab:

Using Cappuccino to build the MemoryMiner Web Viewer

February 26th, 2010

When I first started working on MemoryMiner in December 2004, I had completely had it with building web applications. I’d spent the prior 8 years creating a sophisticated and completely web-based Digital Asset Management system using great server-side technology from NeXT/Apple called WebObjects. Being able to deploy our app from day one as a hosted-service was huge, but there was only so much you could do to make a web application come close to what was possible, user-experience wise, on the desktop. I was therefore utterly thrilled to work full-time with Cocoa, especially since I was completely familiar with its precursor from my days working on NeXTSTEP applications.

Still, the web is critically important for a project like MemoryMiner, and it has been this part of the adventure with which I’ve most struggled. From version 1.0 onwards, MemoryMiner for the Mac has been able to publish sets of annotated photos to the web using a self-contained story viewer. The first two versions were done in Flash (by someone else), and while they worked OK what amazed me was how much effort it took to do something that I thought should have been easy, namely to read an XML file with descriptive data about a bunch of photos and display them in a coherent, pleasing fashion.

Flash has its origins as tool for creating animated content. Tools for building applications using Flash came about much later in its evolution and weren’t available in 2005/2006. If you wanted to create 2D shapes and tween them about a stage, no problem. If you needed a scroll view to display a number of thumbnail images, then it was roll your own from scratch or license somebody else’s code. There were quite a number of different UI widget sets available, but all came with a different look and feel, and none of them really felt right compared to what one was used to on the desktop. Still, back in 2006, given the sorry state of Javascript performance in browsers and the lack of coherent libraries, Flash was the better choice.

Here’s an example of the Flash-based Web Wiewer:

MemoryMiner Web Viewer

Fast-forward a year and a half and the techniques of web development have improved dramatically as Javascript libraries such as Prototype and Scriptaculous came on the scene. I decided to try creating a new web viewer that didn’t need Flash. A big reason I wanted to ditch Flash was that the performance on the Mac was lousy. Prototype did a nice job of hiding some of the inconsistencies between the different browsers, while filling in a bunch of holes in the Javascript language. However, to do anything fancy UI wise, you have to devote a considerable amount of time learning the ins and outs of CSS. While indeed extremely powerful, it just wasn’t something that I, as a desktop application developer, ever really wanted to deal with.

Beyond styling, even basic behaviors such as having an image resize proportionally and remain anchored while the browser window is resized was maddening. Was I asking for too much? I could never get it to work consistently across IE/Firefox/WebKit, so I just gave up. On the plus side, the general performance was quite good (loading time, CPU usage). Still, it bugged the crap out of me that doing the most basic things proved so difficult.

Here’s an example of the Javascript-based Web Wiewer:

MemoryMiner Web Viewer

Fast-forward another year or so, and I hear about this web application called 280Slides and the Cappuccino framework used to create it. Playing with that app the first time was a revelation. I almost wept the first time that I started looking under the hood: the APIs and code syntax were immediately familiar to me as a Cocoa developer. I knew I could leverage a lot of know-how, and maybe even some code.

As soon as Cappuccino was made available to the general public, I started experimenting. How do you display an image using Cappuccino? You create a CPImageView instance and call setImage: passing it your CPImage instance. Works for me (and probably causes “traditional” web developers to roll their eyes). As a first experiment, I made a test app with the idea of creating a simplified version of the image annotation view I use in MemoryMiner for the desktop. I actually just started copying and pasting Obj-C code into a text editor, changing the class prefixes (i.e. NSImage becomes CPImage) and getting rid of pointers (e.g. NSImage *myImage becomes var myImage). Pretty soon, I had a view that could display a photo as well as draw selection markers (ummmm, drawRect:). Amazingly enough when I resized the browser window, things just worked. I didn’t write a line of CSS, I didn’t have to do one thing in FF/WebKit and something else in IE. This is what I was looking for!

By late Spring of 2009, I was pretty addicted, so I kept going with my prototype, adding the ability to create and edit selection markers, add captions to them and persist my model objects via a RESTful Rails back end. Mapping? Easy. There’s MapKit for that, along with a growing selection of high-quality third party code. Community? Got that as well. Among Cappuccino developers, I’ve found the same willingness to help each other out as we all strive for excellence.

This past fall, by the time I had mostly finished the development of MemoryMiner 2 for Mac, I spent about 2 person weeks finishing up on the MemoryMiner web viewer. When I was done, the biggest problem I had was that the deployment footprint of a Cappuccino application is quite a bit bigger than using something like jQuery or other javascript libraries. This is largely due to the fact that Cappuccino is designed for creating Applications, so you get a ton of functionality such as Undo, Key-Value Observation, etc. along with sophisticated UI widgets that you may not need in a read-only viewer such as I was building.

In order to get the initial load time to where I needed it to be, I created a single application that I host on a small slicehost instance, with the web server configured to automatically compress all the .j (Objective-J) files in my application. Between the compression, and the image spiriting techniques that were introduced late last year, I’m pretty happy with the load speed. It could certainly be made faster by eliminating some of the unused code and image sprite data, and I’m confident that this, or other optimizations will be made. All you have to do is take note of the progress made by a tiny team in a rather short period of time.

Best of all, unlike the old system where each web viewer instance had all the code needed to display the content in the same folder as the content itself, the new system works by simply redirecting to the hosted web viewer app’s URL, passing the published RSS feed as a variable in the redirect URL. This means that once a user looks at their first published MemoryMiner viewer, any subsequent loading of any other story viewer will have the viewer code already in the browser’s local cache. Improvements made need only be made once in one place, just like in the “good old days” at my prior company.

Here’s an example of the Cappuccino-based web viewer:

MemoryMiner Web Viewer

While my first publicly shipping Cappuccino project is a read-only viewer, I’ve been working on a full-blown version of MemoryMiner for the web. It’s currently in early Alpha testing, and the feedback thus far has been extremely positive. The viewer and the app actually share a fair amount of code. Most importantly, both use the same Model View Controller design patterns we all know and love. My MMSSelectionMarker class in Cappuccino is virtually the same as its cousin on the desktop: the main difference is that one is persisted in a local sqlite database, the other in a web-service. Believe it or not, I’ve become pretty comfortable moving code back and forth between desktop and web. I implemented undo using Cappuccino before doing the same in Cocoa.

Still, compared to developing with Xcode & Interface Builder, developing a Cappuccino app still feels a bit primitive Fortunately, as Cappuccino has matured, it has been getting better tools, such as 280Atlas which lets you compose your UI layer graphically using real “freeze dried” objects that connect to each other using the familiar control-click and drag mechanism just like on the desktop It’s essentially IB and Xcode mixed together.

For whatever reason, people can easily get into flame-wars about web apps vs. desktop apps, and this toolkit vs. that toolkit. For my part, I really don’t care. I want MemoryMiner to be a person-centric application. Generally speaking, people want to interact their stuff on whatever device they happen to be using. I’ve found that Obj-C/Obj-J and Cocoa/Cappuccino give me lots of leverage because of the dynamic nature of the language, the richness of the frameworks and the availability of quality third party code. Others will say the same thing about Java/C#/Ruby/Python, etc. etc. To each their own, but if you’re a Cocoa developer and care at all about the web, you’d be crazy not to give Cappuccino a serious look.


January 19th, 2010

Ask almost any indie Mac developer what the best thing about developing for the Mac is and they’ll tell you it’s the community of developers. I’ve found this to be the case ever since I started developing MemoryMiner back in 2005. In fact, there was a guy who named Justin Williams who early on gave excellent and thorough UI feedback, and put me in touch with Robert Anderson who helped me enormously early on. I couldn’t believe that he took so much time to help someone whom he’d never even met. Amazingly enough, he was hardly the only one to have helped me along the way (check the About MemoryMiner for this long list of people).

Fast forward almost five years, and the same Justin Williams has, in conjunction, with Garrett Murray put together an incredible project to raise money for the Haitian Earthquake relief efforts. The project is called Indie+Relief and the concept is simple: over 200 indie Mac and iPhone developers have agreed to donate a day’s worth of their sales to a variety of respected relief agencies.

I’m enormously happy to participate in this effort and so will be donating 100% of gross sales from MemoryMiner for 24 hours day starting midnight PST on Jan 20th. I’ll be making my donation to Doctors Without Borders whose work I greatly respect.

So, I invite everyone to visit Indie+Relief, buy some fantastic software, and in the process help ease the massive suffering going on right now in Haiti.

MemoryMiner 2.0.5 Now Released

January 12th, 2010

Whenever you make a major release of software, you always worry that there will be bugs that weren’t found during testing. I’ve shipped enough software on enough platforms to know that there will always be problems that appear after you ship.

This said, I’m happy to announce that version 2.0.5 is now available. It offers some important bug fixes. You can get the release by simply choosing “Check for Updates” from the MemoryMiner menu. Release notes here:

MemoryMiner 2.0: One Week In

December 30th, 2009

It’s been been just over a week since MemoryMiner 2.0 was released. This version was way too long coming, but such is the nature of software sometimes. As I’ve said many times on the MDN show (a podcast for indie Mac developers on which I’m a co-host) finished software does not a product make: you need to put a serious effort into all the supporting parts such as a website, PR efforts, screen movies, etc. etc. Getting all this together is part of the reason why MM 2.0 took longer to get out than I would have liked. I think the new web site turned out quite nicely, so many thanks to Martin and Fabio at MCubed Design for their work. The old MemoryMiner website was getting long in the tooth, so I decided to strip it down then fill it in with new content. There’s still work to do here, but so far, so good.

Invariably, whenever you make a major new release, there will be a few bumps as brand new users discover things that even the most ardent beta testers can miss. For this, I’m incredibly grateful for the Sparkle Framework, and the Shine project for making it much easier to to create, release and track updates.

I’m pleased to report that the existing user base has been upgrading at a very swift rate, which I take to be a good sign. Releasing a consumer product late in the holiday season is always a challenge since people tend to be distracted. Slowly but surely, I hope to get the word out with some good coverage in the usual places.

In the meantime, I invite everyone to tell 50,000 of their closest friends about MemoryMiner 2.0!