Developing for iOS is, most of the time, an enjoyable experience thanks to the diverse and powerful set of tools that have been handed to us in order to achieve great results with the lesser effort. These tools not only come from Apple, but from other third party contributors that are continuously pushing the bounds of the platform and making our lives much easier.
In this post we are going to discuss the tools we use at ticketea and more importantly: how and why they improve our work.
About our apps
First things first, what are we actually building at ticketea?
We have currently two apps in the App Store, both free to download: Checkpoint and Box Office. The former helps organizers validate assistants at the event, so they don’t have to deal with paper, long queues, or fraud.
The latter, Box Office, allows yourself to sell your own tickets created at ticketea.com and manage your sales or reservations with ease.
Both apps are written in Objective-C, since they were launched 4 and 3 years ago respectively. At that time Swift didn’t exist, so it wasn’t an option.
Living with Xcode
Xcode is the native environment to develop iOS apps, it’s what we use, and we are happy with that. Truth be told, it lacks some advanced features, like good refactoring tools that are in fact available in JetBrains’ AppCode, but it's perfect for what we need.
So, are we using this powerhouse at all? We all try to catch up every year with the latest features, but still, we end up chained with what we already had.
Currently, none of our projects is universal (same code that builds for both iPhone and iPad), so we don’t have trouble with screen sizes, nor orientations, but we do use Auto Layout, which has become an indispensable tool to design our interfaces in a very rich and declarative way. Using AL offers a lot of capabilities and allows us to work more freely with our design team. For us, views are not anymore about “this is here, and this is the actual size”, but more about “the user interface should behave like this”.
Nonetheless, it is difficult to master Auto Layout: it takes time and some headaches, but in the end, it is worth. The flexibility it returns to the developer is great, thanks precisely to the lack of absolute sizes and positions.
We normally deal with AL inside Storyboards (a file that contains different screens, and defintions about how they are communicated with each other). We generally try to do design business on design tools, so we rarely have the need for external libraries or coding the thing ourselves. We know that coding constraints is a bit ugly, but since we don’t do it that much, we are fine with it.
Truly, if you are not in love with AutoLayout yet, give it a chance, for it is heaven on earth.
Storyboards are greatly used in our Box Office app. They are really useful to keep track of our existing workflows, but of course they have some downsides: they can get really huge and difficult to handle if you 'feed' them well, and sometimes segues (the connectors that visually bind one screen to another) cause more pain than the ease they pretend to. If you have a complex navigation system as we have, we would strongly recommend you to put your app navigation under test, and keep your screens the more isolated the best from any part of the workflow that is not tightly coupled to them. Remember that missing segues don’t disturb your compiler and, what’s more important, the less a controller knows about navigation, the best.
For this reason, we follow two practices that are helping us a lot on the way when dealing with Storyboards.
The first one: tearing apart our storyboard files. These xml files are huge, so huge that version control conflicts are very usual, and oftentimes painful to solve. Even for the smallest change, we end up sometimes with lots of —automatically silently performed— alterations made by Xcode. For that reason, every workflow lives isolated in its own storyboard. It doesn’t prevent us from dealing with VCS conflicts, but it’s good enough to keep our sanity.
Moreover, at ticketea we use Loctite. It enables us to link one screen to another that is inside another storyboard. So why not using Storyboard Identifiers? You may ask (they are visual links provided by Xcode that bind storyboards). It is a great new tool introduced on Xcode 7!... but it doesn’t work on iOS 7. As long as we support the latter version, we will stick with Loctite.
That being said, there is another silent problem that lurks in the wilderness of our storyboard files: segues. Segues are bound to our controllers, yet they actually don’t know anything about them, even less our project. We knew from the beginning that using constants was the obvious way to go, but because segue identifiers have a weak (in other words, ‘non-existent’) relationship with the code that is calling them, we finally decided to put them all under a single file, so we could have a greater vision about what we had, and how were we calling them.
In order to automate this process we are using sbconstants, which is a ruby script that magically extracts all of our storyboard identifiers (yes, all of them!) and put them into a constant file. Our tests are now more reliable, our changes do not pass silently anymore, and our segue naming is much more consistent now.
Acceptance and unit tests
Apart from this —now ancient— technology, what other tools are at our disposal?
So what about unit testing? We moved toward the native solution, besides we are using some external and very popular libraries for it, such as OCMock and Nocilla (when enabled, it prevents your tests from accessing the network and stub your own testing server responses).
Build, Test, Fix, Ship!
Developers should be focused on being productive, avoiding repetitive and annoying tasks that don’t provide value to their work, and so we think at ticketea. Why wasting our precious time with tedious paperwork while instead we can hand it to the computer, get up, grab a cup of coffee, and ship our app right in the market?
That’s why we use Fastlane scripts to boost up ourselves. Fastlane is a toolset of command line tools that makes it very easy to build scripts that execute various time-wasting tasks. Things from bumping the app build number or having our changelog file in multiple languages, to sending builds to our beta channels, update the screenshots and info of our app on the AppStore, and many other iTunesConnect related tasks (Apple’s content and shipping service for apps, books, music, etc) are just a breeze now.
It’s easy to set up, easy to use and, if you want to get rid of it, it’s as easy as uninstalling it, because it’s not coupled to your iOS project.
So what about our beta-testing tools? What do we use to deploy pre-release versions of our apps, and furthermore, track any crashes our users could experience when it’s already shipped?
We think Fabric’s Crashlytics is the best tool for all of this since we are still supporting iOS 7.
With a really easy and non-very-intrusive installation, it provides instant notifications when any tracked app crashes, with a full stack-trace, description of the failure, and even information about the iOS version on use, device, free RAM, and some other interesting data: how many users are experiencing the same problem, on which version, etc. We definitely encourage any other iOS team to start using Fabric from day one, if it hasn't already. It provides a wide useful insight of what is preventing users from enjoying our apps. Because not being aware of our mistakes, doesn’t mean they don’t exist.
“Wait, so you don’t use TestFlight?” For pagans, TestFlight is an online beta channel that was acquired in early 2014 by Apple. Nowadays provides both internal and external groups of testers (app review required for the latter), but at ticketea we only use it for our external group of testers (usually theaters). Since there is no both alpha and beta channel on iOS, we rely on Crashlytics in order to ship our progresses to our internal testers.
It would be a really pity if we didn’t mention our dependency manager: Cocoapods! It’s hardly impossible to find any complex iOS project out there that doesn’t use Cocoapods to incorporate small libraries to it.
We have so many small pieces of third party modules in our Box-Office app that it would be barely impossible to deal with all of them without alcohol or some divine help. For the libraries that we cannot host publicly (ad-hoc libraries), we use gitlab
Also, it helps our team to be synced up when any of these dependencies need to change between versions or branches. Because, of course, we do use Git.
The path of the righteous man...
Git is the default Version Control System for any developer out there, and at ticketea we embrace it, and we strongly think everyone should too! A good knowledge of Git further improves personal efficiency and it’s a must on any project that relies on feature-driven development.
We follow a Git workflow similar to the one proposed by Vincent Driessen, so ‘master’ branch always follows app store releases, and ’development’ branch conducts stable versions of coming versions, so any new single feature departs from the latter one, providing it is a small one (but we know that’s a lie).
Thus, being able to change between commits, versions or tags in our code at anytime, provides us with fast access to the versions that are needed to put under test, and is a reliable guard if anything breaks at any time...
Many apps are really coupled to a back-end service, and without it, they are mere empty containers. And that’s pretty much our case. The problem is, what if our app cannot reach the server? What if it has new changes that we cannot deal with yet? And more importantly, why would anybody want to mess with a remote environment while there is a private one available?
That, and some other reasons, such as straightforward installations, quick setups and shared configurations, make virtual machines the best, if not the only option. At ticketea we chose Vagrant for that purpose, provisioned by Ansible’s automation tool.
We recreate our database and maintain our local servers ourselves, with some help from Git and from our colleagues, so we can test our code with no worries of breaking or polluting our staging or production environments.
So pretty please with sugar on top...
There is a lot of technology going behind the scenes when it comes to iOS, and we are not only talking about the bunch of frameworks provided by default, such as UIKit itself or Xcode IDE, but also tools provided by a very active community that builds enjoyable utilities that we love to learn and to use.