Skip to main content
Mobile

Architecting a Safe, Scalable, and Server-Driven Platform for Driver Preferences with RIBs

March 1, 2019 / Global
Featured image for Architecting a Safe, Scalable, and Server-Driven Platform for Driver Preferences with RIBs
Figure 1: The Preferences Hub in our new driver app lets driver-partners customize their experience, creating a greater degree of satisfaction for all users.
Figure 2: A toggle switch lets teams implement simple on/off preferences the driver can select on the app.
Figure 3: A multi-select widget lets teams implement more complex preferences, such as this example which lets driver-partners select destinations for ride requests they receive.
Figure 4: While we include pre-built widgets for obvious use cases, we designed the Preferences Hub to allow customized interface components to support future needs.
Figure 5: This custom interface component enhances usability for selecting trip types. Similar to our standard widgets, it is integrated into to the app and powered by the backend.
if preference.id == “trip_type_pref” {
  // custom widget rendering code for trip type pref
  // custom widget business logic for trip type pref

} else if preference.id == “dropoff_areas_pref” {
  // custom widget rendering code for dropoff areas pref
  // custom widget business logic for dropoff areas pref

} else {
  // render generic multiselect widget
  // generic widget business logic

}
if preference.id == “trip_type_pref” {
  let tripTypePrefRouter = tripTypePrefBuilder.build()
  router.attachChildPrefRouter(tripTypePrefRouter)
} else if preference.id == “dropoff_areas_pref” {
  let dropoffAreasPrefRouter = dropoffAreasPrefBuilder.build()
  router.attachChildPrefRouter(dropoffAreasPrefRouter)
} else {
  let genericMultiSelectRouter = genericMultiSelectBuilder.build()
  router.attachChildPrefRouter(genericMultiSelectRouter)
}
Figure 6: The PreferencesHubRIB contains a plugin point that allows developers to add individual app components that do not interfere with code core.e code.
Figure 7: This RIBs diagram of our driver app shows how we can nest plugin points, allowing multiple teams to build features for the app that do not interfere with others.
let plugin = preferencesPluginPoint.createPlugin(for: preference)
let router = plugin.build()
router.attachChildPrefRouter(router)
class DropoffAreasPrefPlugin: PluginInterface {
   init(dependency: PreferencesComponentDependency) {
       super.init(pluginSwitch: .dropoffAreasPref) { context in
           return DropoffAreasPreferenceComponentBuilder(dependency: dependency)
       }
   }
  override func isApplicable(for preference: Preference) {
      return preference.id == “DROPOFF_AREAS” && preference.type == .multiselect
  }
}
“experiments”: [
   “plugin_switch_dropoff_areas_preferences”: true
]
Figure 8: Our plugin architecture lets us enable or disable components, a very useful functionality if a new component does not operate satisfactorily.
Brett Dupree

Brett Dupree

Brett Dupree is a Software Engineer on Uber’s Driver Experience team.

Quynh Nguyen

Quynh Nguyen

Quynh Nguyen was a Senior Software Engineer on Uber’s Driver Experience team.

Bao Lei

Bao Lei

Bao Lei is a Senior Software Engineer on Uber’s Driver Experience team. He occasionally drives for Uber to experience the Uber driver app firsthand.

Posted by Brett Dupree, Quynh Nguyen, Bao Lei

Category: