Unifying Our Mobile Experience — How State Farm Integrated Telematics Into Its Flagship App
By Scott Anderson and Travis Kessinger

We’ve had the privilege of working on the State Farm Mobile app for quite some time — Scott on Android (all the way back when the app was called Pocket Agent!) and Travis on iOS. Over the years, the app has undergone major transformations, from a complete rewrite to add tablet support, to a full redesign in 2017 — the same year it got its current name. In 2020, we added support for dark mode and rebranded the app to align with State Farm’s modernized vision.
Starting in September 2023, we faced our next big challenge: merging our standalone telematics app, Drive Safe & Save®, into the State Farm Mobile app. This effort spanned both Android and iOS platforms, requiring innovative solutions to deliver a unified experience across millions of devices.
In this post, we’ll share why we made this move, how we planned a seamless migration for users, the engineering challenges (and wins!) behind the scenes, and what we learned along the way. Plus, we’ll reveal the real-world impact with hard numbers and reflect on how this integration paves the way for future telematics innovation at State Farm.
Why Combine the Apps? Listening to Our Customers
Let’s talk about the two apps at the center of this effort. First, there’s Drive Safe & Save, a telematics app designed to empower drivers to personalize their auto insurance premiums based on how they drive. Using driving data, the app offers feedback to help users improve their driving habits. It also includes a feature called Accident Assistance, which detects crashes and can automatically notify emergency services, reducing response times and potentially saving lives.
Then there’s the State Farm Mobile app, our flagship app. It’s built around three key areas that customers rely on: Insurance, Claims, and Billing and Payments. It’s the go-to app for managing policies, viewing and downloading insurance cards, paying bills, and starting claims all in one place.
So why combine these apps? Simply put, it’s what our customers wanted. In a 2021 survey, about 80% of respondents said they preferred a single, integrated app experience. At the time, most users were only interacting with one app: the State Farm Mobile app or Drive Safe & Save, but not both. By merging the two, we’re giving more customers access to more features while simplifying their experience. For users, this means fewer apps to manage and more value in one place. For us as engineers, it meant tackling a unique and challenging migration to make this a reality.
The Challenge: Migrating Millions Without Missing a Beat
Planning the Migration: Strategy and Rollout
To ensure the migration proceeded smoothly, we implemented a controlled rollout strategy based on users’ auto policy state. This allowed us to implement the migration flow with a subset of users before expanding to the broader user base.
On both the Android and iOS platforms, the rollout was managed using Firebase Remote Config, where we maintained a list of auto policy states eligible for migration. This configuration allowed us to dynamically update rollout criteria without needing app updates or disruptions for users:

Guiding Users Through a Seamless Transition
When a user in the rollout group launches the Drive Safe & Save app, they are greeted with an “It’s moving day!” screen. This screen includes a button to initiate the migration process by launching the State Farm Mobile app. At this point, the Drive Safe & Save app continues to record trips and provide Accident Assistance to ensure there’s no interruption in functionality until the migration is complete.
Tapping the “Go to the State Farm app” launches a Firebase Dynamic link to direct users to the State Farm Mobile app, where the migration flow begins:

Permission Acceptance and App Deactivation
After logging into the State Farm Mobile app, users are required to accept all necessary permissions to enable trip recording. After the user accepts the permissions, a configured intent is broadcast to the Drive Safe & Save app, signaling it to deactivate.
Deactivation involves:
- Turning off trip recording in the Drive Safe & Save app
- Disabling the Accident Assistance feature, which is now handled by the State Farm Mobile app.
Balancing Complexity and User Experience
One of the biggest challenges in this migration process was balancing technical complexity with user experience. The goal was to make the migration flow as intuitive as possible while maintaining safeguards to ensure data integrity and continuity of features. By leveraging Firebase tools and carefully designed app interactions, we were able to achieve a migration experience that was controlled and user-friendly.
Engineering at Scale: How We Made It Happen
Modern Mobile Architecture: Under the Hood
To successfully merge Drive Safe & Save into the State Farm Mobile app, we needed a solid foundation that could support new features, scale to millions of users, and allow for rapid development on both Android and iOS. This migration was more than just moving code — it was an opportunity to modernize and align our architectural patterns across both platforms.
We focused on:
- Modularization: Continue breaking features into independent modules for better code ownership and parallel development.
- Feature Flagging: Using local and remote configuration to safely control rollout and minimize risk for users.
- Reactive State Management: Adopting modern, reactive patterns to keep UI and data in sync.
- Modern UI Frameworks: Leveraging Jetpack Compose and SwiftUI to accelerate development and improve maintainability, even as we integrated with our established codebases.
- Robust Security and Privacy: Ensuring all telematics features were migrated with strict attention to user permissions and data protection.
With this foundation in place, our Android team concentrated on Jetpack Compose and Model-View-ViewModel (MVVM) to deliver scalable, maintainable features, while our iOS team integrated a new tab using SwiftUI within our established UIKit app for a seamless user experience. In the following sections, we’ll share some technical details and insights from each platform.
Android: Jetpack Compose, MVVM, and Type-Safe Navigation
When we began developing the new Drive Safe & Save feature within the Android version of the State Farm Mobile app, the team already had some experience implementing features with Jetpack Compose and Model-View-ViewModel (MVVM) architecture using StateFlow. This migration effort gave us the opportunity to build on that foundation and gain even more valuable experience with these tools.
The Drive Safe & Save feature includes over 30 screens. By implementing consistent patterns across these screens, we were able to significantly improve development speed, quality, and maintainability. Below are a few ways we leveraged Compose and MVVM principles during this project:
Type-Safe Navigation with the Navigation Component for Compose
For the Drive Safe & Save feature, we used the Navigation Component for Compose to manage navigation between composables. This allows us to take advantage of type-safe navigation, reducing the risk of runtime errors and improving code readability:
private fun navigateToVehicleDetailsScreen(lifecycleOwner: LifecycleOwner, uniqueVehicleKey: String, navHostController: NavHostController) {
if (!lifecycleOwner.isAtLeastStarted()) {
SFLogger.d(TAG, "onNavigateToVehicleDetailScreen called, but lifecycle not at least started: not navigating")
return
}
val route = DssNavigationDestination.VehicleDetailsTO(uniqueVehicleKey)
SFLogger.d(TAG, "Navigating to $route")
navHostController.navigateSafely(route)
}
Reusable Composables for Consistency and Efficiency
To ensure consistency across screens, we embraced creating reusable composables. These composables are prefixed with “Sfma” to standardize their naming to indicate reusability. For example, we leveraged an SfmaCard reusable composable for the “About your discount” screen:
SfmaCard(
sideMarginResourceId = baseR.dimen.sfma_screen_side_margin_always_zero,
topBottomMarginResourceId = baseR.dimen.sfma_screen_side_margin_always_zero,
backgroundColor = SfmaCardBackgroundColor.GRAY,
strokeColor = SfmaCardStrokeColor.NONE,
) {
Text(
modifier = Modifier.padding(24.dp),
text = stringResource(id = R.string.dss_about_your_discount_reminder_body),
style = sfmaTextStyleBody(),
)
}
SfmaCard is now being used hundreds of times in the app, helping to ensure consistency and maintainability.
State Management with StateFlow Emitting Repositories
Our repositories emit StateFlow to provide a stream of state updates for ViewModels. This ensures that the flow of data from the repository to the ViewModel and eventually the UI is seamless and efficient.
class DssAuthIndexRepository : WebServicesManager.WebServiceCallback, RemoveServiceListenerCallback {
private val _dssAuthIndexStateTOMutableStateFlow = MutableStateFlow(DssAuthIndexStateTO())
val dssAuthIndexStateTOStateFlow = _dssAuthIndexStateTOMutableStateFlow.asStateFlow()
...
Screen State Defined with Sealed Interfaces
To manage screen specific state, we use sealed interfaces. For example, the DssVehicleDetailsScreenState interface encapsulates the various states the screen can be in, helping to simplify state management and eliminate warnings.
sealed interface DssVehicleDetailsScreenState : Serializable {
data object LoadingTO : DssVehicleDetailsScreenState
data class ContentTO(val dssVehicleDetailsContentTO: DssVehicleDetailsContentTO) : DssVehicleDetailsScreenState
data class ErrorTO(var appMessages: Set<AppMessage> = mutableSetOf(), val vehicleDetailsErrorReason: VehicleDetailsErrorReason) : DssVehicleDetailsScreenState
}
ViewModels and StateFlow for Reactive Data Handling
Our ViewModels use StateFlow to expose state updates to the UI. This helps keep the architecture reactive and ensures that the composables always reflect the latest data.
class DssVehicleDetailsViewModel(private val uniqueVehicleKey: String, private val savedStateHandle: SavedStateHandle) : ViewModel() {
val screenStateTOStateFlow =
savedStateHandle.getStateFlow<DssVehicleDetailsScreenState>(KEY_SCREEN_STATE_TO, DssVehicleDetailsScreenState.LoadingTO)
Composables for Screen Composition
Finally, our screen composables consume the ViewModel state and render the UI accordingly:
val screenStateTO by viewModel.screenStateTOStateFlow.collectAsStateWithLifecycle()
...
when (screenStateTO) {
DssVehicleDetailsScreenState.LoadingTO -> {
SfmaLoading(
loadingConfigurationTO =
LoadingConfigurationTO.LoadingWithDelayedTextConfigTO(stringResource(id = R.string.dss_landing_loading_label)),
)
}
is DssVehicleDetailsScreenState.ContentTO -> {
DssVehicleDetailsScreenContent(
scaffoldPaddingValues = scaffoldPaddingValues,
contentTO = screenStateTO,
onDiscountTapped = onDiscountTapped,
onAddOdometerReadingTapped = onAddOdometerReadingTapped,
onOrderNewBeaconTapped = onOrderNewBeaconTapped,
onPairNewBeaconTapped = onPairNewBeaconTapped,
)
}
is DssVehicleDetailsScreenState.ErrorTO -> {
when (screenStateTO.vehicleDetailsErrorReason) {
VehicleDetailsErrorReason.DSS_AUTH_INDEX -> onDssAuthIndexTechError()
}
}
}
By embracing Jetpack Compose and MVVM, we modernized our Android development approach, resulting in a seamless and reliable Drive Safe & Save integration within the State Farm Mobile app.
iOS: Blending SwiftUI into a UIKit Legacy
The iOS State Farm Mobile app has been around for some time now. Of course this means the app started out using UIKit for its user interface. Over time, as we updated our minimum supported iOS version (currently iOS 16) and gained experience with SwiftUI, we began integrating SwiftUI into the app. With the migration of the Drive Safe & Save functionality into the State Farm Mobile app, one of the first decisions was where to place this functionality. Prior to the migration, we had 5 tabs: Overview, Insurance, Claims, Finances, and More. The More tab had little functionality so we decided to remove it and create a new tab called Safe & Save for all of the new features.
The Setup
Around the time we started the Drive Safe & Save migration we were also starting to break pieces of our code up into more manageable pieces. For this Drive Safe & Save functionality we decided to create a target that would contain all of its functionality. While there are still lots of pieces of functionality in our main State Farm target, creating a new target allowed for overall better code organization.
For our UI related changes, we have an existing UITabBarController that was modified to include this new tab. Since our app is UIKit-based, we used UIHostingController. We created a DSSHostingController with content called DSSLandingView. This DSSHostingController lives in the State Farm target, allowing it to navigate to views in the State Farm target, such as the profile and preferences screen. For example, the following function is in DSSHostingController:
func didTapProfileAndPreferences() {
self.performSegue(withIdentifier: Segue.profileAndPreferences.identifier, sender: nil)
}
Managing State
The DSSLandingView populates its content from an API call. There are multiple states a user could be in with their vehicles. State Farm is an insurance company that offers more than just auto products, so it's valid for a user to have no vehicles. A user can also have one or more vehicles, with some being eligible for Drive Safe & Save, some enrolled, and some not eligible. In the view model, we have a published property representing this state as an enum:
enum DriveSafeSaveLandingState {
case determining
case enrolled
case notEligible
...
}
And in the view:
var body: some View {
switch state {
case .determining:
EmptyView()
case .enrolled:
EnrolledView()
case .notEligible:
NotEligibleView()
}
}
Navigation
Another item SwiftUI makes extremely easy to handle is navigation. We used .navigationDestination in places we need to push on views. For example:
.navigationDestination(for: ProfileDestination.self) { destination in
switch destination {
case .communicationSettings:
DSSCommunicationSettingsView()
case .contactUs:
DSSContactUsView()
case .helpTopics:
FAQTopicsView()
case .aboutTheApp:
AboutTheAppView()
case .profilesAndServices:
ProgramsAndServicesView()
}
}
This integration of a new SwiftUI tab into our existing UIKit-based iOS app allowed us to deliver Drive Safe & Save features with a modern, flexible user interface, all while maintaining seamless navigation and a consistent user experience within the State Farm Mobile app.
Improving the User Experience: Before and After
Merging Drive Safe & Save into the State Farm Mobile app was never just about reducing the number of apps on a user’s phone — it was about making every interaction simpler, more intuitive, and more valuable.
Before the migration:
- Users who wanted to enroll in Drive Safe & Save or view their telematics data needed to download, log in to, and manage a separate app.
- Many State Farm customers were unaware of Drive Safe & Save, or missed out on features like trip feedback and Accident Assistance simply because they weren’t using both apps.
- Switching between apps to manage policies, pay bills, and access telematics features created friction and increased the likelihood of missing important information.
After the migration:
- Everything is in one place: users can enroll in Drive Safe & Save, access driving feedback, manage policies, pay bills, and start claims all from the State Farm Mobile app.
- Drive Safe & Save features are now more prominent and accessible, leading to increased enrollments and engagement.
- The migration flow was carefully designed to ensure users didn’t lose access to critical features like trip recording and Accident Assistance, so the transition felt seamless.
- Unified navigation and consistent UI patterns make it easier for users to discover and use new features.
- With fewer apps to juggle, users have a more streamlined, reliable, and satisfying State Farm experience.
By bringing everything together under one app, we’ve not only simplified the customer journey, but also set a new baseline for what users can expect from their State Farm app going forward.
Lessons Learned: What Worked and What We’d Do Differently
No major migration comes without a few surprises. Along the way, we encountered unexpected challenges, uncovered opportunities for smarter solutions, and learned valuable lessons about both engineering and project management. In this section, we’ll highlight a few of the key insights and takeaways that will help guide us in future efforts.
Geocoding at Scale: How We Turbocharged the Trips List with Smart Caching
One of the most interesting technical challenges we tackled during the Android migration was optimizing the performance of our Trips Landing screen. This screen displays all trips taken by users and other drivers on their policy over the past 30 days. For larger households, this can mean well over 100 trips — each with its own data to load.

A key piece of information we display for each trip is the destination city, which we derive by reverse geocoding the trip’s ending latitude and longitude using Android’s Geocoder class. While the destination is being fetched, we show a loading state in place of the city name.
The Problem: Geocoder Bottlenecks
When displaying a large number of trips, we initially encountered performance issues related to reverse geocoding each destination in real time. This led to slow loading times for users with extensive trip histories, in part due to external service rate limits and caching behaviors.
The Solution: Lazy Loading and Smarter Caching
Credit goes to fellow engineer Andrew Erickson, who devised an innovative two-part solution that made the Trips Landing screen performant:
1. On-Demand Geocoding
Rather than processing every trip’s destination at once, we now trigger geocoding only for destinations that are likely to be viewed soon. This reduces unnecessary processing and network calls, especially when users scroll quickly through their trip history.
2. Optimized Caching
We enhanced our caching mechanisms to better handle repeat destinations and minor GPS variations. By grouping similar locations and leveraging in-memory storage, we minimize redundant geocoding requests and improve response times.
The Impact
Thanks to Andrew’s combination of on-demand loading and optimized caching, we slashed unnecessary Geocoder calls and cut down on loading times — even for users with very large trip histories. Users now see their trip destinations populate quickly, and the Trips Landing screen remains fast and responsive.
Optimizing destination city loading on the Trips Landing screen was a great example of how thoughtful engineering and innovative solutions turned a sluggish feature into one that feels seamless for users. These improvements translate directly to a more polished and reliable experience for our users.
Reducing Friction in Permission Handling
For Drive Safe & Save to work correctly, the Android version of the app needs several permissions from the user during onboarding. Shortly after release, we noticed a high drop-off rate on the location permission screen. We suspected that users may be downgrading the location permission from the settings screen, for example, choosing “Don’t allow”, then switching back to “Allow all the time.” On Android, this will trigger the OS to kill the app process.
The State Farm Mobile app’s security logic returns users to the login screen after a process death. This meant that when users downgraded a permission, that required users to log in again and navigate back to the Drive Safe & Save tab, creating a major friction point.
The Solution: Restore Sessions After Permission Downgrades
We added logic to detect permission downgrades and, when possible, restore the user’s authenticated session. This allowed users to pick up where they left off without having to log in again.
These changes led to an improvement in onboarding completion rates. Monitoring analytics and implementing Firebase non-fatal events helped us quickly identify and confirm the root cause of the drop-off, reinforcing the value of closely tracking critical user flows.
Estimating the Unknown is Hard
At the outset of the migration, we underestimated just how challenging it would be to predict our delivery timeline. Our initial approach to project management was rough around the edges — we were dealing with shifting requirements, new technical hurdles, and the complexity of coordinating two platforms. As a result, our story tracking and estimation lacked the rigor and clarity needed for a project of this scale.
After a few sprints of missed estimates and unclear progress, we realized we needed a better system. We invested in more disciplined story management: breaking down work into smaller, well-defined stories, setting clearer acceptance criteria, and regularly updating progress. We improved communication between engineers, product owners, and stakeholders to ensure everyone had a shared understanding of priorities and blockers.
With improved visibility into our backlog and progress, we could finally provide more accurate timelines. This new level of transparency also made it easier to make the case for bringing on additional engineering talent — helping us stay on track and meet our objectives.
The lesson: big migrations demand more than just technical skill — they require intentional, evolving project management practices to keep everything moving forward.
Need for Continuous Regression Testing
As development progressed, many stories impacted the same areas of the app’s codebase. After several sprints, both testers and engineers occasionally discovered that features completed in previous sprints had defects. This highlighted the need for a plan to maintain the quality of previously completed work throughout the project.
To address this, our testing team committed to ongoing regression testing for the duration of the migration effort. Each sprint, they revisited and validated features from previous sprints to ensure that recent changes had not introduced new issues. This continuous regression testing helped us catch and resolve defects early. It was easier for us engineers to resolve defects that were introduced recently.
This proactive approach to regression testing ensured that quality remained a top priority throughout the migration. By continuously validating previous work, we minimized the risk of defects slipping through and preserved high quality as new features were implemented.
The Results: Adoption, Stability, and Satisfaction
Millions of users have successfully migrated from the standalone Drive Safe & Save app to the State Farm Mobile app. This seamless transition has resulted in a significant increase in app adoption and engagement, with more users exploring features and returning to the app regularly. Here’s a look at the impact so far:
- User Growth: Since the migration began, the State Farm Mobile app has seen an approximate 20% increase in active users.
- Drive Safe & Save Enrollments: Monthly Drive Safe & Save mobile app initiated enrollments have doubled.
- Drive Safe & Save Trip Recording: Currently, 85% of all Drive Safe & Save trips are now recorded through the State Farm Mobile app instead of the legacy app. This number is projected to reach over 90% as more users complete the transition.
- Accident Assistance: Enrollments doubled.
- Exceptional Stability: Despite the complexity of the migration and the increase of new users, the app continues to deliver a crash-free experience, with an average crash-free rate of 99.98% on both platforms.
- Customer Satisfaction: Across both Android and iOS, the app maintains an impressive average customer satisfaction rating of 92.6%.
The Road Ahead: Expanding Telematics
This migration effort was a large team effort involving collaboration across numerous teams at State Farm. Engineers, designers, product owners, testers, and other stakeholders all worked together to achieve this milestone. For both of us, being part of such a successful and collaborative effort has been one of the highlights of our careers.
As proud as we are of this achievement, we know this is only the beginning. The integration of telematics into the State Farm Mobile app opens up exciting new possibilities for innovation. We’re just scratching the surface of what telematics can do to empower users, help improve driving habits, and enhance safety. The future is bright for telematics in the State Farm Mobile app, and we’re ready to continue driving forward!
To learn more about technology careers at State Farm, or to join our team visit, https://www.statefarm.com/careers
Information contained in this article may not be representative of actual use cases. The views expressed in the article are personal views of the author and are not necessarily those of State Farm Mutual Automobile Insurance Company, its subsidiaries and affiliates (collectively “State Farm”). Nothing in the article should be construed as an endorsement by State Farm of any non-State Farm product or service.
<hr /><p>Unifying Our Mobile Experience — How State Farm Integrated Telematics Into Its Flagship App was originally published in State Farm Engineering Blog on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>