Why Many of my Apps Failed And What Comes Next

I’ve started building something new.

I’m about four weeks in and already finding it incredibly useful in my day-to-day.

I’ve built many different apps over the years, thrown them against the wall, and excitedly watched which ones developed a following and which ones failed miserably.

Most of my apps have fallen into two categories. There are the ones that solve a personal need I face, that I can inform and direct with my own experiences. And there are those where I saw a market opportunity or just thought they might be fun to build.

Almost all of the ones in that second category have failed. Incoming!, Nottingham, Highwire. They each had their share of a few passionate and engaged users, but mostly were ignored. (The jury is still out on Triage.)

But that first category of apps? Those have flourished.

I was a web developer for ten years before I started building Mac apps. I know the industry well. And working at an agency meant I was juggling many different websites at once. I needed a faster/easier way to spin up local development environments, and that led to me creating VirtualHostX. Which, in turn, led to Hostbuddy and Hobo years later.

My core set of apps, as I think of them, found a wonderful niche among solo web designers and developers and the small companies they work for. And the apps have succeeded beyond my wildest dreams. From 2012 to 2014 they were my full time and only job.

But since their heyday in 2014, sales have steadily declined. A big part of that, I think, is because the world has moved on from the LAMP-based standards of 2004 – 2012. Nginx, NodeJS, etc. have led to a sea change. If it weren’t for WordPress’s continued dominance, I’m not sure if I’d have any more sales at all.

So, I’ve seen the writing on the wall for a few years now, and have been on the lookout for ways to branch out and diversify my app portfolio.

I’ve done some freelance jobs here and there, and tried a few new things on my own, but nothing has taken off. And as I talked about earlier, I think a lot of that is due to none of those new ventures being true passion projects that I could bring my own experiences as a user with specific needs.

But four weeks ago I finally became fed-up with the awfulness of Mint.com. I know they’re able to provide a free service because they plaster the site with advertisements and sell my data, and I’d be ok with that if they weren’t so intrusive. But they’re taking over nearly the entire browser window now. Add to that the cumbersome Web 2.0 UI and lack of any real reporting capabilities, and I’d had enough.

What I really want is a fast, powerful, native Mac app that automatically imports my financial data and gives me the ability to slice, dice, filter, organize, and export my data in every possible way. The flexibility and power of an Excel sheet with the learning curve of iOS and the familiar paradigms of a real Mac app. Something that keeps me in control of my data, respects my privacy, and syncs to all my devices.

So I built it.

Preview1

Most of it. It’s not done yet, but all the major pieces are in place, and I’m using it to track my family’s budget every day.

I’ve taken a heavy dose of inspiration from one of my favorites apps – OmniFocus – both from a UI perspective (a clean, modern, attractive Mac interface) and from the power they afford users over their data by way of custom perspectives.

My app is smart. It auto-categorizes your transactions. You can just let the app do its thing and everything will end up in the (mostly) appropriate place. Or you can categorize each transaction manually. Or you can setup smart rules to do it for you automatically. Whatever fits your workflow.

Each transaction can belong to a single category. But categories can be nested. With one click you can see all the dining out you did last month. Or just the fast food orders. Or just what you spent at McDonalds.

And then there are tags. Assign multiple tags to a transaction. Do it manually, or create a smart rule to assign them automatically. Then use the app’s powerful search feature to find any combination of AND / OR.

Take search further by combining tags with categories and date based filtering. Find every Uber ride tagged #business during the last quarter and export the results to a CSV you can send to your boss to get reimbursed. Snapped a picture of the receipt with your iPhone? Yep, you can attach files, too.

And once you’ve got that perfect search query and set of filters in place, save it as a new Report that you can recall at any time. Just like an OmniFocus perspective.

And, just for fun, why not view all of your transactions plotted on a map?

Preview2

I’ve got all of this working (albeit without the necessary UI/UX polish) and it’s totally opened my eyes to some aspects of our financial situation that I’d overlooked. The last major piece is adding a budgeting component. I know the system I want to adhere to, but I’m still working through how it will fit in the interface.

