Enhancing Observability in iOS Applications: Key Insights
Take a closer look at how to implement observability more easily and why it is so important to improve app performance and provide a better user experience.
Join the DZone community and get the full member experience.
Join For FreeMy name is Siarhei Misko, an iOS Team Lead with over eight years of experience. Today, I want to walk you through the essential topic of observability in mobile applications, focusing on iOS. We are going to take a closer look at how we can implement observability more easily and why it is so important to improve app performance and provide a better user experience.
Why Observability Matters
The very fundamental question is: how do we ensure our application is stable and working fine? Conventionally, the answer would point to testing. We fire up QA tests by using various test cases, test environments, and on specific devices. The thing is, these tests are synthetic and mostly remain incapable of reflecting real-world scenarios. In the real world, applications go through much more complex environments, and here is where observability bridges the gap between test conditions and real-world functionality.
Observability does not originate from another technical buzzword, but rather from engineering and systems analysis. Thus, in the parlance of software and particularly mobile app development, observability describes a system's ability to report on its internal state and operations. This is like designing a system to be intrinsically stable and secure in that the system will be one that actually informs you about what could go wrong.
Observability isn't just about collecting traces, metrics, and logs. It's the tools that grant observability, but aggregating all this stuff into one focal point is what true observability is. Teams could monitor trends through this aggregation, visualize them in dashboards, and even trigger alerts when thresholds of incidents were reached. This sort of observability will enable people not only to respond quickly when there is an emerging issue but also to make predictions before things start to go wrong.
Imagine a system that tells you exactly what went wrong and why. That's the power of observability. With great observability in place, teams can instantly identify the root causes of issues, minimize downtime, and by doing so, improve overall user experience.
Observability in Practice: Learning from Failures
Let's take a very real example: consider some iOS project, having absolutely no observability features such as analytics, logging, or crashlytics. Within this imaginary case, the team launches a new release, and voil̀a: users start reporting crashes — sometimes when opening particular screens, or sometimes totally at random. The team tries to reproduce this issue on their own, but it's all working fine in their environment. No clear data to work from means they're ultimately just guessing, hoping their fixes fix the problem.
If this app had been using tools such as crashlytics, it would have instantly caught crash data, like stack traces and device information. This will give them the information they need to find out how to solve the issue. Apple has some basic functionality by default for tracking crashes, but it is pretty basic. That's why many developers use third-party solutions, such as Firebase Crashlytics, which not only captures crashes but even helps identify the potential causes.
Expanding Beyond Crashes: Performance and Feature Flags
Crashes in and of themselves are not the only problem that could lead to dissatisfied users. In fact, many non-crash issues could be far worse. The more complex a system becomes, the more variables will involve things like different devices, OS versions, and feature flags.
Think feature flags: a product manager mistypes or misconfigures something within their feature flags, and all of a sudden parts of that functionality aren't available. Maybe everything seems to be fine on the server side, and maybe crashlytics shows nothing, yet it still affects users. Observability enables engineering teams to keep track of how features will actually run under real-world conditions like flag configuration, device compatibility, and settings within an app.
Another challenge is testing: you can never simulate every possible usage scenario. That's where observability steps in: it helps you build metrics on how your app is doing, even under very specific conditions, such as on specific phone models, OS versions, or for certain app settings.
Key Metrics for iOS Observability
Where would you start when it comes to implementing observability in iOS apps? Following are three key areas to focus on:
- Important user stories: Focus on critical flows that include registration, login, processing of payments, and sending of messages. It helps you observe not only whether these flows work but also how well they perform.
- Dynamic parameters: Most features operate based on dynamically changing parameters related to country codes or feature flags. Observability in this respect helps you in the capture of errors caused because of these misconfigured parameters.
- External dependencies: An application may depend on services or third-party APIs. Ensuring that in case of their failure, observability will make sure that you will be able to detect the issue and take action before it affects users.
Implementing Observability in iOS: Architectural Solutions
Speaking more about iOS observability, architectural considerations become important. A well-structured app makes a lot of things easier to implement when it comes to observability tools. You also need to explore best practices from fields such as DevOps and backend development — quite often, these share a lot of valuable insights for mobile apps.
Almost all observability is based on logging. While metrics indicate the overall health of a system, logs capture an in-depth view of what happened inside the app. Logging has a number of problems: there might be too much overhead. Here are a few ways to manage logs on iOS:
- Live or online logging: In this mode, logs are sent right after recording. Though the latter is common in most of the backend systems, it tends to result in data overload for mobile apps.
- On-demand logging: Logs can be sent either manually by the user or automatically due to certain triggers. Examples include a flag created for any login or a push notification. This is useful for troubleshooting issues in a focused manner.
- Triggered logging: Logs will be sent only after an event occurs, such as a crash or an error.
Whichever you decide there are ways to handle your logs properly. For instance, it is not necessary to record every log at any time. This will cause your disk to become overloaded, which you wouldn't want. Work with log file rotations to limit the file size and handle log levels accurately. Make sure to include only the most critical logs in your release builds.
Logging in iOS: Tools and Techniques
Log collection in iOS can be done in a number of ways. Apple's OSLog is quite strong, but it also includes a set of limitations. For example, retrieval of logs from extensions or past sessions of the app is not possible. While OSLog is well-integrated with iOS, the process of accessing the logs themselves is somewhat cumbersome and therefore not the best for real-time analysis.
Instead, consider logging to a text file, or third-party solutions like Firebase Crashlytics. These give you more flexibility, such as logging more data at the time of a crash, like user roles or subscription statuses. Firebase itself is a great starting point, but beware of some of its limitations, which include data sampling and being unable to execute user-created queries.
Optimizing Logs and Metrics for Performance
Logs and metrics can be quite verbose, so some optimization is in order. One of the ways this would be achieved would be to log only important events — not to log each event, but only key system states. Instead of trying to log all user interactions, like mouse movements and keystrokes, track high-level events in an app, such as screen transitions or API requests. This will reduce the volume of data down to a more digestible volume and will simplify any analysis that needs to be conducted on it.
In more complex cases, such as when processing Notification Service Extensions, observability may provide step-by-step process tracking. Notification extensions have very tight memory limits of 24 MB, where exceeding this limit may kill a process. Observability enables you to trace every step of the process with confidence that no steps were skipped and no unnecessary overhead happened.
Leveraging Architectural Patterns for Observability
Finally, let me address how architectural patterns can contribute to observability. The coordinator pattern turns out to be really good at knowing exactly how the user navigates through the app —it provides all the transitions between screens and thus a clear view on where the user has been and where the app currently is.
You can monitor something like app start time — for instance, how long it takes for an app to transition from launch to some state. Or you can observe user flow completion times, such as how long it takes for users to make a payment. If users suddenly take longer in completing one, observability allows you to find problems much faster.
Also, you can apply user behavior tracking metrics, such as Annoyed Tap — a metric that tracks the amount of taps on a single UI element in a short period of time, which may indicate frustration or a malfunctioning feature.
Conclusion
By implementing observability in your iOS applications, you ensure stability, performance, and a much better user experience for your app. With well-thought-out implementation of logs and metrics, besides architectural patterns, you get real-time insight into the behavior of your app and are able to detect and fix problems much faster. Keep in mind that observability is not a replacement for classic testing, but a strong boost to make your app resilient under real-world conditions.
Thanks for reading, and good luck implementing observability in your iOS projects!
Opinions expressed by DZone contributors are their own.
Comments