How apps are actually built

Chris Stott at Swift Summit San Francisco, 2016


Chris: As I mentioned we're going to talk about how apps are actually built in the world. I'm with Buddybuild. Buddybuild started a couple of years ago and it was born out of our own frustration with trying to build an app. It was a horrible, horrible idea for an app. We were trying to build, essentially, Instagram for bad drivers, it was called “What an Idiot”. It was a side project we were messing around with, trying to get back into iOS development but we really wanted to have a really great workflow. Because we really believe that the workflow you have and the tools you use and your ability to iterate dramatically effects the quality of the apps that you produce.

Out of that, we started to think about how development work should be, and this is common across pretty much all software developments I think. Typically as an engineer, as a developer you create something. You create the app that you're building and you share it with people. You share it with your users, you share it with your clients, you share it with your product manager, your VPs, your team mates, your QA team and ultimately you share it with the world hopefully.

Your users use it and they test the app or use the app depending on who exactly they are and they will give you feedback on that. That feedback might be explicit or it might be implicit feedback. Explicit feedback might be a screenshot that says "Hey, this button is confusing to me" or it might be implicit feedback like analytics or crash reports. Then hopefully if you're doing things right, in my opinion, you listen to their feedback.

You action the crash reports, you read the JIRAs that were created and then you fix the bugs and improve the product. The fixes and the improvements go into the next build of the app, which you then share again and you go through this cycle. This is standard for all software but getting through this as quickly as possible and with as few interruptions as possible helps you build better apps. So throughout those circles, there are thousands and thousands of micro decisions you have to make. Do you use CocoaPods or do you use Carthage or do you use Swift or Objective-C or do you use hybrid apps. There's many, many decisions that, some of these are implicit and you don't even think about, but you've made just subconsciously. Some you would make very explicit choices. So as I mentioned this is kind of the way most iOS development workflows work. Maybe you have a continuous integration, maybe you have continuous deployment, you have some sort of feedback mechanism for getting crash reports and getting actual screenshots and things like that. That leads into development workflow.

We certainly found that this was a broken system. If you get it wrong you end up with it being very difficult to build your app. It becomes difficult to build your app so you can’t integrate as quickly so you go through fewer cycles and you end up, sadly, with a worse product.

This is one example of how frustrating it can be. If you google “Setting up iOS CI”, this is one of the top blog posts. It's a 19 page guide on how to set up Jenkins and connect it to TestFlight. It's been around for quite a few years and it's still hovering around the top of Google. By it's own admission it's, wow, this has been quite a journey and instead of spending the time that he was spending actually building the app and building his features, he spent this time trying to ... Spent 10 hours googling a cryptic error message and these kind of things. It's a painful process, so if you get the workflow wrong, it ends up hurting you and hurting your ability to build great apps.

So, I wanted to highlight some of the features in Buddybuild very quickly where we've made a few decisions to try and make setting those things up more easier for teams. Then after that I'm going to look at a ... We took a sample of a thousand apps in Buddybuild and a thousand actively developed iOS apps and looked at the kind of choices that they made for developing. Some of the things we had strong opinions of of how things would work, would be for example; CI should be zero config, we should be able to infer the settings you need to build your project and setting up CI should be a single button click. We should be able to infer schemes and infer where the workspace is and infer if you use CocoaPods. You shouldn't have to spend any time scripting that at all.

Another thing that's very difficult for iOS teams in general is managing provision profiles, managing code sign identities. Dealing with when you're trying to send a build to someone and their device hasn't yet been added to your Apple account. Actually the process of getting that UDID and actually adding it to the Apple account and then getting their build. That's typically been a very frustrating process. So we wanted to make sure that you could have automatic UDID management, so you could just send a build and just let software deal with that. Let it automatically work.

We also want to make sure that you have a really quick way of getting feedback from your testers, so you can listen to them and listen to, because you've spent a lot of time getting the build to them, and you want to make sure that you can actually listen to what they're trying to tell you. Having a screenshot, having something you can draw on screen, finding device information, finding NSLogs is super important.

The same with crash reports, typically getting a crash reported can be often really hard to debug. Call stacks are quite cryptic sometimes. So having more context, having ... This is jumping around too much, excuse me. Here we go. Yeah, so having the context, because say for example we built the code in the first place, we know the code where it crashed, so we can do things like show you the code where it crashed, we can show you not just that line of code but the actual code. We can do things like instant replay where on a testers device you can turn on recording video in the background so you can see exactly what they're doing on the screen up to the crash. All of those things give you more context to debug the issue and understand exactly how it was caused.

Same thing with managing Xcode versions. We have a feature called Xcode Preview where when a new version of Xcode comes out, not only do we get it available to people to use very very quickly but we also make sure, we'll take your last green build on your previous Xcode version and rebuild it with the new version. You get information telling you whether you're going to have some Swift errors with Swift 3.1 or whatever it happens to be.