Of course, I’m leaving out the iOS counterpart. But I’m saving that for later. The model layer is still a bit too much in flux. But I’ve written all the business logic to be platform agnostic. So the plan is to reimplement the appropriate features in UIKit (not everything the Mac app can do would make sense or be needed on a mobile device) and reuse as much of the existing codebase as possible.

But don’t forget syncing. As I said in my requirements, I want this app to be privacy-focused and have the user be in charge of their own data. So, no financial data will ever touch my server. Unless they enable syncing, no data will ever leave their device. But if they do want to sync, that’s all privately handled by CloudKit so I, the developer, can’t see their info even if I wanted to.

So, that’s it. That’s what I’ve built and am working towards completing. I have no idea when it will be ready. CloudKit could easily throw a big wrench into everything. And I’ve also got major updates to VirtualHostX and Hostbuddy underway and due out this Fall.

But I’m excited. It’s an app I’m passionate about and I have a clear direction and feature set in mind. It caters to a broader audience than my developer-focused products and could potentially save my tiny company if they continue to trend downwards.

Rockwell – Sort of like a private Foursquare meets Fire Eagle

Back in 2008, when I worked for Yahoo!, I had the good fortune of chatting with Tom Coates a few times about the now defunct Fire Eagle location brokerage service. Fire Eagle was my absolute favorite product to come out of Yahoo! during my time there. I’ve always been fascinated by real-time location data and sad that Fire Eagle’s intersection of privacy and ease of use never caught on.

Anyway, fast-forward to last Summer, I was bummed that although so much of my life is documented through photos, tweets, and journal entries, my location data was missing. A few products tried to solve this problem post-Fire Eagle. Google Latitude (née Dodgeball) gave you a way to seamlessly track your location and view your history, but they’ve since sunsetted that product. And, besides, it was a little creepy having Google track your every step. (Which I realize they still are via Google Now, but that’s another conversation.) There was also other apps like Rove and Foursquare, but none of them offered quite the feature set I was looking for. In 2010, I even went so far as to reverse engineer Apple’s Find My iPhone API so I could remotely query my phone’s location. That worked great, but doing so on a regular basis killed my battery life. But, with iOS 7’s advances in background location reporting, I knew there had to be a better way. I wanted something that would automatically track my location as precisely as possible, respect my phone’s battery life, keep that data private by default, yet still offer the ability to granularly share my location as I saw fit.

So I did what I always seem to do. I built my own app. It’s called Rockwell, and it’s available on GitHub.

Rockwell consists of two components. An iPhone app that monitors your location and allows you to annotate where you are using Foursquare’s database of named locations. And a PHP/MySQL web service you can install on your own server that the app talks to.

As you go about your day, the iPhone app uses iOS’ significant location change reporting feature to ping the web app with your location. The web app stores your location history and allows you to go back and search your history either by date or by location.

Further, since the website knows your most recent (current) location, you’re able to share that with others. In my opinion, one of the reasons Fire Eagle failed was it was (by design) very difficult to get location data out of the service. You had to go through an intricate OAuth dance each time.

With Rockwell, you simply choose the location level you’re comfortable sharing – either precise lat/lng coordinates, current city, current state, etc – and a format – plain text or JSON – and Rockwell generates a short url you can pass around. You can use that URL to embed your plain text location on your blog, or you can use the JSON version to do something more API-ish with it. There’s no OAuth shenanigans to deal with. You can have as many short geo-links as you want, and each one can be revoked at any time.

One more thing I’d like to explain. The iPhone app reports two types of check-in data to the web service. The first kind is dumb. Just your latitude, longitude, and timestamp. Many apps like Rove and Foursquare use this data to try and generate automatic location check-ins. Based on your past history, your friends’ location, and your location, they try and guess where you might actually be at a given time. Doing this well is the holy grail of location reporting. The problem is that I’ve yet to see any service get it right. In a dense urban area, with hundreds if not thousands of locations per square mile, there’s just no reliable way to figure out where you really are with precision. (At least not without some serious machine learning, which I assume Foursquare is working on.) Rockwell dances around this problem by allowing you to augment your dumb check-ins with annotated ones. Just launch the app, tap “Check-in”, and Rockwell pulls a list of nearby locations from Foursquare. Just tap on one and you’re done. It’s saved to the web service alongside the rest of your location history.

