Feature flags give iOS teams the power to change app behavior remotely without waiting for App Store approvals. They make it easier to experiment through A/B testing, release gradually, tune configuration values on the fly, and disable problematic features instantly. This enables faster iteration, safer releases, and smarter decision-making based on real data. In this article, we’ll look at how feature flags work, common use cases, ways to implement them, and how they fit into a broader system.
Feature flag basics
A feature flag is a remotely controlled value that your app reads at runtime to decide what behavior to use. Instead of hardcoding constants or shipping new builds for small changes, you can control the app dynamically.
Feature flags can have different data types:
Bool — to turn features on or off
Number — to control thresholds, limits, or percentages
String — to select variants, layouts, or modes
JSON — to define structured configurations
Using JSON is especially powerful because it allows you to group related flags together in a single place. This makes versioning cleaner, simplifies configuration updates, and allows you to decode the data into typed Swift structures for safe and convenient access in code.
Feature flags aren’t just about toggling features on and off. They open up new ways to release, test, and maintain your app without unnecessary App Store updates.
A/B Testing & Experiments
Feature flags make it easy to serve different variants of a feature or flow to different users and measure which one performs better. This leads to data-driven design and product decisions instead of relying on guesswork.
Gradual Rollouts
Instead of launching a new feature to everyone at once, you can enable it for a small percentage of users, monitor its stability, and ramp it up gradually. If something goes wrong, you can roll it back instantly without waiting for a hotfix.
Remote Tuning
Flags can store values like thresholds, timeouts, or strings, letting you fine-tune your app behavior remotely. It’s ideal for making quick adjustments based on feedback or experiments without resubmitting to the App Store.
QA & Internal Testing
Unfinished features can be hidden using flags and exposed only to testers. You can use user properties or external data sources—such as a database field or an internal employee role—to control visibility. This way, a feature can remain invisible to regular users in production while being fully accessible to internal teams on all environments.
Emergency Rollback
If a new feature causes problems in production, a single flag flip can disable it for everyone immediately. This minimizes user impact and protects your release schedule.
Building feature flag system
There are several ways to build a feature flag system. You can use a third-party service, or build your own lightweight setup.
GrowthBook – open source with powerful experimentation tools.
ConfigCat – SaaS with targeting rules and team collaboration features.
Custom setups:
Static JSON hosted on a CDN — lightweight, fast, and simple.
Backend-driven JSON — full control and perfect backend-frontend parity.
Implementing feature flags in Swift
Each project has its own architecture, so there isn’t a single implementation that fits all. In general, it’s best to:
Have a dedicated service responsible for loading, storing, and exposing flags.
Use an enum to define keys for type-safe access.
Keep local defaults for when the device is offline.
Allow dependency injection for testing.
Flags should be fetched when the app launches, and ideally, the UI should wait until they are loaded. This prevents visible changes while the user is interacting with the app. You can also create a macro or property wrapper to make flag access cleaner and more convenient for developers.
Some feature flags should be treated as temporary infrastructure, not permanent fixtures. Each flag should have a clear owner responsible for it. Old or unused flags should be reviewed and deleted regularly to prevent clutter and technical debt. A lightweight approval process for creating and modifying flags helps keep the system clean and maintainable over time.
Backend-Synced Feature Parity
Using the same flag system for both backend and frontend ensures consistent behavior across your entire stack.
For example, a numeric flag can define a search radius for nearby users. The iOS app uses this value to draw a circle on the map, while the backend uses the same flag to query users in the database. There’s no risk of the two diverging.
Connectors
Some platforms let you connect your data sources directly. For example, you can use your application database to set conditions such as user roles, allowing you to target flags based on live data. This eliminates the need for maintaining multiple sources of truth.
Summary
Feature flags give iOS developers a powerful way to control behavior remotely, test ideas safely, and ship faster. They support A/B testing, gradual rollouts, targeted QA, and emergency rollbacks. A clean implementation with a small service, type-safe keys, and a good lifecycle process will make your system scalable and reliable.
If you have questions or want to discuss how to implement feature flags in your project, feel free to reach out to me on LinkedIn.
Run 80 miles in a month; do 2 000 000 steps in a year…
It doesn’t matter if you run, bike, or walk, fitness goals are indisputably beneficial for many reasons. They keep you on track towards your long-term plans whether it’s losing weight or running a marathon (or both). Since you clicked on this article, I will assume you track your workouts with your Apple Watch, and I will show you a few ways to track the fitness goals that will hopefully help you on your fitness journey.
Health app
A great starting point is the Health app you already have on your iPhone. There are many trends and statistics available in the Summary tab. If you set yourself a specific goal (for example the step count), you will need to open the data type detail and set the desired time period in the top selection bar. For example, to show daily averages by months select “Years” in the top selection. You can then click on each chart column to show the exact value.
The Health app is a simple solution that works out of the box, but it has some limitations as you can see. For example, if you’d like to view the above-shown chart in a total step count in months (not daily averages), you cannot do that. Another good example is the ran distance because the Health app merges run and walked distances, thus making it impossible to track how many miles you tracked in a running workout this month.
HealthExport Remote
I was frustrated with the Health app limitations and lack of any customizability. I think everybody should have the ability to view fitness data in a way that will be most useful for them. We are all different, so naturally, we want to see fitness data from a different point of view, thus a certain level of customizability is necessary. It’s great if you are happy with the Health app and there is nothing wrong with it, but I wanted to build something for people for whom the functions of this app were not enough.
HealthExport started as a simple iPhone app helping users to export Health data into CSV files. The app features expanded as time went on. A year after the initial release I launched HealthExport Remote service that lets users access fitness data from a browser. The website gives users the option to create customizable dashboards, which is the primary way I track my fitness goals nowadays.
Let’s go back to the example we talked about. My goal is to run 100 kilometres in a month.
I created a “Running” dashboard with four charts. The two charts in the first row are gauges showing my goal progress this and the previous month. Then there is a bar chart and a table visualizing monthly sums of ran distance in this year. The best thing is that you can tailor the dashboard exactly to your needs and you can have as many of them as you want. There are also other sections on the website like Workout and Nutrition overviews.
I could talk about dashboard configurations for hours, but the strength of the service is its customizability and you are the only one who knows what charts and layouts will be most useful to you. There is a month free trial so you can try the service and cancel it if it won’t meet your expectations. I built HealthExport as a service for me and other fitness enthusiasts, so I will be more than happy if you reach out to me with any feedback or feature suggestions.
I hope this article helped you on your fitness journey and I wish you all the luck in meeting and execting your goals.
Push notifications are a great way to communicate with your users. They let you inform the user about what’s going on. Another good usecase is to remind potentially lost users about your app (a user who didn’t use the app in a while).
In this article, I’m gonna assume you know the basics of push notifications. If you’ve never implemented them yet, check out for example the Firebase Cloud Messaging getting started guide.
Today I want to talk about improving the user experience of push notifications. Sure, the basics work, but I think we can do better. One way to improve the UX is to think about these two cases:
The user receives a notification while the app is in the foreground
The user launches your app and has an active notification
Usually, we attach notification actions only to opening the notification, but that doesn’t have to be that way.
I recently thought about this for EventBattle - a scavenger hunt mobile game. We want to ask our users for feedback once they played for a while and we use push notifications for that. Let’s think about the two cases listed above. If the app is in the foreground, we can show the feedback dialog right away and there is no need to show the notification. If the user launches the app and has an active feedback notification, it would be nice to show the feedback dialog and cancel the active notification.
Receive the notification while the app is in the foreground
UNUserNotificationCenterDelegate has function userNotificationCenter(_:willPresent:withCompletionHandler:), where you decide how to handle incoming notification while in foreground. In our case, we want to check the notification type and also verify the applicationState just to be sure we’re in the foreground.
funcuserNotificationCenter(_center:UNUserNotificationCenter,willPresentnotification:UNNotification,withCompletionHandlercompletionHandler:@escaping(UNNotificationPresentationOptions)->Void){switch(notification.notificationType,UIApplication.shared.applicationState){case(.feedback,.active):// Handle the notification herecompletionHandler([])default:completionHandler([.alert,.sound])}}
App launch with an active notification
We can use the getDeliveredNotifications function on an UNUserNotificationCenter to get active notifications, ie. notifications currently displayed to the user. Thus it’s simple to check if there is some active notification we are looking for.
I hope I gave you a new perspective about push notification’s UX. It’s always good to think about outside the box. Yes, you can attach the action to click on the notification, but maybe other ways will make the application more pleasant for your users.
The software development field is changing rapidly. Apple announces a lot of changes at their yearly WWDC conference. Recently, Apple started to release new features even during the year (like the mouse pointer support introduced last Spring). Besides the iOS SDK, there are a lot of best practices, frameworks, architectures, etc. that don’t have any update schedule. Until now I’ve talked only about keeping up with changes, but nobody knows everything so we should also strive to learn new things. All in all, learning is an essential part of a developer’s life. Today, I want to share my tips for learning resources.
Apple introduced the Developer app back in 2019 and it has been a good resource for me ever since. You can find all the WWDC sessions inside the app, with search, transcripts, bookmarking, and other nice features. In addition to the dub dub videos, Apple posts interesting articles inside the app. It’s free to get the app from AppStore, so I encourage everyone to download it and give it a shot.
John has been writing articles about iOS development for ages. I’m sure you have visited his website already through a link in Google search results. John divides articles into categories and there is also a search so you can always find what you are looking for. If you want to learn something new but don’t know what, check out the Discover section.
Hacking with Swift is similar to Swift by Sundell. Paul is a good teacher with many years of experience. You can find pretty much everything on the website. Paul is also known for quickly publishing articles about just released new iOS SDK changes (like within a few hours). There is also Hacking with Swift YouTube channel you can check out as well.
Standford CS193p is a course recording from Standford university as the name suggests. It’s completely free to watch it. The course is aimed at beginners, so this is the resource I recommend to everyone who wants to start with iOS development. The course has been around for ages and, actually, I learned the basics of iOS development with this course years ago. Don’t worry, they publish a new version of the course every year, so it’s not outdated.
Podcasts
My favorite way of learning new things nowadays are podcasts. I like that I can listen to them while doing other things such as driving or working out. When I hear something interesting, I bookmark it with the Airr podcast app so I can look up more information about it later on a computer. My favorite podcasts about iOS development are:
Under the Radar by Marco Arment and David Smith
Stacktrace by John Sundell and Gui Rambo
Swift by Sundell by John Sundell
AppForce 1 by Jeroen Leenarts
I hope you have discovered a new learning resource while reading this article. There are a lot of resources and I know I’ve missed some good ones so take this list just as a starting point. I always like to chat with people on Twitter, so feel free to reach out anytime if you have a recommendation for a learning resource, feedback about my article, or just want to chat in general.
Most professional cameras nowadays still don’t have a build in GPS module. When you are photographing a wedding, you probably don’t need GPS coordinates. On the other hand, one of my hobbies is traveling. I like to take photos during my trips and I’d like to view them later on a map. But my Sony A6500, unfortunately, doesn’t have a GPS module.
Recently I’ve been looking for a solution to this problem and it turns out to be quite simple. There are tools that can add GPS coordinates to photos based on a GPX file. Let’s look at how to do it.
GPX file is a file containing a series of GPS coordinates. There are many GPX recorder apps available on AppStore and Google Play. In my case, I track my outdoor photoshoots with my Apple Watch as outdoor walks, so the location data is already being tracked. To generate the GPX file, I use one of my iOS apps - HealthExport app.
When you have the GPX file, you need a tool that can associate images with GPS coordinates in the GPX file. I use exiftool, which is available for free at https://exiftool.org/. After you install exiftool, you can open the Terminal app on your mac (command line on Windows) and type following command:
exiftool -geotag"{path to your GPX file}""{path to your folder with photos}"
If you have any feedback or question, feel free to reach out via Twitter.