The data I'm gonna look at, these are some of the companies that are using Buddybuild right now and the data I'm going to look at comes from companies like this, so it's across the whole spectrum of app development teams. From smaller projects to companies as large as Slack and Meetup. The data itself.

Where do people host their code? Is one of the interesting things that you start with. It's pretty much the first choice you have to make on a project, is "I have to put the code, I have to put my git-repo somewhere." Hopefully you're using a git-repo or some sort of source control. Do you put it in the Cloud or do you put it on something hosted on the side of your own VPN? Turns out like 95% of teams use Cloud hosting. There's a few, 5%, for whatever reason they're doing something behind their VPN.

Where do they put it when they do it in the Cloud? One of the things I found quite fascinating was ... While GitHub's very widely known, Bitbucket seems to be less widely known, but is used by almost the same number of teams, overall. There's a few others as well. When you look at where teams self-host, turns out Gitlab tends to be really quite dominant for self-hosting and Stash, which is Bitbucket's server and GitHub are like far behind in those numbers.

The platforms people are developing for. For example, this is really interesting if you want to consider a watch app. Watch apps seem to be very under-served, only 3% of apps actually contain a watch app, so there's probably opportunities if you think about developing your own app, so maybe adding watch support. If you start looking at what they're doing with watch support, you can see most apps have moved over to watchOS 2, but there are still some people who like developing on watchOS 1. And for tvOS as well, there's very few. If you look at the apps in Buddybuild, there's very few tvOS apps at all. Which kind of resonates with what I've seen from the platform in general. So there's probably an opportunity to start thinking about building TV apps, because it's probably an under-served market.

Same with supported iOS versions. I took this data just after iOS 10 came out and already 1% of people had started requiring for their apps iOS 10. But if you look at the other side of it, there's still 1% of people who are actually using supporting iOS 6, and you can imagine the headaches their development team must be going through trying to do that. The technologies teams use to build their apps. If you look at, within the set of a thousand apps, 9% of these apps use some sort of hybrid technology. Something like Cordova, something like Ionic, something like React Native. The remaining 91% are traditional, native Swift and Objective-C apps.

If you start looking down at the break up of this, this is a fascinating sight for me. One fifth of apps now, 21% of apps we're seeing are 100% Swift. They don't have a single file of Objective-C in them anywhere, even in their tests or in their project or in libraries, which is really quite amazing. There's a third of apps that still, a third of apps are not using any Swift whatsoever, but if you look at it, now we have two thirds of apps that are actively being developed, contain Swift. It's really quite a dramatic uptake in Swift. We’ll look at the project structure as well. Bitcode is pretty interesting, because recently Apple made bitcode defaulted and they're trying to push it into all apps. Only 1% of apps we see actively turn off bitcode, which shows that it's actually probably working quite well for people at this point.

The same with number of build configurations. Apps you can see, it gives you an idea of the kind of complexity people have when they build their apps. Most people have the default one and two for apps, but you see people having up to like 11 different build configurations, which is pretty incredible for different staging environments I imagine, things like that. Then extensions, as well. This is kind of similar to the watch app and TV app. Only 4% of apps actually use extensions. Only these apps are using Apple's platform to a fuller extent. If there's opportunities, you think about building your own apps, of adding Today extensions, adding Share extensions, adding ... You can differentiate your own apps by doing this. It's clear that many of the developers are not doing this.

Dependency management is really interesting, that's a choice everyone has to make at some point, because unless you write 100% of the code yourself, you need to pull in dependencies from somewhere else. If you look at what people use for dependency management, CocoaPods is used by 70% of the apps in this thousand set app sample. Carthage is used by 7%, so CocoaPods is clearly incredibly dominant in the industry, it's used by almost everybody. But there's a significant chunk of apps that decide not to use either CocoaPods or Carthage and just do dependency management themselves. Maybe through GitHub sub modules or maybe manually copying it. They choose to just do that themselves.

If you look at the number of Pods, some apps have an incredible number of Pods in there. Some have in the eighties, which I can imagine would be quite a nightmare. I've heard that Apple recommend no more than 6 dynamic frameworks included in an app. The versions of Cocoa ... This was taken a month ago or so before the 1.1 release came out, but you can see there's a lot of teams that are still using 0.39 of CocoaPods and not moving over to the 1.0 releases. One interesting thing I found, especially for CI and for collaboration is, 5% of apps don't check in their Podfile.lock, which is roughly saying screw you to your colleagues, I think.

You can see just in a thousand apps, there's an incredible diversity of the Pods used. 2,600 different Pods are used across these thousand apps, it's an incredible variety. It's an amazing kind of long tail. But if you look at the Pods that are really really dominant, you can see that the main Pods come from Google, come from Facebook, come from Twitter and then there's a series of amazing and well-used open source frameworks, that really fill in gaps where Apple hasn't really been providing the functionality and framework. Things like Alamofire for networking, most of these are networking, UI things, logging, JSON. It's really cool to see these big open source projects.

