red sweater blog
This App Is Your App
One of the challenges existing Mac developers face with the Mac App Store (MAS) is whatever copy protection you have been using up until now has to be thrown out in favor of a protection scheme based on Apple’s App Store “receipts,” a tiny cryptographically signed file they place inside purchased applications that let your app confirm the authenticity of an application upon launching (and at any other time).
This leads to a conundrum if you continue to sell software directly, or offer preview beta releases for direct download. How can you offer access to these releases for customers who purchased through the MAS and thus do not have the “Registration Code” that direct-purchase customers receive? Apple provides no means of determining the identities of, or contact information for, authorized MAS customers. But even though I don’t know who these customers are, I want to treat them as first-class customers in every regard.
For me, I decided that the compromise is to provide, for those MAS customers who want it, full access to the direct-download versions of my software. Today, any customer who buys a MAS edition of my applications will find that, after running that edition at least once, they are automatically authorized to run direct-download versions of the app from that time forward.
A Recipe for Mass AuthorizationHow did I achieve this bit of wizardry? And more importantly, how can you, or other developers whose apps you love, achieve the same thing? There are three major code-level changes that I needed to make. I’ll discuss those changes, and some of the potentially non-obvious considerations to keep in mind while making them.
-
The MAS edition must stash its receipt somewhere obvious for the direct-download edition to find it. Because both editions of my app share a common Application Support folder, I chose to store them here. Inside the Application Support folder, I create a subfolder called “App Store Receipts” that contains the pertinent receipt files for this app.
Why a folder? Because a customer may sync or copy their App Support folder across various Macs, I chose to store each receipt keyed by the computer’s GUID, which is derived from its wired ethernet MAC address. Developers who have implemented app store authentication will be familiar with this value.
-
The direct-download version must, in the event it is not already authorized by a standard registration code, look for secondary validation in the form of a receipt in the aforementioned location. If it finds a receipt, the same type of validation is performed on the receipt as would be performed in the MAS edition.
You will want to apply some lenience when interpreting the validity of the receipt. For example, you probably want a receipt authorizing version “3.0″ to also be considered valid for “3.0.1″ or “3.0.1b1″. Similarly, if you use separate bundle IDs for your MAS and direct-download editions, you will want to consider the MAS bundle ID as valid for the direct-download version.
-
If you used a different bundle ID for your MAS and direct-download editions, then for the sake of the users sanity and yours, you probably want to implement some kind of transparent migration of preferences from one edition to the other. You don’t want customers to have to go in and reset all their preferences when they switch, and it can be annoying as a developer as well.
I had some preference migration code around from when I transitioned MarsEdit and Black Ink from their previous companies’ bundle IDs to mine. I reused that transition code, with a bit of careful but appropriate logic: if the other bundle ID was modified more recently than mine, then import it and replace my defaults. The same logic is applied in each edition so that whatever version you run, you’ll feel as though you’ve picked up all the latest preferences from the last time you used the app.
With these changes in place, I have the flexibility to offer direct-download versions of my software to any MAS customer who asks for it, or for customers who I request the assistance of in testing a pre-release bug fix. In most cases, I can just ask the customer to run the app. In the worst-case scenario, when a receipt has not yet been “stashed,” I have only to ask the customer to run the MAS edition once before trying the newer release.
Pitfalls and DownsidesThis solution isn’t perfect. In particular, it brings MAS customers into the fold for direct-download software, but does nothing to soothe the existing and new direct-purchase customers who wish for access to the benefits of the MAS: sharing reviews, mass-updating purchased software, etc.
Worse, it leads to a potentially confusing situation where a customer may be running version 3.0 of an application that they direct-downloaded before Apple had approved it. When Apple does approve it and it goes live on the MAS, they are notified inside the App Store about the available update, but when it does update, it will update the previously installed MAS version, and not the direct-downloaded one. To benefit from the Red Sweater compromise, customers need to embrace the mental model that MAS and direct-download versions of the application are fundamentally different, and need to be managed and stored separately from one another.
I believe that the people this compromise serves are in general a more technically astute type of customer who will be able to embrace this difference, or will understand it with little explanation on my part. The less technical customers are not liable to be on the lookout for beta releases or “day of” releases of new software, and will happily wait until the MAS notifies them of a standard, Apple reviewed update.
Black Ink 1.3
I am happy to announce that after a short, productive beta release period, Black Ink 1.3 is now available for direct download and through the Mac App Store (has been approved but may take a little while to update in the store).
- New web puzzle sources
- LA Times Daily & Sunday
- Newsday
- USA Today
- Universal
- Rework the Startup preferences to be more user-friendly with reopening puzzles
- Give keyboard shortcut Cmd-K to “Check Current Letter”
- Now includes automatic crash reporter
- Fix a bug that caused Black Ink to hang when printing on rare occasions
- Fix a bug that caused puzzle timer to be placed off screen edge
- Fix a bug that could prevent puzzle solving menu items from being enabled
- Fix a bug that prevented canceling a stalled puzzle download from working
Enjoy!
Black Ink 1.3 Beta
The success of Black Ink on the Mac App Store has motivated me to get busy working on a number of improvements I have been planning for some time but just hadn’t found time to do.
The big deal in 1.3 is that I added support for a different format of puzzle that opens up Black Ink to a number of new sources for more solving fun.
Because I don’t have a strong, established beta testing group for Black Ink, I’m opening this up as a public beta to get any bugs ironed out before it goes public for the Mac App Store and direct-purchase customers. If you’d like to test out, just download and give it a spin!
Be sure to drop me a line if you run into any problems, but also if you are interested in being part of a more permanent Black Ink beta testing group. I’m going to try to get organized for future, private testing rounds.
A round-up of the changes to expect in this release:
Black Ink 1.3b1- New web puzzle sources
- LA Times Daily & Sunday
- Newsday
- USA Today
- Universal
- Rework the Startup preferences to be more user-friendly with reopening puzzles
- Give keyboard shortcut Cmd-K to “Check Current Letter”
- Now includes automatic crash reporter
- Fix a bug that caused Black Ink to hang when printing on rare occasions
- Fix a bug that caused puzzle timer to be placed off screen edge
- Fix a bug that could prevent puzzle solving menu items from being enabled
- Fix a bug that prevented canceling a stalled puzzle download from working
- Encoding issues with Newsday 2/4/11 characters
- Documentation not updated to reflect reworked startup preferences
- Puzzle icons in startup window get smaller if window closed and reopened
- Newsday, USA Today, and Universal have generic icons for now
Enjoy!
MarsEdit 3.1.6
MarsEdit 3.1.6 is now available for direct update for customers who purchased through the Red Sweater Store. A Mac App Store version has been submitted and will hopefully be approved by Apple soon. Update: as of February 3, MarsEdit 3.1.6 is available on the Mac App Store.
Important aside for App Store customers: I am working on a solution that will, in the future, allow those of you who bought through the Mac App Store to also run newer releases before Apple has approved them. Until then, hold tight for Apple to approve this release. Things will get better!
This is an incremental bug-fix release and addresses a number of small nuisances and some rare crashes.
- Media manager and image upload improvements
- Use a nicer format for default alt text description
- Fix the file extension of image file name to match the actual format
- Fix a bug where e.g. PNG images were converted to JPG when resizing
- Auto-convert image formats not suitable for web to PNG
- Fix a possible crash when searching for photos
- Fixed the Convert Line Breaks filter so it doesn’t add paragraph tags to preformatted text
- Fix an occasional crash when doing a global search/replace
- Fix possible crash when mistyping keyboard shortcuts in the app
- Add a special error message for situations where Tumblr is not responsive
Toggle Twitter
I use Twitter. A lot, and almost entirely on my Mac desktop. Over the years, I have switched between many popular client applications, often returning to old favorites when the specific advantages of one outweighs the advantages of another for my current priorities.
The way I use Twitter is to leave one of these client applications running in the background, with all the notification settings set to off. I still check it quite often, but it’s on my terms. If I get deep into concentration working on some bug, chatting with a friend, or or watching a video, I don’t want Twitter interrupting me.
Twitterrific was the first desktop client I used, and I can’t remember whether it was the default choice or if I picked it, but I got in the habit of using the global keyboard shortcut Cmd-Ctrl-T to toggle the window’s visibility. When I tried other Twitter apps, I made a point of setting the preference in that app to match the same shortcut.
Eventually I tried an app that didn’t support a setting for a global keyboard shortcut, so I had to write a script to do it for me. It occurred to me at some point that I could write a single AppleScript to handle the toggling of visibility regardless of which app I was using.
The script logic is pretty simple: given a list of common Twitter app-names, is one of them running? If so, toggle it. If not, launch it. If you’re using something else, just add it to the list, and it should work perfectly.
I used FastScripts to hook this up to the global shortcut Cmd-Ctrl-T because it matches my historic muscle memory, and well, T is for Twitter.
Blast From The Past
Following the cues of friends Shawn Blanc, Marco Arment, and Neven Mrgan, among others, I’m digging in to the Red Sweater Blog archives to find some older posts that I think are worth reading, if you missed them the first time around.
I love the idea of highlighting things that others have written, but since I don’t have a convenient repository of these items, and haven’t got time to scour my mind for suitable candidates, I’m sticking to what I know best. Presented here with a brief synopsis:
- Adiós a las Computadoras Dell. On the eve of Apple’s transition to Intel processors, I speculate that the end is nigh for Dell.
- Magical Code. Based on my experience working at very low levels inside Apple, and on my own high level stuff, I dispel the notion that any code is so magical that you can’t understand it.
- Five Things I May or May Not Know. Particularly meaningful for folks who are grappling with the idea that their full-time work is not for them, and are toying with the idea of branching out on their own.
- The Road Less Traveled. The story of my transition from a full-time Apple engineer to a self-bootstrapped software business owner.
- Forget the Shortest Path. Wisdom inspired by lessons in sailing. Sometimes moving directly at your objective is not the most pragmatic way of reaching it.
- It Should Be Free. My reaction to the expectation among some customers that things should be free. I dig into the true cost of “free” things.
- Getting Pretty Lonely. My rant against the GPL open source license.
- Elements of Twitter Style. My fairly recent prescription for getting the most out of Twitter, while annoying the fewest.
Thanks, as always, for your attention to my blog and my writing.
Instapaper Keyboard Shortcut
Like many people these days, I am using Marco Arment’s Instapaper to facilitate effortless postponement of reading longer, potentially interesting content I find on the web.
Marco provides a handy bookmarklet that you can add to your browser’s button bar, so when you find something cool you just click “Read Later” and it gets added to your Instapaper collection. This is handy, and if you’re using a browser like Safari, these bookmark bar items even get mapped to default keyboard shortcuts based on their position, e.g. Cmd-1, Cmd-2, etc.
My news reader of choice, NetNewsWire, also supports Instapaper, allowing me to easily add any news item’s underlying content to my “Read Later” list. In NetNewsWire, the keyboard shortcut is Ctrl-P (for paper!), and I’ve gotten hard wired to punting stuff to my reading list with a quick flick of the keys.
For months I’ve thought it would be nice if I had the same workflow in Safari and in NetNewsWire: see something, want to read it, don’t have time, press Ctrl-P. I don’t know why I took so long to sit down and spend the 5 minutes it took to write an AppleScript wrapper for Marco’s bookmarklet, and install it in my scripts folder to invoke with FastScripts.
If you want to be cool like me:
- Download and install FastScripts. Free for up to 10 shortcuts!
- From the FastScripts menu-bar icon, select FastScripts -> Create Safari Scripts Folder.
- Download this script, and move it to the Safari-specific scripts folder: [Home] -> Library -> Scripts -> Applications -> Safari
- Switch to Safari.
- While holding the Cmd key, select “Read Later” from the FastScripts menu.
- Assign a keyboard shortcut of your choice. (Ctrl-P for NNW-likeness).
Now whenever you see a cool page in Safari, just press Ctrl-P to instantly tag it for later reading.
Update: David Kendal observes on Twitter that you can assign custom keyboard shortcuts to bookmarks in Safari by simply using the System Preferences Keyboard Shortcuts and assigning to the correctly named bookmark. I was not aware that this would work with bookmarks! Very cool. It diminishes the necessity of the above workflow considerably, though I was pleased to be able to take “Read Later” out of my bookmarks bar. Another downside to the System Preferences route? Apparently the keyboard shortcuts will never take effect until you’ve shown the menu that they appear in at least once per Safari-launch.
The Mac App Store Debug Menu
I can’t help myself. It’s probably worth noting that nobody knows for sure what these options do, and you might do serious damage to your Mac or your App Store account by playing with them. But … just a look can’t hurt … can it?
- Quit App Store.app
- Open Terminal
- defaults write com.apple.appstore ShowDebugMenu -bool true
- Relaunch App Store
Enjoy it while you can. I’m sure it will be gone in the next update, especially if anybody at Apple sees this post.
The Future Of Mac App Store Installs
It’s only been one day since the launch of the Mac App Store, and the Mac developer and user communities are buzzing with consequences, both good and bad, of the store and how it operates.
One particularly vexing issue is the question of whether an app that is already on your Mac is “installed” or not in the eyes of the App Store application. Dan Moren of Macworld presents a great summary of the situation.
In a nutshell: if App Store thinks an app is installed, it’s impossible to buy it. If App Store thinks an app is installed, but it’s not really from the App Store, there’s a risk of repurchasing something that you already own a license for.
What this brings into focus is the very problematic nature of that small multi-purpose button the App Store, that allows for either buying an app you don’t own, or for linking to an app that you do own:
As it happens, the App Store user interface is implemented primarily in HTML. Using a surprisingly under-appreciated feature of WebKit, the omnipresent web inspector, I was able to look behind the scenes at some of the interesting HTML that supports this Buy/Installed button. For Black Ink’s button above, this is what I see:
<button version-string="1.2.3" is-rental="0" is-pre-order="0"
buy-params="productType=C&price=24990&
salableAdamId=402376365&pricingParameters=STDQ"
preflight="http://a1757.phobos.apple.com/us/r1000/ 057/Purple/e7/fb/12/mzm.gytejomu.pfpkg"
is-install-button="0"
large-icon="http://a1.phobos.apple.com/us/r1000/013/ Purple/74/8c/bb/mzi.wpgwhzjm.170x170-75.png"
is-update="0" item-name="Black Ink" adam-id="402376365"
is-free-download="0" bundle-id="com.red-sweater.blackink.macappstore"
metrics-leaf="1" metrics-loc="Buy" title="Buy, Black Ink: $24.99"
disabled="" its-bound="iTSBuyButton">
<span class="price"></span>
<span class="action">Installed</span>
</button>
Formatting XML, even with a cool app like MarsEdit, is still a huge pain. I’ve tried to make it readable here so you can enjoy some of the interesting tidbits in this markup. There are some tantalizing attributes like is-update and is-free-download, which might lead some of us to imagine whether a paid update may be a configuration away. There’s some hocus-pocus sale parameters which surely mean something to iTunes on the other end of the network connection, and there’s a link to the application’s pretty icon.
Wondering about that global web inspector trick? Any application that has the NSUserDefaults key WebKitDeveloperExtras defined to YES receives access to the sexy WebKit web inspector that is so awesomely utilized in Safari. You can define this for the App Store app by running this from the command line in a Terminal window: defaults write com.apple.appstore WebKitDeveloperExtras -bool true Make sure you quit App Store before you run it, then relaunch it.
But What’s Really Interesting…All of this is fun to poke around at, but what I find fascinating is the preflight attribute, which points to a mysterious asset on the web. This “.pfpkg” file, which as it turns out is simply xar archive format, contains an interesting file called Distribution, an XML-formatted file that contains rules and attributes for how the application should be installed, how the App Store should locate an “Installed” app on the user’s Mac, etc. I’m not going to the trouble of color formatting this one, but have a look in a separate window:
View Black Ink’s Preflight Rules
I believe the format for this XML document is either completely or partially tied up in the way the Mac OS X Installer packages work. I have been lucky enough in my lifetime not to have to do all that much with installer packages, so I am not sure exactly how to parse the whole file. It’s clear however, that the file contains information about the application, its version and bundle identifier. It also contains similar information for each of the frameworks that ships with the application.
But the interesting stuff begins below that, where we see flags such as customize=no, and an alluring volume-check, which seems to be terminology from Installer-land that alludes to installers being able to determine whether the targeted volume is suitable for installation.
As you can see, the Black Ink preflight document is pretty boring. No, there is no customize flag. No, there are no interesting volume-check attributes, aside from the fact that this requires 10.6.6, like every other dang app on the Mac App Store. Yawn.
I decided to take a look at another application in the App Store. One that, if anything was going to be interesting, surely this one would be.
One of the things I keep reminding myself, when trying to deduce what Apple’s plans are for a variety of “would be nice” features in the App Store, such as upgrades, trials, etc., is “how does the current setup inconvenience Apple itself?” Many of Apple’s apps are shipped for free with the system and are updated for free along with OS updates. But others are not: iLife and iWork are sold in a bundle with no upgrade pricing, and other apps such as Final Cut Pro and Logic have complicated pricing, which perhaps explains why they aren’t on the App Store at all. But Aperture falls right in the middle: fairly straight-forward pricing, but it’s expensive enough that they offer reasonable upgrade charges for users who already own a license. Maybe there will be something interesting in these preflight rules:
View Aperture’s Preflight Rules
The file length alone indicates that something slightly more complicated is going on, and my eyes are drawn immediately to the JavaScript code in the middle of the document, and a function named shouldAllowPurchaseAndInstall(). Hmm, you mean there’s a choice? Usually what happens when you click “Buy” in the App Store, is you are prompted to login if necessary, and then you are warned that this is going to cost you money, it’s a big deal, etc. But as far as I can tell, a side-effect of clicking Buy in the App Store is that the aforementioned volume-check is also run on the target system, giving App Store one last chance to bail out of the process before something unfortunate is done.
In Aperture’s case, you can see by the nicely commented script that it takes care to only allows the Buy order to go through under certain circumstances. In making this determination, it checks all of the installed copies of Aperture on the system, looking for signs of App Store purchase such as the presence of a “_MASReceipt” inside the app. It also takes care to differentiate between different versions of Aperture, failing in some cases with a specific string that is presumably passed along to the App Store user.
If you’ve managed to follow along this far, you’re probably putting two and two together and realizing that the technology exists today for applications to avoid at least one of the problems mentioned above: the inadvertent redundant purchase that may happen when a user thinks it’s safe to buy an app, because “they already have a license.”
The preflight XML document may be documented in part or in full in the context of Mac OS X Installer Packages, but as far as I know, none of this is documented in the context of the Mac App Store. I do not know if any 3rd party developer has been invited to use this technique, or if it’s something we could just put into our installer packages somehow on our own, and hope for the best.
What’s most interesting about all this is that there is clearly an infrastructure in place for allowing a wide variation of behaviors, all centering around the multi-purpose Buy/Installed button in the App Store. I would like to see the volume-check options documented and made explicitly available to developers, so that we can help prevent unwanted redundant purchases on the part of our customers. I would also be curious to know if other hooks are in place or are planned to for example allow developers whose apps do show up as installed to second-guess that assumption and encourage the App Store to provide a “Buy” option to customers.
Where we’re going, only Apple knows, but I thought the details I discovered in this nook of the App Store app offer some interesting clues. I’m also interested in sharing this because I believe that the more we understand about the App Store install process, the better we’ll be able to offer meaningful enhancement requests to Apple. “Support paid upgrades” and “Allow variable behavior depending on installed apps” are fine feature requests, but if we are able to put them into the context of what Apple already knows is possible, they may be more likely to get implemented.
If anybody else has delved into the underbelly of the App Store and has observations to share, please do so in the comments, or with a link to your own blog article on the subject.
The Mac App Store
I am happy to announce that MarsEdit and Black Ink are now available for purchase on Apple’s Mac App Store.
As I expected, the Mac App Store is both an exciting new platform for reaching new customers, and a somewhat frustrating and difficult to explain territory when it comes to existing customers who are interested in the benefits of the Mac App Store, but who already own licenses to my software. Allow me to answer some questions that I have already been hearing quite often.
I already own your software, how can I migrate my purchase to the Mac App Store?So far Apple has not indicated that there will be any mechanism to migrate existing paid customers into the Mac App Store update process. For existing customers, my applications will continue to receive regular updates outside of the App Store mechanism. I hope that Apple will come up with a solution to allow us to migrate folks who prefer the App Store into that workflow.
Some of you may have noticed that apps from some companies show up in the App Store app as “Installed” even though you purchased them outside of the App Store. I believe this is a quirk in the way the App Store works, and for example you will not be able to review or update these apps through the store. In a nutshell: the App Store app is confused into thinking that you bought the app through Apple, and this is causing many customers to believe that developers have found a way to “migrate” them onto the store. I don’t believe this is the case.
Is the Mac App Store version different from the version I can download from your site?The Mac App Store and site versions are identical in core functionality and features, but there are minor differences having to do primarily with the update mechanism. The version I sell directly still updates itself, while the version from Apple can only be updated by Apple and is dependent on Apple’s approval schedule.
I have an older version of your software, can I get upgrade pricing on the Mac App Store?At this time the Mac App Store does not allow for variable pricing based on customer qualification such as a previous purchase. Discounted upgrade prices are still offered from our own store.
Is it possible to download a trial of your software before I commit to buying it on the Mac App Store?The Mac App Store doesn’t have an official mechanism for downloading trial versions of software, but you can download the standard trial version of my applications from the respective product pages. If you decide to purchase the application on the Mac App Store, you will be able to download and install a separate, authorized copy from Apple through the App Store interface.
I have another question that you haven’t addressed.I am always available to answer your questions. Please get in touch by email or through the forums.
MarsEdit 3.1.5
MarsEdit 3.1.5 is out, with a few bug fixes, and support for editing excerpts in Squarespace blogs. Thanks to the Squarespace team for updating their API to allow for this.
MarsEdit 3.1.5
- Now supports editing the Excerpt/Summary for Squarespace
- Dragged images now open the upload utility with the correctly targeted blog preselected
- Fix a bug in upload utility window that didn’t update UI correctly when blog switched
- Restore ability to attach image-uploads for separate blog to Tumblr posts
- Fixes to prevent some rare crashes with HTML syntax highlighter
- Fix crashes affecting the Media Manager when editing photos in other apps
Information Wants To Be Everywhere
I followed an interesting link from Daring Fireball, relating to recent debate about WikiLeaks. Nelson Minar reaffirms the often-stated aphorism, apparently attributed to Stewart Brand, that ”information wants to to be free.”
I think this is a useful way of thinking about it, but it’s insufficient for describing the way that information actually travels. Even taking to heart Minar’s reminder that information can’t strictly “want” to do anything, the suggestion that it even tends toward or prefers freedom is not accurate.
Information is like water: it wants to be everywhere. Unlike say, a person, who will almost universally want to be free. Information in a cage will not rattle the bars, or scramble frantically to reach a just-too-distant key. On the contrary, information is happy to occupy every corner of the cage, and yes, given an opening, to seep out of the cage as well.
This is truer than ever in the digital age. As individuals we have more capacity than ever to stash away information for our own private use. And we relish it. Consider your private computer archives with their thousands of photographs, unfinished stories, poems that nobody will ever read, and bookmarks that nobody will ever visit. Information is as content to live on the front page of the New York Times as it is to occupy several square millimeters of hard disk surface in a Backblaze server farm.
For every person who wants to shout information from the rooftops, there are probably twenty who want to keep a nice private stash of it for their own enjoyment. The presumed motivation for information to be either public, private, or undiscovered is imbued by the people who care most deeply for it. Perhaps in this light the truly earth-shattering, profound information does want to be free. But by default, information wants to be everywhere.
MarsEdit 3.1.4
Relatively hot-on-the-heels of the previous release, MarsEdit 3.1.4, fixes some major memory performance issues and includes some fixes that streamline integration between Tumblr photo posts and the media manager.
Major Memory MeltdownI have always been pretty proud of my ability to manage memory usage in my code. In addition to using good programming habits, I periodically run Apple’s memory leak-detection tools, and the clang static analyzer. These tools do a great job of finding accidental memory management errors. But as I discovered, they are not enough.
For months I have received anecdotal feedback that MarsEdit is using more RAM than it should. But I couldn’t find any evidence of wrong-doing on my part, so I committed a major mistake: I just assumed it was normal. MarsEdit uses a lot of Apple’s frameworks, including WebKit, which is so big and expansive, I assumed there was something about the degree of WebKit I use in MarsEdit that explained the large amount of memory consumption.
Wrong! I was inspired by a recent one-two punch of feedback, combined with a recent blog post I had read, to dig deeper.
Twitter user @Fletcher_Chris was exceedingly polite when he asked if MarsEdit’s 200+ MB memory usage was “normal.” Ugh! Normal? I don’t know? I think so? Not knowing about why your software does what it does is a major alarm bell.
Then my friend John Gruber wrote to let me know that not only is he noticing major RAM consumption, but that it’s something that has bothered him for some time now. A recurring, nagging issue, noticed by somebody who is technically competent enough to know a real issue from a false one. I have a problem on my hands.
It was lucky timing that my friend Bill Bumgarner recently published an article on the very subject of hard-to diagnose memory leaks. I had actually read this article, enjoyed it, and blithely assumed it didn’t apply to any of my current software challenges.
It turns out that MarsEdit was in fact suffering from exactly this kind of leak: one that the brilliant leak-targeting tools from Apple are not able to detect. For a variety of reasons mainly involving retain cycles, I was neglecting to clean up after a major part of the MarsEdit post editor’s user interface, which means that every newly created and closed document would leak hundreds of KB of RAM.
Mea fricken culpa. Fixed in 3.1.4.
Tumblr Photo PostsTumblr has been a major challenge for MarsEdit because of the degree to which it doesn’t follow the usual paradigm for media management. This means in a nutshell that things you can do with almost every other blog system are not possible in Tumblr, making the user-interface a little clunkier to handle. In particular:
- Tumblr does not allow direct file uploads. Even though their web-based UI allows you to upload an image for direct insertion into a post, this is not something they have exposed for remote clients such as MarsEdit.
- Tumblr supports the notion of a “Photo” type of post, but it takes at-most one single photo. Usually MarsEdit is happy to add as many photos as you like to a post, but with Tumblr it has to be limited to one, and requires that the post type be switched to photo.
In MarsEdit 3.1.4, I take baby steps towards improving the situation when users do want to publish photos to a Tumblr blog. First, the per-blog “image constraints” settings are now applied to Photo posts on a Tumblr blog. So if you’ve got it set to limit posts to no more the 400×400 pixels, it will apply to any photo you drag in to Tumblr’s photo well.
I also streamlined the experience when choosing a photo from the Media Manager for a Tumblr-style post. Not only will the image constraints selected in the Media Manager be applied to the photo, but for example selecting and inserting a photo will automatically set the photo for the open Tumblr post document, or create a new post if one is not already open. This should make the photo-blogging experience on Tumblr a lot smoother.
A Curious Lack of Crash ReportsSince MarsEdit 3.0 was released, I have included a crash reporter mechanism that will automatically notice when MarsEdit quits for any unexpected reason, and offer to let the user send me a crash log plus any additional information they choose. This has been a great tool for measuring the number of harder-to-find bugs that remain in MarsEdit, and for zeroing in on and fixing some of them.
Luckily, the flow of crash reports is a relative trickle, compared to the number of users running MarsEdit on a daily basis. But after MarsEdit 3.1.3, the crash reports all but dried up! Was I really so brilliant as to accidentally fix any remaining bugs in the application? 3.1.3 forever!
No, what actually happened was I was brilliant enough to break the crash reporter in 3.1.3, so that it would fail to present the dialog to users offering to send in the report. Crashes were still happening, I’m sure, but I wasn’t hearing about them. Now fixed in 3.1.4, and I’m anxious to get back to monitoring the pulse of MarsEdit stability with this great feature.
Ask For Help
When I first started working at Apple, I was 18 years old. I was going to school at UC Santa Cruz and studying to be a computer programmer. Like my dad.
I was lucky to end up as a Quality Assurance tester inside a software development group at Apple. I worked for the Software Update team, which was essentially responsible for diagnosing, evaluating, fixing, and shipping bug fixes for anything in the System 7.5.x era software that Apple was building at the time.
I was so bold back then that I told my bosses, and my bosses bosses, and my peers, and anybody who would listen that I wanted to be a programmer. I wanted to write Mac software. No, I wanted to write the Mac!
That dream came true on May 12, 1996, when I joined Apple as Software Engineer I in the System Updates team for Mac OS Engineering. I immediately went to work, fixing bugs here and there as fast as I could. I took copious notes, in an effort to assure my bosses that I was the right person for the job. How did I spend my time over the past 5 minutes? I could happily elaborate.
I was so nervous about my performance, so worried that somebody might notice I was a fraud, that I didn’t ask for help as much as I should have. When somebody assigned me a problem, I scraped the walls of hell to find the answers, lest it be revealed that I wasn’t quite as smart as I might have seemed.
All the bugs in our group were difficult. One day I was assigned a particularly vexing one. I had shown a knack for tracking down tricky issues, but this one stymied me. I hammered away at the bug but I couldn’t figure out the cause. I couldn’t even think of where to go next. I was petrified. This was it, they would learn about my incompetence and put me out to pasture. I decided to take a walk.
I clearly remember that balmy summer day in Cupertino. I was filled with dread. I walked from Apple’s Infinite Loop headquarters, across Highway 280 on De Anza boulevard, towards the expansive suburban doldrums of Sunnyvale.
My pre-hire boldness had abandoned me. “Maybe I should quit,” I thought to myself. “That would be a stoic way of getting out of this mess.” It sounds so dramatic in retrospect, but I was so sure of my failure, it seemed like an obvious move at the time. I talked myself through the facts of the bug in question, and simply could not think of a solution. I couldn’t think of a part of a solution. I couldn’t even think of a step in the direction of a solution.
I walked for an hour or more, and then returned “home” to my office at Infinite Loop. I sat at my desk and stared into the monitor, hoping against hope for some inspiration. My friend and coworker, Darren Litzinger, stopped by my office.
“What are you working on?” he asked.
“I have a terrible bug, and I can’t figure it out.” The thought of asking for help didn’t even cross my mind. But fortunately, my frustration spoke on my behalf.
Darren sat down in my guest chair and adopted an excited look. “Well, what do you know about the bug?” He was here to help. I hadn’t even asked for it, yet here he was. I could have asked for it at any time, and I didn’t even realize it.
Talking through the bug with Darren, he asked me to perform particular tests at the computer. I realized that we had completely different approaches to problem solving. It wasn’t that his were right or that mine were wrong, they were just different. As it turned out, his technique saved the day and we got to the bottom of the issue within a couple hours.
As I moped along De Anza Boulevard that afternoon, I thought that I might not be cut out for software engineering in general, let alone at a world-class company like Apple. After I retreated back to my office and got a surge of help from a trusted colleague, I realized that I was perfectly qualified for the job. Especially if I could ask for help every once in a while.
MarsEdit 3.1.3
MarsEdit 3.1.3 is out and contains some “finally!” bug fixes, as well as a relatively major shift in the way that Google Blogger type blogs are configured by default.
Improved Rich Text PasteAs I have said before, the Rich Text editor in MarsEdit, as incredible as it is, is a work in progress. One of the things many people have reported since MarsEdit 3 came out is that it can be particularly irritating when it comes to pasting text. Often extra paragraphs would be inserted, and things just seemed generally unreliable. I’m not promising perfection yet, but I think you’ll find it a lot cleaner starting with this update.
Communicating With BloggerFor years, MarsEdit has communicated with Blogger using its standard “Google Atom” interface, which was developed in tandem with the standard AtomPub protocol. Over the past couple years, they have been working on a newer version of the interface which aims to be more compatible with the AtomPub standard. MarsEdit started supporting this in release 3.1.2, and starting with 3.1.3, “Google Data Protocol 2.0″ will be the standard means of communicating with Blogger.
The big win for users with this change is it should lead to more reliable preservation of HTML markup in your posts. But I don’t want to jump the gun and shift everybody over to it just yet, so I’m only defaulting newly configured Blogger blogs to use the new protocol for now.
If you’re feeling adventurous, you can switch your previously-configured Blogger blog to use the new protocol. Just open up the blog settings in MarsEdit, switch to the “General” pane, and select “Google Data Protocol 2.0″ from the System API popup. Then refresh your blog to make sure you get a fresh copy of all your recent posts.
Local Draft DuplicatesOne of the major annoyances people run into with MarsEdit is a creeping number of extra draft copies in the “Local Drafts” area. I have been tackling this problem for years, and I think I finally found one of the last, if not the last cause of the problem. If you’ve been running into this, delete all the cruft now and hopefully it will stay tidier going forward!
Change LogMost of this was discussed in detail above, but in case you want a definitive list of the user-facing changes that come with 3.1.3, here it is!
- Improvements to paste functionality in Rich Editing mode
- Avoid a bug where saved local-drafts were not deleted after publishing
- Fix a bug that caused custom field values to go blank while editing a post
- Blogspot-specific changes
- Newly configured blogs now default to GData 2.0 protocol, fixing some HTML formatting issues
- Fixes to GData 2.0 protocol to allow edit date, categories, etc.
Staying In Touch
Update: I originally cited the content of a customer’s email in this post, and although I didn’t reveal her identity, I don’t think this was appropriate or particularly constructive.
Mea culpa.
In the future I will never cite the contents of a customer’s private email, no matter how anonymously, unless they have expressly permitted me to do so.
I have edited the post to remove the contents of our correspondence with each other. I am leaving the post because I still think it expresses some interesting ideas.
Continuing the recent trend of posts about, essentially, “just doing it,” the purpose of this post is to underscore the wisdom of staying in touch with customers, while acknowledging that doing so brings its own challenges.
Since I established my own web store a few years ago, I have collected the emails of customers who buy my software and, for those who leave the pre-checked option selected, subscribe them to a company newsletter for infrequent announcements:
Infrequently is the operative word here. In more than three years I’ve neglected to send even one email to these folks. This is a problem, because permitting me to contact them set up the expectation that I would. When major releases such as MarsEdit 3 have come out, some people don’t find out until months later, and tend to be annoyed that they haven’t heard about it directly from me.
Yesterday, I finally got around to setting up a mailing list with Campaign Monitor, drafting a simple plain-text letter, and pressing the send button. I finally broke the ice.
For those of you who are not on the mailing list, here’s what I said:
News From Red Sweater SoftwareHello from Red Sweater! This is Daniel Jalkut, its founder and, for now, its only employee.
When you purchased one of my products, you agreed to receive infrequent email updates that keep you up to do date with my latest products. Since that time you have received approximately zero emails! I sort of dropped the ball on direct communication, but I’m working to rectify that now.
Messages will still be infrequent and hopefully pertinent, but if you are no longer interested in receiving updates about Red Sweater, just visit this link to unsubscribe:
(unsubscribe link)
On to the news: what’s happening at Red Sweater?
1. MarsEdit 3 Released
Earlier this year I released a major update to MarsEdit, our desktop blog editing application. MarsEdit now sports a rich text “WYSIWYG” editor, support for WordPress pages, and a media browser that integrates with iPhoto, Aperture, and Lightroom. Read more about MarsEdit 3 on the web:
http://www.red-sweater.com/marsedit/new3.html
If you don’t already own MarsEdit 3 you can purchase it for $39.95, or update from a previous version for $14.95:
https://www.red-sweater.com/store/
2. iPhone and iPad Releases?
People often ask about my plans to release applications for the iPhone, iPad and iPod touch. It’s easy enough to convey my intentions, but a bit harder to make specific promises. I am very excited about building iPhone and iPad versions of my apps, especially MarsEdit and Black Ink. I have made significant progress on these apps but there is still fine-tuning that needs to be done before I’ll be prepared to release them publicly.
3. The Mac App Store
You may have heard the news that Apple is planning to launch a Mac version of the App Store, which will give Mac users the ability to easily browse, purchase, and install applications in a similar manner to the way it works for iPhones and iPads. I’m hoping to get most or all of my apps into the catalog so I can reach an even wider audience of users. The good news for you, my existing customers? More customers will hopefully lead to more revenue, which means more resources and impetus to continue adding great features to the applications you already love.
4. Keeping In Touch
As I said earlier, I am resolving to do a better job keeping in touch. Next time a major update like MarsEdit 3 is released, you’ll hear about it before 6 months have passed! But if you want to proactively stay tuned in on an even finer level, there are some resources available to help you monitor our progress:
Email support. You can contact Red Sweater with whatever’s on your mind, be it a bug report, feature request, or just to say hi.
Address: [email protected]
Red Sweater Blog. The official company blog is my platform for providing a combination of company news and business-related thoughts and analysis.
Link: http://www.red-sweater.com/blog
Twitter accounts. For short, conversational style updates I maintain a personal account, a company account, and a special account just for MarsEdit:
Link: http://twitter.com/danielpunkass
Link: http://twitter.com/redsweater
Link: http://twitter.com/marsedit
5. Thank You
I want to close by thanking you for your business. I have been working on Red Sweater for over 10 years now, and in the past few years it has reached a level of success that supports myself, my wife, and my son. This is so unfathomable to me that I can only assume the sky is the limit! Let’s keep working together: your feedback and support combined with my desire to build great products should lead to many more years of successful results.
Daniel Jalkut
Founder, Red Sweater Software
To unsubscribe from this email list, just visit this link:
(unsubscribe link)
Delivery ConfirmationCampaign Monitor made the mass delivery painless for me. Thanks to their sophisticated tools, I know a day later that the vast majority of recipients received the letter, and only a small percentage have unsubscribed. Out of the thousands (wow!) of messages that were sent:
97.1% appear to be delivered
2.9% bounced
1.48% unsubscribed after receiving
1 reported it as spam (1 person, not percent – can’t win them all!)
This kind of feedback is great, but nothing compared to the direct responses I got from customers. The semi-personal tone of my letter inspired customers to respond in kind with heartfelt support and encouragement.
I received dozens of responses, ranging from the brief, enthusiastic “Word!” to longer, philosophical letters about small business, following one’s dreams, and the meaning of work in life.
Then, early this morning, I received this:
[EDITED: In retrospect, I do not believe it was appropriate for me to share the content of a customer's email here, even if information about her identity was removed.]
An upset or merely irritated customer always calls for a cautious response. The last thing I want is to escalate the situation. But this response is particular challenging, due to the number of provocative facets:
- The customer is not pleased by the email I sent.
- The customer is using a sarcastic, admonishing tone.
- The customer projects a lack of respect by omitting proper punctuation and sentence structure.
- The customer’s core criticisms are vague and subjective, making it hard for me to evaluate whether an apology or correction is called for.
These facets sort of multiply with each other and make it difficult not to respond defensively. My first reaction is to shout something into my email client like “What the hell?! Most people like a little humanity in a company, and furthermore, I did enumerate benefits where appropriate, and the content of this letter addresses the most common questions I have received over the past few months. And … and … who pissed in your Wheaties, anyway?”
Instead I take a deep breath, vent a little to my friends on IRC, and respond:
[EDITED: As with the content of the email from the customer, I don't believe it is appropriate for me to include the content of my response.]
I then proceeded to vent on Twitter about the response. I wasn’t particularly looking for comfort, but was glad to receive supportive responses from people who agreed there was cause to feel irritated by the customer’s tone. A sample of the dozens of reactions:
“That’s the kind of thing, when said in person, earns someone a kick in the teeth.” — @dssstrkl
“That guy is a jerk. Keep your personality in your work. if he doesn’t like it, let him use products from huge faceless corps” — @scottaw
“Personally, I couldn’t live with myself without adding a note about their tone. Why encourage an asshole.” — @mrgan
“Screw that guy. He’s just jealous that your Indie endeavors are successful enough to support you and your family. Good on ya!” — @fonix
“He presumes to speak for all your customers, co-opting “us.” He does not. Bravo on your measured and thoughtful response.” — @artgillespie
“That guy replied as if you were trying to sell him something. Your letter was more like a ‘state of the union’ communication.” — @morrick
Many of the responses refer to the customer as “him,” while none of them refer to “her.” In fact, this customer is either a woman, or a man with a very feminine name. Apropos of not much, but it’s interesting that we tend to assume somebody who is “being a jerk” is a man. I would have made the same assumption.
Do I feel a little disingenuous about responding to the customer politely and without indication of my annoyance, while essentially glorifying her message behind her back on Twitter and now here? Yes. This is not really my style, and I don’t think it’s very classy of me to share the private message of a customer, even if I am preserving her anonymity.
But, I think this experience is instructive both to customers and other small-business owners. And since I already vented on Twitter and essentially let the cat out of the bag, I thought I might as well go all the way.
Staying In TouchWhat does it mean to stay in touch? It means building and preserving a relationship with customers. The stronger the relationship, the greater the empathy for the other’s circumstance. But as with other relationships, the increase in communication and contact leads to an increased risk of misunderstanding and offense.
My letter served a valuable purpose. It let my customers know that I’m thinking about them, that the checkbox they vaguely remember leaving selected wasn’t pointless. That I do have plans for the company and for the products they purchased, and that I am interested in turning a new leaf with regard to communicating directly with them.
The challenging customer and my reaction to her has also been helpful. It reminds me of the related importance of “staying in touch” with my own values and priorities. Over the course of Red Sweater’s growth, I have used a very rules-based approach to how I handle just about everything. Running my own business means biting my tongue and doing “the right thing” even when the instinct in my animal brain wants to do the opposite. This is true for coding habits, fiscal responsibility, and yes, customer support habits. A variety of informal rules help to keep me in line.
As I have gained confidence in my own decisions, I find myself more prepared to break these rules. I suppose that pragmatism slowly takes over. When I first started out, I informed my decisions by asking “what would a good business do?” Then I learned to admire other Mac software companies such as Bare Bones, Rogue Amoeba, Panic, and Omni, and asked myself “what would they do?” I still defer often to the wisdom of others, but sometimes I have the distinct pleasure of asking myself “What would I do?” and acting on it. Staying in touch with myself is as important as staying in touch with my customers.
Blog The First Draft
MarsEdit users sometimes sheepishly admit that they aren’t blogging as much as they “should” be. Excuses vary, but it usually boils down to the classic issue afflicting all of us who try to stick to a productive routine: we simply fall out of the habit.
Long time readers of this blog will note that I’ve had my dry periods as well. But watch closely: I’m blogging now about a thought I had just earlier this evening, while reading Twitter updates and responding to them. Colin Barrett complained that his perfectionism is limiting his blogging:
I plan to write more; I think my @secondconf talk on freelancing would work well as a series of posts. Just gotta get past my perfectionism.
I’m incredibly familiar with this line of thinking. In fact, it’s a variant of the indefinitely postponed software releases that I just wrote about. I read Colin’s tweet and, before I had even noticed that the neurons in my brain were firing, I had responded with a bit of encouragement:
@cbarrett The modern business model for solo writing is to blog your first draft and sell your final.
I’m referring to the fact that very few blogs are edited to the level of professionalism you might find in literary or scientific journals. On the contrary, some of the web’s most celebrated bloggers have let their essays loose in a semi-rambling form, only to piece them together later into a more refined, salable volume. Rands in Repose and Joel on Software spring to mind in the techie world, while writers such as Heather Armstrong and Julie Powell turned their respective parenting and cooking blogs into million-dollar enterprises.
The ever-so-thinly veiled message? Don’t worry so much. Just blog it. If you are among the lucky few who achieves perfection effortlessly, then by all means carry forth. The rest of us are lucky if we coerce a unit of coherent thinking out our brains and onto the web. Perfectionism? Your editor will help you achieve it after you’re famous.