Rockwell is working great for me currently. All the basics work. The majority of the remaining work is around coming up with nice ways to show your location history in a useful way. The code is available on GitHub. I’d love it if you gave it a try, sent feedback, and maybe even a pull request or two.

Nostalgia – Rename Your Photos

I have a problem. Half of my photos come from my iPhone (via the Dropbox uploader), which creates filenames based on the date they were taken. But all the photos from my awesome DSLR are named BLAHBLAH_7001.jpg and BLAHBLAH_7002.jpg. That annoys me. I want all of my filenames to be date based so I can quickly sort them and find the photos I’m looking for.

Much to my dismay, Hazel and Automator can’t solve that problem.

This Mac app does.

Launch the app, drag and drop a bunch of photos onto the window (or the Dock icon), and boom! Everything gets renamed appropriately based on the EXIF date.

Currently, there’s no way to customize the output date format. It’s set to yyyy-MM-dd HH.mm.ss. I make no apologies for that. If you’d like something different, feel free to modify the Xcode project or submit a pull request with the ability to customize the date :) Also, it only looks for the standards based yyyy:MM:dd HH:mm:ss EXIF format. If your camera doesn’t follow along, Nostalgia won’t be able to parse it. Again, pull requests are very much welcome.

You can download Nostalgia for your Mac from here.

Setting Up NSOutlineView Drag and Drop with Core Data in Cocoa

Last week, I finally got around to building the number-one VirtualHostX feature request – groups/folders in the sidebar. I had put off implementing this feature for years because I never knew quite where to start when it came to Core Data and NSOutlineView. But, with VHX 5.0 coming out later this year, I decided to lock myself in my office and not come out until I had a sorted, drag-and-droppable, outline view working. In the end, it only took about three hours to get all the pieces in place. And while I’m not quite ready to release this feature to my users, I thought I’d jot down some tips and code snippets that I found helpful while it’s still fresh in my mind. Google wasn’t particularly helpful with any recent results on the topic, so maybe this’ll be found by someone struggling with the same problem.

Setting up your XIB

In your Core Data model, create a one-to-many relationship called children pointing back to your same entity. Then create a corresponding one-to-one relationship called parent back to the same entity. The trick here is that you’re not going to have an entity for groups/folders and then another entity for your actual items (in my case, virtual hosts). They’re all going to be the same entity, but with a property called isFolder that allows you to differentiate between the two types.

In your NIB file you’ll need an array controller bound to your NSManagedObjectContext, set to Entity mode, and with a Fetch Predicate of parent == nil. This will fetch our top level objects – entities without a parent.
Next, create a tree controller with its Children Key Path set to children, set to Entity mode, and its Content Array bound to your array controller’s arrangedObjects.

Finally, drag an NSOutlineView to your NIB. Set its dataSource and delegate to one of those blue NSObject’s, which you’ll subclass to be an OutlineViewController you’ll create in code later on.

OutlineViewController.h/m

Connect the IBOutlets back to the appropriate objects in your NIB.

Here’s the first big chunk of OutlineViewController.h/m

Managing the outline item’s expanded state

We’re so spoiled with how much crap work Cocoa handles for us, I naively thought that NSOutlineView would just automatically remember the collapsed/expanded state of the items in my tree. It turns out, there is a way to have NSOutlineView persist those states to NSUserDefaults, but I could never get that to work. So I just do it all manually – it’s not that hard. Just add a BOOL to your Core Data model called isExpanded and then further down in OutlineViewController.m

And then subclass your NSOutlineView’s reloadData method to be:

And that’s basically it. Overall, not as much code as I would have expected (thanks to bindings, natually). Hope the above code helps anyone tackling the same problem. Much of my code was discovered/cribbed from this great blog post on the topic from a few years ago.

Guessing a User’s Location on iOS

A few months ago at work we ran into an odd user experience problem. The home screen for one of our iPad apps included a small icon in the navigation bar showing the current weather. Normally it displays the weather for the user’s current location or any location they’ve saved. No problem. But what do we show the first time the app launches? At that point, they have no saved location preference and we don’t know their physical location because they haven’t yet opted-in to CoreLocation. We came up with three options.

  1. Don’t show anything, or show a generic no-location-set icon. We tried this, but our designers didn’t ilke the empty experience.
  2. Immediately prompt the user for permission to access their location as soon as the app launches. We nixed this idea, too, since we didn’t want an ugly system alert to be their first interaction with our app.
  3. Pick some standard default location until the user chooses a different one.

We actually went with option #3 and set New York City as the default location. Unfortunately we found that this confused users. Even though they hadn’t given us their location info yet, they still assumed that the icon represented their local weather forecast. Imagine seeing a sunshine icon when it’s pouring rain outside. Not good.

That led us to consider a fourth solution. Over lunch we came up with the idea of trying to infer the user’s general location based on the data available in their address book. If it worked, we could provide an approximate weather forecast on first launch without popping-up a nagging alert window.

On Mac, doing this is easy. Just query the user’s “Me” card and pull out their city or zip code. But on iOS, for privacy reasons, we don’t know which card is the user’s.

Thinking a bit more about the problem we realized that most people know lots of people who live near to them and fewer people as the distance increases. So we decided to look through the user’s address book and find the most common city, state, and zip code. The idea being that would let us infer the user’s state if nothing else.

The code for this was pretty quick to write. We built a small sample app and distributed it to everyone in the office. We were shocked to find out how well it worked. It correctly guessed the user’s appoximate location for all but one of the devices we tested it on.

In the end, however, we chose not to add this “feature” to the app. We decided, while clever, it was just a little too creepy even though we never did anything with the data. But, it was still a fun thought experiment and a nice proof of concept to spend an afternoon on.

If you’d like to see or use the code, it’s available on GitHub.

Sosumi for Mac – Find Your iPhone From Your Deskop

Every holiday, between the food and family, I always seem to find time for a quick project. Last year I built the first version of Nottingham over the Thanksgiving break. This year was no exception, and I found myself putting the final touches on Sosumi for Mac after an eighteen hour coding streak this weekend.

Sosumi for Mac builds on the original Sosumi project I started last Summer — a PHP script that returned the location of your iPhone by scraping MobileMe’s website and that eventually evolved to use Apple’s “official” API once that was released.

Last week, Apple pushed a rather large update to the Find My iPhone service and made it free to all users. Along with that came some API changes, which broke Sosumi. With help from Andy Blyler and Michael Greb, we managed to get it working again. I took the opportunity to go all out and write a native Cocoa implementation of Sosumi as well. And, with that done, I went one step further and built a full-fledged desktop app for tracking all of your iDevices.

Now that it’s complete, it’s much easier to simply open up Sosumi for Mac, rather than having to re-login to Apple’s website or iPhone client each time. The desktop app also opens up some fun possibilities. A future version could notify you when your spouse leaves work in the afternoon so you know when to begin preparing dinner. Or alert you if your child strays from their normal route on the way home from school. Or, since Sosumi provides your device’s battery level, you could even send alerts if your phone needs to be charged soon.

Admittedly, this kind of always-on location tracking can certainly be creepy. But that’s almost always the case with these types of applications. Whether Fire Eagle, Foursquare, or Google Latitude — it’s always a matter of striking a reasonable balance between convenience and privacy. I trust you’ll use Sosumi for good rather than evil.

Download Sosumi, read more about it, or grab the source on Github and build something even cooler.

https://clickontyler-clickonideas.netdna-ssl.com/images/sosumi-ss1.png

OpenFeedback Part Deux

A year and a half ago I wrote about OpenFeedback, an open source Cocoa framework for gathering feedback from your users. Initially, it was a sister project to Appcaster, my indie dashboard web app. Since then, Appcaster has grown up and morphed into Shine, but OpenFeedback remained unchanged. Tonight, though, I took a few hours off from Highwire and rewrote OpenFeedback from scratch.

The rewrite wasn’t strictly necessary, but it certainly didn’t hurt. The original code was hurried and in poor shape. I was able to cut the amount of code by 30% and give the dialog a more modern looking tab view.

Like before, adding OpenFeedback to your application is trivial — there’s no code required. You simply link your app against the framework and hook-up the appropriate actions in Interface Builder. In under five minutes you can have an elegant way to encourage users to ask questions, submit bug reports, and suggest new features.

My long term goal for OpenFeedback has always been for the Mac developer community to rally behind it, making it a drop-in standard much like Sparkle. That hasn’t happened yet (obviously), but Shine has been getting some good attention lately. If I’m lucky, maybe some of that goodwill will carry over and help kickstart things along.

Like the rest of my open source projects, OpenFeedback is MIT licensed and available on GitHub.

Sosumi – A MobileMe Scraper

Sosumi is a PHP script that scrapes MobileMe and exposes Apple’s Find My iPhone functionality to the command line or your own web application. This lets you pull your phone’s current location and push messages and alarms to the device.

Like my previous blog post that dealt with AT&T’s Family Map service, my goal was to connect my iPhone with Fire Eagle by Yahoo!. There are a few iPhone Fire Eagle updaters available, but they’re all limited by Apple’s third-party application restrictions. Sosumi gets around those restrictions by running every few minutes on your own server rather than the device itself. In my case, I’ve setup a cron job to run the script every fifteen minutes and push my location to Fire Eagle.

Until Apple releases a location API for MobileMe (not likely, and not their job), this will have to do.

Grab the code on GitHub.

Example:

<?PHP
$ssm = new Sosumi('username', 'password');
$location_data = $ssm->locate();
$ssm->sendMessage('Daisy, daisy...');

Introducing Appcaster + OpenFeedback

Today I’m proud to announce the release of two new open source projects: Appcaster and OpenFeedback. I’ve been working on them off and on for over nine months, so I’m very excited to finally see them out the door.

Appcaster, which I’ve written about before, is a web-based dashboard for indie Mac developers. It’s designed to manage payment and order processing and generate license files for your users. It even handles your product’s revision history in Amazon S3 and can produce reports from your users’ demographic info. It also serves as a central location to collect user feedback, bug reports, and support questions.

OpenFeedback is a Cocoa framework written in Objective-C that collects feedback from your users directly within your application. Instead of sending your users to a website or asking them to write an email, OpenFeedback gives them a simple window where they can ask support questions, file bug reports, or suggest new features. Their data is automatically sent to Appcaster for you to review. They never have to leave your application.

Collectively, I’m calling the two projects Appcaster since they’re designed to work closely with one another (and since I wanted them to be part of the same Google Code project). However, OpenFeedback can send data to any server-side script that accepts HTTP POST requests — you can easily integrate it into your existing bug tracker or reporting system.

Appcaster

When I first built Appcaster last year, I wrote a detailed overview of the application here. Aside from cleaning up a few bugs and upgrading it to use the latest version of the Simple PHP Framework, the only major additions have been adding support for OpenFeedback and graphing user demographic data using the Google Charts API.

Google’s Chart API is such a slick, clever way of doing things that I couldn’t pass by the opportunity to use it in a project. After aggregating your data, you simply craft it into a special URL and use that as the source of an <img> tag. Google parses your data out of the URL and returns a PNG formatted chart.

It took all of half an hour to create some basic stats from the Sparkle update data Appcaster collects. It would be trivial for other developers to add their own custom reports in the future.

OpenFeedback

The idea for OpenFeedback came from Cultured Code‘s task management application Things. Clicking on the Support menu item in their Help menu brings up a dialog where you can submit questions and feedback from inside the app — no need to visit a website or open an email.

I thought their implementation was a great idea and emailed them to ask if I could recreate that functionality as a Cocoa framework for other developers to use. They were nice enough to say yes :-)

Adding OpenFeedback to your application is trivial. Like Sparkle, there’s no code required. You simply link your app against the framework and hook-up the appropriate actions in Interface Builder. In under five minutes you can have an elegant way to encourage users to provide feedback.

My long term goal is to see the Mac developer community standardize around OpenFeedback much like they have around Sparkle. Not only would it save time for developers, but it would provide users with a consistent interface for submitting feedback. That should help improve the dialogue between developers and our users — improving Mac software all around.

Speaking of Feedback

Your feedback is always welcome. This is my first open source Cocoa project, so I’m very much flying by the seat of my pants. Suggestions, improvements, bug reports — they’re all welcome. You can send them directly to me or file an issue in our bug tracker.