There are tons and tons of tutorials out there about the topic. However, I couldn’t find anything explaining clearly how to handle complex situations that can happen in a real-world application.
All the examples I could find were basic: they start with a simple view where they put some data fetched by the view model. The View Model is kept alive by the view using
@ObservedObject variables. And that’s it.
In real-world applications, we have dependencies and pieces of logic that need to be properly orchestrated. We have subviews to which we need to pass bindings. …
Swift heavily relies on two types of entities: structs and classes. The main difference between the two is that structs are value types while classes are reference types.
The two differ in how Swift handles them in memory. Reference types are allocated in the heap, while value types are allocated in the stack. For variables on the stack, the memory is freed automatically as soon as the variables go out of the scope. Freeing the memory from the heap is not as easy, and different languages implement different systems for that.
Swift uses a static approach called Automatic Reference Counting…
When developing an app or a library, it can happen that we need to parse a JSON that has no fixed or known schema. It can also happen that we need to write an API that allows our users to send different kinds of data to a service. The classic example is a tracking API like this one:
func logEvent(named name: String, metadata: [String: Any])
Here, the users can put
Anything they want in the metadata:
Boolean and even more complex objects.
iOS comes with some APIs that can help us with this effort:
JSONSerialization. This API can…
Most apps have to perform network calls. We need them to retrieve data from a service, perform a login, or send data to a remote server.
At the end of the day, we often end up writing an abstraction over the networking layer, and we want to test this layer.
But, testing the networking layer is not as straightforward as it may seem. Networking inherently interacts with an external dependency: the backend. We can’t control that dependency and, if we rely on it, our tests become slow, flaky, and unreliable.
We want tests that are fast, reliable, and repeatable. To…
The main reason why classes are generally not properly deallocated in Swift is because of reference cycles.
In their simplest form, we have an instance of a class
A that holds a strong reference of another instance of a class
B that holds a strong reference to the first instance of
A has a reference of
B that has a reference of
A. In code, it looks like the following:
This is a…
Handling the keyboard is one of the annoying tasks that iOS developers have to do every time there is a screen with some input. It is also something that the platform should provide us for free.
At the end of the day, the keyboard is shown and hid by the system and the sizes and frames of the window and of the keyboard are known by the system.
However, we still need to manually listen to those events and react accordingly.
Today, I’d like to show a solution that will work out of the box for every view you are…
In my article last week, we explored how to write the layout of our apps using AutoLayout.
This technology is more declarative than manipulating the frames. Although it is more verbose, we can easily create a small Domain-Specific Language (DSL) to simplify it. It also takes care of many things automatically for us, which is a very nice plus.
This week I pushed the exploration a bit further. I wanted to learn how to animate layout changes in an MVVM application. …
When developing an iOS app with UIKit, we need to decide how to layout our views. The three alternatives are: Storyboard/XIB files, programmatic AutoLayout or manually set up the view’s frames. Among these three, the one that I know less about is programmatic AutoLayout, and I wanted to learn how it works.
From a very high-level perspective, AutoLayout lets us arrange our UI components on the screen by defining a set of constraints in a declarative approach. …
Modern apps have to communicate with a backend. They may use it for several reasons:
In the majority of the interactions, the data from the backend is well defined. There is a model with a fixed number of properties, with each property having a well-defined type. The client and the server agree upon this model: For every request, there is a corresponding response with a precise contract.
In other applications, the same requests may return different data depending…
When iOS apps begin to grow, we need to handle some kind of global state. The global state usually contains two kinds of information:
Whether the user is logged in or not is metadata. The app can use that information to show the profile page (when the user is logged in) or the login page (if the user needs to log in).