Rewriting my App for the 3rd time from the ground up
Hi, I am Daniel from Austria and this is the story of my app “FIMPL”.
Introduction: Problem my app tries to solve
Imagine you play football on an amateur level. You go to training 2–3 times a week and have one game on the weekends. Maybe you play in a local league and for games away you need approximately 20–40 minutes. BUT where are those fucking pitches of your enemies you want to crush later on? You know you have to go to this village/city where the games take place, but where is that field in that village/city?
And thats exactly where FIMPL is rushing to your aid. FIMPL comes from the german words “Finde meinen Platz” which can be translated to “find my field” And FIMPL helps to find those pitched hidden away a mile outside of the village where no one would have guessed it.
At the moment FIMPL only works in parts from Austria, because its a pain in the ass to find all the fields with their coordinates via Google Maps.
Here is the landing page:
(Unfortunately in German, sry folks, but it’s very beautiful you should take a look ;) )
You can skip this part if you are not interested in how I learend to program and how the app connects with my background and work.
So how do I got to write this app? First of all I was a footballer myself before my knee started to jump out of the joint announced. As a footballer in a local league you always have to find the field of the away team, it does not count how many time you have been there (once a year), you nearly always forget how to get there. So I thought I write an app for that! Smart hm?
I had some experice in web development so I started out with a website. After some weeks of being live it was clear to bring this idea into the hands of the user in form of an app. As I knew web development I started with PhoneGap. If you know PhoneGap it can be a pain in the ass, but I know it from work and I also knew web development, so this first my path.
The 3 1/2 times
As mentioned above I started with a website, I count that as 1/2 of my app because I could reuse a lot of the code since I started out with PhoneGap.
I released the app for the first time for iPhone and Android at the time and the feedback was great. The ones who used it where thrilled, so I kept going. I coded some aditional features, but only for iOS, since PhoneGap and Android, pared with my unexperience in web development (everything self tought) were a horrible combination. If you correct a design related issue on one device you get like a thousand glitches on ten others. I also made another app with PhoneGap thanks to the grandmother of my girlfriend.
At work I am a product manager for apps and I have a college (Martin = guy with the best ideas related to UI/UX) who is interested in Android development, so I convinced him to write the Android version and I would do the native part for iOS.
As a result I started watching videos on Udemy (from the awesome Mark Price and his course and @j_brinkmann and his german course) in no time I was able to produce a working native prototype. This was the second time I wrote FIMPL from ground up. It was more of a gluing together tutorials from Youtube, Stackoverflow and Udemy, but you know what? I kept going. As soon as I started to get cozy with Swift I didn’t even looked back once at PhoneGap.
Reading more about Swift and native programming and watching my videos and I got more and more confident in what I did. And since Xcode threw a lot of (like 30?) warnings what I should do different in FIMPL as well the structure of my app wasn’t really modular so I could easily add new features, I decided to start over one more time.
And this was/is the third time I rewrote FIMPL from ground up, it’s still under development as I am writing this post, but its like 90% finished. I changed everything on the inside. From object oriented programming to using all the new and fancy frameworks. WITHOUT warnings, oh man I feel so proud I pulled that of. And as I said before, programming is so much fun:
- Detecting a problem
- Banging you head against the wall trying to solve it
- Scribbling the solution on a sheet of paper as a workflow
- Sitting several hours translating it into code
- and then there is that feeling where it works on the first try. Best.feeling.ever!
But this only happens like never, the normal way is to get frustrated over your code and you don’t know why it is doing what it is doing and you spend several hours on Stackoverflow, but isnt that what its all about?
Screenshots and features
As I am the iOS developer of FIMPL I only provide iOS screenshots here. But you can checkout the awesome Android version here.
The main view of the app is a map with the teams on it. On every fresh start there is a little animation where the searchbar comes from the top down.
I download the data and create a class for each team. When starting the app I ping the server to check for the “last-modified” in the header of the file. If there is a newer file on the server, than I got locally in my app, I download it, if not, I get the data from the NSUserdefaults from a previous download. I am super proud of the little progress bar at the top. If you have bad reception it really helps the user to see what is taking so long. Speaking of bad reception, a long with the new version we also revised our JSON file. After some slimming and refactoring we could slim it down from 265kB to 145kB — nearly 50% isn’t that great? Theat means loading time is cut in half!!
Picking a team from the map
One way to pick a team is via the map, if you do so, a card comes from the bottom with all the information you need.
On the card there are several infos:
- The name of the team in green on the top(obviously)
- The region (e.g. “Niederösterreich)
- Distance and time to get there
- Local weather
- A button to get directions to this team (big green one)
- Three additional buttons to re-center the team on the map (left). To show the website of that team (middle) and to edit the teams data (on the right — more on that later)
I get the weather from http://openweathermap.org. The distance is calculated with AppleMaps (its not the linear distance between your location, instead it’s the first route via car) and the website is opened with a SafariViewController. The button to re-center the team is disabled until you move the map. Everywhere where data gets loaded I have loading indicators. (Weather, distance and time)
TableView with Teams
In a former version, the user could only see teams when he started typing in the searchbar like an autocompletion, in this version I list all the teams in the tableview, which brings several advantages.
I have a webserver with a JSON file which holds my data. As already mentioned, when I receive data I make a class per team.
Here is an example of my data structure:
“nam”: “SVD Langenlebarn”,
“adr”: “Donaulände 159, 3425 Langenlebarn”,
As you can see my name contains also this ugly prefix, in this case “SVD”. This is an easy example tough, but in most cases its “FC” like “FC Barcelona” or“FC Bayern”. There are seeral others like, SC, SV, TSV, HSV, KSV, ASV the list is endless…. But as you can see in the screenshot above the teams are ordered after the name after this prefix. So what I did here is that I split the name and compared the first part to a list of common prefixes for sportsteams. If the team has one of those prefixes I order them after the second part of the name, if not I do that for the first part.
On the right screenshot you can also see the “Zuletzt hinzugefügt” section, which shows the last four searched teams of the user. Funny thing here to consider is that I store them into the NSUserdefaults. But when new data is downloaded from the server I have to replace those four teams with the same teams from the newly downloaded data, because if a team from these “Zuletzt hinzugefügt” gets changed, it wouldn’t be changed in this four teams array. (I hope you get what I want to tell you here)
As I explained at the very top, the main use case of the app is to find a football field and if you have to go by car, direct navigation is a must. So this part is just to get directions via AppleMaps to the field. I also show the address, because shortly after the initial launch I got feedback that people want to use their navigation systems in their cars, altough the address could be a kilometer away from the field itself because nor Google or AppleMaps have addresses directly at the fields. With AppleMaps tough you get routed directly to the coordinates of the field.
Menu with sharing
The screenshot above shows my menu. I could have realized it with an additional button on my main screen because the only real menu point is “Mannschaft melden” so that the user can report a team. The other stuff is just nice-to-haves.
The user can jump directly to the review page and he can share the app via different social medias.
I am still reconsidering how the layout should be, maybe I will highlight the “Mannschaft melden” a bit more. Also the wording is not optimal.
As you can see, I placed the close button on the bottom, because on big screens like the iPhone 6Plus its a pain in the ass to reach to the top.
With “Bewerten” you can rate the app, here I don’t just jump to the App Store, I directly jump to the reviews page. I do that with this link:
What you can see at the top is a status of how many teams the user has reported or updated so far. This is just a little emotional binding to the app so maybe the user gets motivated to report or update some team’s data.
The status is derived from the amateur leauges of Austria to the very top to worlds best footballer, the Ballon d’Or. So if you report more then 55 teams you get that status.
This is the new big feature I introduce with version 4.0 of FIMPL. Users are now able to report new teams or update the teams information right from the app. As I want to expand to new types of sports the user is able to choose between football, tennis and ice-hockey. (at the moment there are like 50 amateur hockey places in FIMPL)
Crucial part of that was that I need the coordinates of the team, because thats the main business of FIMPL :) So how do I make sure that the user clicks on the map first? As you can see in the video I show only a map at the beginning of the reporting process. Only if the user marks a point on the map he is allowed to provide additional information and the map shrinks.
When the user clicks the map I get the address via reverse geocoding. Also I provide a guess for the teams name based on the locality. So if the user marks a point in Vienna I ask him in the name field if the team is “FC Vienna?” (bad example, but if I do it with the name of a small village here in Austria you don’t get the idea :) )
I also validate the fields name and address which are required, without them the user can’t submit the data. I do that with this framework. When the user submits data, my webserver creates a file with the new data, I check it and if its correct I add it to the JSON file.
I have several entry points to the reporting form:
- The user can access it via the menu
- The button on the card as mentioned above
- If he does not find anything via the search a button gets displayed or via a long press on the main map.
If the form is entered with one of the latter methods it gets pre populated with the given data. The map shrinks and via reverse geocoding address and name is prefilled for the user.
Have you noticed? I really want that the users report the data so I don’t have to do it! ;)
Letting the user know if teams he reported are available
Remember Martin, my coworker who made the Android version? He had this absolutely genius idea to personalize the experience of our web in an easy way.
The idea is to write a users id on the server per team when the user reports a team. When he downloads new data, the app checks if there is a team with his ID, if so, he gets prompted with a popup that the teams he reported/updates are now available in FIMPL. AWESOME!
So Martin hashes the time the user submits a team the first time. He then stores this ID to the device. For iOS although there is an even cooler way to realize this.
Each iOS user has an Apple ID and with this Apple ID he is unique. You can read more about that in this great article from Sebastian Kreutzberger. Basically what it does is that Apple assigns a unique ID per user per app! To cite Sebastian from his article:
It means that Apple generates these iCloud tokens not just based on the user but also relating the app it asks for it. So even if an app would publish all its tokens on the internet another app could not use that token to see if both apps do share users!
Another cool thing is that if the user opens the app on his iPhone and iPad the data is the same because iCloud generates the same ID based on the AppleID for FIMPL.
Isn’t that super awesome?
To bring back my JSON structure once more you can see that there is specific field for the user ID “Uid”:
“nam”: “SVD Langenlebarn”,
And in this ID I paste the generated CloudID from the user to hold all the teams he reported/updated.
If the GIFs where too short, here is an additional walkthrough:
Where to go from here?
There are some things I might try in FIMPL but I am not sure tough because FIMPL is just for such a small user group and I actually want to build apps for a broader audience.
One thing which I will do in the next days is that the user can “donate” via in app purchases. I will provide 0.99€, 1,99€ and 19.99€ as an in app purchase which the user can buy to donate some bucks so I can pay for my server, the domain, the developer certificate and maybe some PR things :)
I will sell these donations as beers the user could buy from FIMPL — you know footballers drink a looooooot of beer :)
Some additional ideas:
- A photoupload would be nice to get even more emotional binding
- Extensive facebbook sharing, so teams could post the location of the game to their fans via facebook and if a user clicks on the post inside fb, FIMPL or the Appstore with FIMPL opens.
- If FIMPL gets big enough local advertising would be an idea.
- Routing with other apps like Google Maps.
- Additional type of sports
- A tutorial at the very first start
- Spotlight Search and deep linking from Google searches
Well thats it! Thanks for reading so far, I hope that there are some things I could explain that you also understood them. If you have feedback or questions just ask!