The main reason for me was that as an engineer you need to stay up to date anyway so that is reason enough to learn a new topic. My way of learning has always been to write it down, summarize it, as well as creating a logbook myself for whenever I want to go back to revisit a certain topic. The logical step afterwards, for me, was to create a blog and use that to write down my learnings in a way that is beneficial for others to learn from. That process started very simply. My first articles were something like four short paragraphs, no intro, no conclusion, lacking the structure that you would expect from a good blogger. Over time, everything improved. But yes, the main reason was initially for myself, to build up a knowledge base that I could return to!
Yes, for sure! I’m often writing about something that I learned from my job, but it's also often the other way around. I find a new topic on the web or I learn of a specific topic that I want to dive into one day, and while I do, I create the article as well. Then in the next week, during my day job, I will be working and realize, hey that new technique that I just wrote about a week ago, will be a good tool to use now. It really works both ways for me.
Yes, well these are things that can be learned. I know I definitely was not as good a writer years ago as I am now. I get a lot of questions from other developers who want to start blogging, they all want to know how I keep it up? How I write a blog every week. I think they often struggle with the desire for perfection. They want to write a perfect article, they have imposter syndrome, and they don’t write it in one go. So on Monday you write down some ideas and leave it there. Then Tuesday you revisit it and you have new ideas, new thoughts, you think, no, this isn’t perfect, and they start re-writing it instead of finishing it up. Then Wednesday they get bored with the topic and scrap it instead of publishing it. My process is very consolidated. I have three hours to write before I publish, and then it goes out. If people like it, great and if they don’t that is their problem. I have at least released a new article, it might not cover everything, but it's good enough. With that mindset it becomes easier for engineers to start blogging.
There are many aspects to this. I don’t think there is any one thing that brought us to where we are today. First, I think that tooling has improved a lot. If you look at Xcode we have a main thread checker and thread sanitizer. Tools that you can basically use to get immediate feedback on “weird” crashes that you can sort right away. These are also crashes that you can look at in Shipbook and Firebase Crashlytics and that will give you feedback on those issues and a cure. Secondly, the third-party tools that we have today give us a lot of insight on how to solve crashes. Like bread crumbs, they give us insight on how to reproduce the flow, as well as the iOS ecosystem becoming more stable, more mature, and less easy to make mistakes. Like we don’t have problems with “retain” and “release” anymore, because we have ARC right now. The same with auto-layout that is adjusting views for screens automatically. Everything adds up. If you look at the future of Swift for example, it becomes even more mature as we got the new concurrency changes that make it very difficult to create race conditions and data races by adding compiled time feedback on possible bugs in your app. I guess the overall answer to your question is as the system becomes more mature, we have better tooling.
That’s always a nice discussion. I always try to prevent myself from using force unwrapping. That forces me to either create feedback for the developer implementing the feature by using fatal errors, and that’s only for configuration steps. Without any other option you wouldn’t skip that during a run of your app. You want to prevent those cases that you think of force unwrap can just take place here because you know it should be there. Often, you can just use a guard let, or an unwrapping with an error being thrown if the failure does exist and that way you will always end up with an app not crashing for the user just in case something changes in the future with your code. It might be obvious today that the force unwrap can take place today, but if you change something tomorrow, it might not be that obvious anymore. Our coding guidelines at WeTransfer are, even if you’re one hundred percent sure, try not to use the force unwrap. And there are several techniques to do that which contribute to the stable app that we have today.
Well, I could say yes, but if I look at our backlog, the answer is definitely no. We still have so many bugs open. That’s basically because, yes, you have to pick your battles. We have a close relationship with our support team, and whenever we see that multiple users are affected, we know for sure we have to deal with the issue. If ten users found the issue important enough to contact the support team, that means that there are likely some thirty other users that did not take that step but who are still being affected, so that is an important enough bug to pick up. On the other hand, there are bugs that only affect one user in a million, those are of course not worth spending our time on. So there is a distinction based on priority as to when we pick up issues.
Yes, I see what you mean… we have been going back and forth on that one. You see, why would you keep a level three priority issue open when you know that you are never going to have the time to pick it up. Although it does help prevent pickup reports if we keep bugs with a priority number one two or three open. So I think the answer right now is we keep them open, but it’s definitely not a consistent process. I can still at times close an issue because I’m almost certain we won’t pick it up.
I think the major tool for us is our own developed framework called Diagnostics. It basically allows the user to contact support and also includes two files. The first is a diagnostics report including logging from each session the user had, including network requests, user defaults, some custom reports regarding core data really helps us, system information and device information, such as iOS version, how much storage is left on the device, and other similar metrics. The second file is a copy of the core data database and all the user information is obfuscated. This allows us to replicate the exact state the user was in when encountering the bug, without actually seeing any of their information. It's quite advanced and it saves us so much time. Especially the diagnostic report because we can open it and in five minutes, we know exactly which bug it is and can match it to a user as well. This is because user A could say uploading is not working, and user B could complain downloading is not working, but the underlying error could be exactly the same. The diagnostic report is key to matching the bug to user complaints. We also use Firebase, but we are almost phasing it out because the tools Apple provides us alongside the diagnostics tool are enough in a way, except for tracking, but that is a different story.
I have experienced both. When we had QA teams within the company, in my experience they were all over the place, they weren’t really dedicated to our product, because everyone was able to pull them into their projects to test their products now. It has been a few years now that we are outsourcing our QA team in India, and it’s been nothing but great. They are fully dedicated to testing our app, they know our app better than I do. They find bugs that I don’t have any idea how they were able to find. They do a great job. In my experience outsourcing is better but I think if we had people as dedicated to our team in-house it would have worked as well.
This is an interesting question and it comes up in our company every now and then as well. For example, the claim that the engineers should spend more time writing UI tests which will be automated and replace the QA team. In my experience there are many facets to this. On the one hand there are unit tests, and we have so many unit tests in place. But still, QA has been able to find so many things that aren’t covered in the unit tests. And we have a lot of unit tests, our core code has something like 1,500 unit tests. It's just proven to not be enough to catch everything that QA catches. Then there is the UI testing flow. If we were to write them ourselves it would take a lot of valuable time from the engineers, who are more expensive than the QA team, on hourly rates. UI tests are slow so you need to constantly run and maintain them. It can be super time consuming - so all together - if I look at our project it's super cheaper to have a QA team. But to come back to your point on laziness I sometimes create features and not test myself, because I know that QA will test it anyway. Especially if I’m pretty sure it’s stable. So even if 1 time out of 10 it does come back from QA, it saves valuable time when QA is testing anyway.
We don’t do much monitoring other than Xcode’s organizational tools that are in pace. We have a key metric in app launch time, and Apple provides information quite clearly in Xcode itself. We’re also not in a position to investigate app performance that much which means we didn’t spend time researching app performance tools whatsoever. Because we don’t really need it, or we don’t have the time, we need to just focus on optimizing the things we have today. It's also the type of product we have- it’s not an app where we need to be focused on it operating as fast as possible. But if I did need to focus on app performance I would start with Xcode instruments and hands on performance optimizing instead of looking at the field data of real users. We have ondevice processing, and that is quite easy to reproduce locally. We don’t really need the information from users themselves. Although I can imagine that if performance was a key metric, the first step would be instruments but secondly you would want to see data from the field, and then you would look at third-party tooling.
Well in a way you could say that Swift has improved app quality once we can use the new concurrency changes, which we are now, not allowed to use because you need iOS 15 and up. Looking back, Swift 2 and 3 were such improvements that a lot of re-writing was required, mostly semantics and code-lines that needed to be updated. It didn’t affect performance, but as I said earlier, Swift 5.5 will be a major improvement regarding data race conditions, data logs and other kinds of similar aspects. We will need to watch Swift futures even more then, because the Swift language itself is becoming more and more feature rich. It contains all the basic features you expect from a language, and once you have that, you’ve achieved the goal that the Swift team has had since the Swift concurrence road map in 2017, I believe, which was the main goal of being able to produce programs that don’t crash and remain stable without having to have a lot of knowledge of memory management and those kinds of things. In the upcoming years, we will be super focused on that.
If you asked this one year ago it would have been async await. But today, I’d have to say build time improvements, all the way. That would increase developer productivity so much. It would be a game changer if we were able to just build a run in one second. I can’t even imagine what that would mean for so many projects. You know, we’ve been spoiled already with Swift’s UI previews. We use it more and more in our daily development. I use it in my side projects as well, and it’s such a productivity game changer already. But imagine you can do that for an Xcode application, that will be really incredible.
It was really wonderful to meet you and conduct this interview. Your input and answers are really interesting and valid for iOS developers, and in my opinion, for all developers in general.
Shipbook gives you the power to remotely gather, search and analyze your user logs and exceptions in the cloud, on a per-user & session basis.