In terms of testing. I took a look at which of these thousand apps actually have some sort of test target in the repo. Maybe even if it's just a generated default one that Xcode gives you and they haven't touched it since, but 61% of apps have some sort of test target. 40% didn't even bother clicking, I'm gonna add test to my repo. But if you look at actually how many people run their tests in CI, the number's dramatically less. Only 16% of apps are actually actively trying to run test. Unit tests or Xcode UI tests. Where as 84% of people who are still doing CI aren't running a test. It shows how much room there is to improve the support for testing and the ability to run tests and writing tests within our community.

If you look at the frequency of tests as well. Most teams are writing maybe a few hundred, if they are serious about it, a few hundred tests. Then there's a few outlies where teams are just, all they seem to do and probably do is write tests and they're probably working in an incredibly test-driven way and that app has like 3,000 tests and probably takes a little while to run. As I mentioned earlier, hybrid apps take up 9% of this set of a thousand apps. If you look at what the ... If you look at React Native, React Native is really interesting because at the same time as Swift is taking over native development, it seems like React Native is taking over hybrid development and it seems like there's gonna be ... 6% of apps are React Native apps and that number is growing rapidly.

If you look at what used to be very dominant with PhoneGap and Cordova and something like Ionic, very rapidly those sort of apps that are choosing to use JavaScript and choosing to use hybrid technology, are switching over to React Native. So it seems at the same time as Swift is growing so rapidly on the native side, React Native is growing really rapidly on the hybrid side. I suspect we'll end up in a situation in a couple of years time, where the really, two dominant ways that people will be developing apps are Swift on the native side and React Native. From the data that we're seeing I suspect there'll be something like 20% of apps, are going to be React Native and the rest of the apps are gonna be pure Swift.

One of the interesting things about React Native is, as you saw the CocoaPods dependencies earlier, there's a very mature set of Pods that are used throughout many apps. But if you look at the same kind of data for React Native NPM dependencies, there's actually very few. There's only four dependencies that are used in more than 15% of the React Native apps. So it shows there's an immaturity in the ecosystem, so there's probably an opportunity for anyone who's doing React Native apps, to actually build up sharable components that can be used throughout that community, and that community is growing pretty rapidly. It's interesting that it isn't a pure choice between do you want to have React Native… or do you want to go hybrid or do you want to go native. But you can actually do a mix of them too. A third of the React Native apps happily use CocoaPods as well.

One interesting thing is custom scripting. In Buddybuild we try to build the experience where for most apps you don't have to do anything custom, but there's some people who, for whatever reason, their project, they want to do something special. Maybe they want to run some extra tests or maybe they want to do some Appium stuff, or maybe they want to archive their build to S3. So we have the ability for basically running any scripts and customizing the VM images as you want. I took a look at what people were doing inside these custom scripts. It turns out only 14% of people have felt the need to do anything custom whatsoever, which speaks to how standard most mobile workflows are. Only 14% of people actually need to do something custom. If you look at the things they're doing inside that. If you look at the kind of things they're doing inside that, then there's lots of things like npm install, things like curling, things like git-cloning, things like managing CFBundleVersion.

There's a few people of this thousand. This is the number out of a thousand, who do these things. Apple developer portal. Yeah, so one of the things we do in Buddybuild as well is to do the UDID and device management and provisioning profile management. We allow you to add a connection to your Apple developer account. I thought it would be interesting to look at how many people essentially say "Buddybuild, please take that pain away from me." And how many people want to just manage and control things themselves, independently.

73% of people add connections. So 73% of people essentially allow Buddybuild to automatically manage their Apple account. For whatever reason, 27% of people, maybe they're not allowed to by some process or maybe they don't want to. Then there are types of Apple accounts that people have, this is fairly interesting. Most people who are doing professional app development and who will be doing CI use corporate accounts. But there's a series of people who are individuals as well and doing this. But it's also interesting how many people are using enterprise accounts. I suspect these people are not doing enterprise accounts because their large corporations are doing actual enterprise work, but they're using enterprise to try and improve the beta test process, try and improve their distribution process.

The number of devices that companies have in their accounts. This is interesting, because as you probably know, Apple has this 100 device limit, on like number of iPhones you can have in your account. I looked at kind of the pressure that these apps face in their accounts and there's a lot of teams who are down to like 10, 20, 30 apps left. They're probably starting to face questions like "What if we can't do the sort of testing we want to do? We can't send it to the groups we want to send it to." The message there for Apple would be to increase that limit to something more generous so teams don't feel that pressure. Yeah. Thank you so much for listening to me. It's really fun sharing this information with you.