I’ve been doing iOS development since 2010, and I’ve worked on 100+ apps, from simple apps that took a couple weeks to build and deploy, to huge monster apps that had dozens of engineers working on them for years.
In this case study, I want to talk about a relatively simple app and how I helped the client design, build, deploy, and test a barebones prototype app to validate an idea and assess the feasibility of building a business around it.
As an organizational behavior consultant, my client Derek saw first hand how bad models of decision-making could inhibit the flow of creativity and efficiency throughout any organization.
That’s what gave Derek the idea for HuddleUp: an experimental app to help organizations solicit feedback in a constructive way.
Note: because this app is being used within companies whose name you would recognize, I’ve changed its name and Derek’s to not violate any confidences. No confidential material of any kind appears in this article.
The flow of information and requests for feedback on various proposals within the org chart was critical to Derek’s approach. He had often witnessed organizations slowed down in their decision-making by bring in too many stakeholders, or by involving people in the process who weren’t true stakeholders.
As a result, Derek designed HuddleUp to organize around a topic of discussion, and to let the topic creator invite others in the organization to add comments and give feedback on how the decision on the table should be made.
But crucially, Derek wanted to restrict the topic creator to be able to only solicit feedback from direct reports, direct managers, and colleagues in the same group.
In his day-to-day work as a consultant, Derek had a number of clients that could serve as a testbed for the app, but the budget and timeline were limited, and it was unclear what the distribution method would be for the first version of the app, to be tested within the organizations.
Derek approached me about helping him design the UX and develop the first version of HuddleUp, as well as support the deployment within the test organizations.
Derek flew down to NYC from Toronto so we could spend a couple days in front of a whiteboard deep-diving on HuddleUp and what the MVP might look like.
Because our time and budget were limited, our priority was to distill the idea down to its core principles and functions, and then design the MVP around just those items.
Our first step was to put together a wish list of all the functions that the app could possibly support in its mission to help organizations make decisions more effectively.
Then we went through and asked if each function had to be there for the MVP. If the answer was no, we put it on the Phase 2 list.
This process is often very hard for founders, as they’re very attached to the idea of the app that lives in their head, but Derek knew that the best chance of success was to get something useful into the hands of users and then iterate from there.
In order to save cost, we decided to use Parse as the backend server to power the application. Parse is one of a group of services known as a Backend-as-a-Service, or BaaS. Rather than building a custom backend application and database to live on a server and deal with maintaining it, Parse allows you to quickly define your data model, write lightweight code that runs in the cloud, and tie it all together with your mobile application.
This can literally cut the price of an MVP in half, and shave months off the timeline. This does come at a price of loss of flexibility and customizability, so Parse and similar services like Firebase won’t work for every startup, but they’re a great option where they will work.
In our case, we had boiled the first version of HuddleUp down to a very straightforward MVP that Parse was especially well-suited to, so it was an easy choice.
What made the cut
The basic MVP that we came up with works like this:
- A user can post a topic for discussion on HuddleUp
- A user can invite others within their organization to participation in the topic, but only within one degree of separation.
- All of the users on a topic can add comments, and give a yes / no / maybe vote on how they think the topic should be decided
- The topic creator can select the “winning” decision
That’s the core of the app. Pretty simple, right? The things that made it slightly more complicated were:
- How to easily tie together users in the same organization
- How to restrict users to inviting only within 1 degree of separation
- Push notifications
- The best way to deploy to test organizations
A key issue that we needed to solve early on was how to tie users within an organization together, so that they could invite each other.
We ended up solving this by restricting based on email address. We had a list of organizations in our database that were approved to use the app, and the email format that each user’s email had to follow when they signed up. Then we would only allow invitations to be sent to others with that same email address format.
Restricting involved users
Related, we needed to only let people invite others to join a topic if they were direct reports, direct managers, or colleagues in the same group.
We went around a few times on this, but we ended up opting with the lowest-tech solution ever: making users declare their relationship when they invited another user. So if you create a topic in HuddleUp and invite Bob to join you on the topic, you have to declare if Bob is your manager, your direct report, a colleague within your group, or someone else. If you select someone else, the app won’t let them be added to the topic.
Now, obviously that’s not a perfect solution, but short of getting an org chart that is always up-to-date, we didn’t have a better option. And this fit our criteria of being fast and cost-effective 🙂
One technical issue we faced was how to best deal with “anonymous” users who had been invited to the app, but had not joined.
The typical way of doing this is to have a list of “invitations” in your database, which represents all the times that a user of the app has invited someone else to join the app. That invitation record also has references to anything that the user was invited to do in the app.
For example, under this model, if a user in HuddleUp invited
email@example.com to join them in a topic discussion, we would create an invitation record in the HuddleUp database that contains references to the user who did the inviting, the email address of the person invited, and the topic that they were invited to. That invitation has a specific ID in the database, like
742829 or whatever.
Then we would send out an email to
firstname.lastname@example.org, and we’d include in that email a link to our app. Part of that link would have the invitation ID (
742829) included. That way, when SpongeBob pops over and signs up for our app, the app can see that he’s signing up in response to invitation
742829, which is linked to our original topic, and it can automatically pop SpongeBob into that topic discussion after he signs up.
However, if SpongeBob signs up without that invitation ID being present for some reason, he doesn’t get added to the topic. He’s just left stranded, like any other user who just randomly signed up for the app. Not a good experience if you’re signing up in response to an invitation.
The big issue with the flow I outlined above is that if
email@example.com gets the email with the link to the app but he doesn’t have the app installed, he’ll have to go to the App Store and install it. OK, so he goes and downloads the app and then taps on it to open it.
But now he’s not opening it from the link anymore, he’s tapping on it after installing from the App Store! So the invitation ID is not present, leaving him stranded again.
Now, there are ways to “fingerprint” SpongeBob so that when he clicks on the link, we record who he is, then send him to the App Store to download the app. And then when he opens the app after installing it, we sense that it’s him and that he was originally trying to open an invitation link, so we go ahead and put him in that topic discussion, even though he actually opened the app after installing it without clicking the invitation link.
If all this is confusing, don’t feel bad; it’s kind of a mess.
In order to get all this working correctly, you need to do some work on the app, the server, and some help with a third party system like Branch.io. In our case, we needed a simpler approach for the MVP.
Instead, we decided to just use the email address as a simple invitation ID.
So in HuddleUp, when you invite someone to join you in a discussion, the system checks to see if a user already exists with that email address. If so, we just send them a notification that they’ve been added to a new discussion.
If a user doesn’t exist with that email address, we store a reference to that email address with the discussion record in the database. Basically, we store with each discussion a list of the email addresses that are “pre-authorized” to join the discussion if they sign up.
Then when a user signs up and they give us their email address, we check all the discussions to see if any have that that email address as being “pre-authorized” to join. If so, the new user is automatically added to those discussions.
The downsides of this approach are two-fold:
- It doesn’t scale very well; searching for those “pre-authorized” email addresses could be inefficient once we have tens of thousands of discussions. We could solve this with an architecture change though.
- The user has to sign up with the same email address that they were invited with in order for us to match them up with the discussion. If they are invited at one email address and then sign up with a different email address, their new account will not be linked to that invite, and thus they won’t be able to participate in the discussion they were invited to.
The first item isn’t an issue for now, as we’re still in small-scale beta testing, and could be solved pretty easily later if needed.
The second disadvantage is annoying, but we include a note in the invitation email urging the person to sign up with the same email address that the invitation went to, in order to ensure they get added to the right discussion(s).
This approach reduced the amount of work by around 80% vs. creating a full-blown invitation system.
Next, we needed users to be notified via push notification when a topic they were invited to a topic, when one of their topics had a new comment, or when a decision was made on the topic.
Fortunately, Parse handles Push Notifications well, but we still had a little wrangling to ensure that notifications went out to the correct group of people at the right time.
Finally, we needed to get this in the hands of users at Derek’s test organizations. Two options we considered and discarded were the App Store and Apple’s Enterprise distribution method.
The App Store was too public for this app at this point, given that it was a very rough MVP. It was important to us that Derek have the opportunity to walk the first few groups of users through the application and get their feedback, watch them use it, etc. This can often be the most valuable part of beta testing, when the biggest breakthroughs are found, things that are hard to divine from an analytics dashboard.
Enterprise distribution would have worked, but this use case is technically outside of Apple’s guidelines, which can really get you into trouble.
For the first version of HuddleUp, we ultimately opted to distribute via Apple’s Testflight External Beta Tester service. The advantage is that, compared with some other options, it’s a relatively painless user experience. The user is notified that they’ve been invited to the app, and can login with their Apple ID and download a copy of the app. Easy.
One minor downside is that Apple puts those apps through a review process, which just adds several days to the timeline for releasing updates to your beta app.
The bigger downside for HuddleUp is that a user has to be added as an external beta tester in iTunes Connect before they can install the app. Since we were deploying within several large organizations, we didn’t know in advance who the employees would invite (and we couldn’t simply add all the employees; there were too many), so we had to add another step. When an invitation is sent from the app to another user, we send out an invitation email from Parse that ends with:
“If you haven’t already been invited to HuddleUp, please email us at firstname.lastname@example.org and we’ll add you to the list of beta testers.”
This impeded the flow of invitations in the app, but it was the best fit for the first few dozen testers.
UI / UX
Because this was an MVP and our timeline and budget were limited, we pretty much stuck with stock Apple user interface elements and transitions for the first version. This simplified development and saved budget that would have gone to design as well.
Note: While this typically is not appropriate for consumer-facing apps headed to the App Store, in this case, we were deploying to people that Derek could onboard face-to-face. Our MVP for this particular audience was really more of a working prototype than anything ready for a public launch. The primary purpose was feedback and learning, and we felt confident that the simple design would not be a distracting factor.
Over the next couple months, we deployed the app to a couple of test organizations using the methodology outlined above. Derek was active in the organizations as a consultant, so he could help them understand how best to use the app, and immediately get involved if there were problems or miscommunications with deploying or using the app.
Through this process, Derek got a lot of great feedback on the app and how to make it more effective. He and I did some work on the v2 set of features and how we could improve the user experience to make organizational decision-making even more seamless and powerful.
However, after some reflection, Derek elected not to continue with the development of the app. The users liked it and found value in using it, but the traction wasn’t so strong that Derek was ready to invest the large sum of money to build beyond the prototype. People just didn’t want it enough to break them out of the status quo.
Now, that might make this episode seem like a failure, but remember that this was an experiment in Derek’s mind from the very beginning, which is why we went the rapid prototyping route. Believe me when I say that he was much happier with this outcome that having spent 5x the money to create a super-polished app that people still didn’t want.
Startups are hard. Most of them fail. Better to fail quickly and cheaply and move onto the next thing.
The additional upside here is that Derek was able to leverage this experience into additional consulting case studies and work for his practice, giving him a positive ROI.
If you need a mobile app and you want to save some time and money by building smart and validating as you go, contact me and perhaps I can help you avoid throwing a huge pile of money away just like Derek!