In his book Succeeding with Agile, Mike Cohn defined the concept of a test pyramid. Mike presented a visual metaphor depicting a pyramid of layers, where each layer in the pyramid represented a different type of software test. The idea is that the pyramid helps us to think not only about what type of tests we implement, but also about how much of each type we implement.
I just felt…different. Something was off, but I couldn’t say what exactly. I even told my wife that day that I just felt…weird. I didn’t feel sick exactly, more like I was not myself. A few days later I would get confirmation of what I suspected — I had contracted Covid-19.
It’s now been three weeks since those first symptoms appeared. The most impactful symptoms lasted about two weeks. While I was recovering, I decided that when I felt better, I would write something about my own experience, to provide something useful for anyone else who contracts Covid-19. So here…
Onboarding is the process of helping users to understand an app, and hopefully, encouraging them to continue to use it. Onboarding flows usually consist of one or more screens explaining how a user can use the app, and often involve some input from the user, e.g signing up, logging in, granting permissions etc.
In this post we will learn how to implement a simple app onboarding flow using SwiftUI.
Note 1: This post assumes at least a basic knowledge of SwiftUI.
Note 2: Shameless plug! The onboarding flow described in this post can be seen in my app Bikey. …
“Experience is simply the name we give our mistakes.”
I recently made a simple mistake.
An implementation which appeared correct, based on its initial usage, turned out to be incorrect when its usage changed.
But before we start, although this post describes the mistake I made and shows you how you can avoid it, the point here is not really the mistake…or even the way to avoid it. It’s a simple mistake, and it’s easy to avoid. The destination is not what’s important…it’s the journey, and the experience we gain along the way.
While playing around with SwiftUI, I decided…
This short post describes a Github Actions workflow to generate your Hugo-based website and publish it to Github Pages.
To learn more about Hugo and GitHub Pages, and how to use them to build your website, see my previous post.
Github Actions is a service from Github which allows you to automate parts of your development workflow (e.g building, deploying) based on Github events (e.g a merge to the master branch of a Github repository).
A Github Actions workflow is a automated process made up of one or more jobs, which we define in a YAML file. …
Xcode 10 includes a new build system, enabled by default, which improves build performance. This is a very welcome improvement.
R.swift is an open source library which makes it both easier and type-safe to use resources such as images, fonts, and segues. It’s a really cool library, and we have used it successfully at Zendesk for quite a while now.
When building a project which uses R.swift with Xcode 10, the build will fail with the following error:
error: Build input file cannot be found: /LOCATION/R.generated.swift
R.swift is integrated into projects using an Xcode build script phase. This phase…
Xcode’s interface builder allows us to configure layouts which will automatically change shape and size based on a range of environment variables, such as:
In this post, we will learn how to add
NSLayoutConstraints in interface builder which adapt to changes in these variables, allowing us to build universal apps which run on both iPhone and iPad.
First, some useful terminology.
Trait — Each of the environment variables described above is a trait; screen size, orientation, and adaptation.
Device configuration — A devices configuration…
The Zendesk Support app supports a number of languages, meaning that the strings we display in the app change, depending on the device language set.
Recently we encountered buggy UI component positioning when the device language was changed from the default language (English). This is shown below with Dutch.
Due to some ambiguous auto-layout constraints, the UILabel containing the string increases in size when the string grows in length, causing the next UI element, a UISwitch, to be pushed outside the bounds of the containing view.
Unit testing is invaluable in helping us to identify problems early in the development cycle, both in terms of the implementation and the specification. It also facilitates change, providing confidence that any future changes to the tested code won’t break its expected behaviour.
Key to unit testing is code coverage, which indicates what percent of the tested code was executed when the corresponding unit tests were run. Generally, we want to have a high percentage of code coverage.
Xcode 7 introduced a code coverage feature which allows us to measure and visualize code coverage.
In this short post, we will…
Recently, a feature required that we create a copy of a
UIButton. The duplicated
UIButton needed to look the same as the original, and targets/actions set on the original
UIButton needed to be set on the duplicate.
On iOS, if an object conforms to the
NSCopying protocol, we can arbitrarily create copies of it. Unfortunately,
UIButton does not conform to this protocol.
Luckily, there is a way around this. Since
UIButton (which is a
UIView) can be archived, we can use
NSKeyedUnarchiver to create an
NSData object representing our
UIButton, and then de-serialize this object to get an…