Migration Guides

Migrating to Rover 4 from Rover Campaigns 3.x and Judo 1.x - Android

Welcome to Rover 4.

The purpose of this guide is to aid you in adopting Rover 4 from your existing Rover (sometimes referred to as Rover Campaigns) 3.x and Judo 1.x setup. The Rover 4 SDK supersedes both the Rover 3.x and Judo 1.x SDKs.

We'll begin by replacing Judo's Maven repository with the new Rover Maven repository and removing the old SDK dependencies.


Replace SDK Installation

First, begin by replacing Judo maven repo declaration in your top-level build.gradle or settings.gradle. Note this repo was used even for Rover-only customers:

Remove:

maven {
    url 'https://judoapp.github.io/judo-maven/maven'
}

Then, ensure the new Rover Maven repository is present:

maven {
    url "https://roverplatform.github.io/rover-maven/maven"
}

No other Rover or Judo repositories are needed. If any other previously used Rover or Judo Maven repositories are present, they can be safely cleaned up.

Then, update the Rover SDK dependency in your app's build.gradle.

You'll have multiple Rover Campaigns modules listed in your app's build.gradle. You should update all of these

Remove:

// Rover Experiences standalone renderer:
implementation "io.rover:sdk:3.8.2"
// Rover Campaigns modules:
implementation "io.rover.campaigns:core:3.11.0"
implementation "io.rover.campaigns:notifications:3.11.0"
implementation "io.rover.campaigns:experiences:3.11.0"
implementation "io.rover.campaigns:location:3.11.0"
implementation "io.rover.campaigns:debug:3.11.0"

Note the io.rover:sdk dependency on the first line. It is possible you have also this in your build.gradle. This was actually the standalone version of what we now call Classic Experiences, and has been entirely integrated into Rover 4 SDK's experiences module. You can now safely remove this dependency entirely.

Replace with:

implementation "io.rover.sdk:core:4.0.0"
implementation "io.rover.sdk:notifications:4.0.0"
implementation "io.rover.sdk:experiences:4.0.0"
implementation "io.rover.sdk:location:4.0.0"
implementation "io.rover.sdk:debug:4.0.0"

Note that this should apply to all Rover modules you have installed. If you had any other Rover Campaigns modules installed, such as io.rover.campaigns:ticketmaster, you should update those as well to the new naming and version number.

See Android - Installation for more information.


Remove Judo Initialization

You can now entirely remove the Judo initialization call from your app's application class:

Judo.initialize(
    ...
)

Update Package Imports and Rover Singleton API Calls

Any imports you had of io.rover.campaigns should be replaced with io.rover.sdk. These may occur in your source files and in your manifest entry for TransientLinkLaunchActivity.

Thus, in your code files:

import io.rover.campaigns.core
import io.rover.campaigns.experiences
// etc.

These should be replaced with:

import io.rover.sdk.core
import io.rover.sdk.experiences
// etc.

And, the same for TransientLinkLaunchActivity:

<activity android:name="io.rover.campaigns.core.routing.TransientLinkLaunchActivity" android:exported="true">
    ...
</activity>

Becomes:

<activity android:name="io.rover.sdk.core.routing.TransientLinkLaunchActivity" android:exported="true">
    ...
</activity>

The singleton API for Rover has also been renamed in Rover 4, and additionally the optionality of the shared accessor has been removed.

Replace your initialize call with the new singleton name, Rover:

RoverCampaigns.initialize(
    ...
)

and replace it with:

Rover.initialize(
    ...
)

Now we'll replace any usages of the Rover shared singleton object. Note that the accessor is now non-optional.

So, replace any previous calls to:

RoverCampaigns.sharedInstance // (or .shared, which did previously exist but was optional)

with:

Rover.shared

If you still require a failable accessor (that returns null instead of failing in the event of the SDK not yet being intialized), use Rover.failableShared.


Set up Experience Activity Color Theming

Previous versions of Rover relied on the Material theme set on the ExperienceActivity in the manifest to determine the color for auto-styled app bars.

However, to make this behaviour more explicit and allow for smoother integrations with Jetpack Compose-based apps, this is now done programmatically.

ExperienceAssembler now takes a new parameter, appThemeDescription, where colours are provided explicitly.

See Android Installation - ExperienceActivity Color Theming for details.


You will have previously registered custom routes (such as in your AndroidManifest.xml or other routing tool) to handle Judo links to your app. Now that we're removing the Judo SDK, we can now direct these links to the new Rover 4 SDK instead.

Update your Routing

If you're using Manifest-based routing, you can make this change by moving your intent filters previously given in your app.judo.sdk.ui.ExperienceActivity to your entry for Rover's TransientLinkLaunchActivity.

For example, you likely had a manifest <activity> element like the following. Remove it and move the intent filters over to your io.rover.sdk.core.routing.TransientLinkLaunchActivity entry:

<activity android:name="app.judo.sdk.ui.ExperienceActivity" android:exported="true">
    <!-- An Example Intent Filter that opens Experience links in Judo's ExperienceActivity -->
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />

        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

        <!-- Include the Judo domain(s) you have configured -->
        <data android:host="brand1.judo.app" />

        <!-- Always include these two schemes for standard Experience links -->
        <!-- eg: https://brand1.judo.app/my-experience -->
        <data android:scheme="http" />
        <data android:scheme="https" />

        <!-- Lastly, you can also opt to use allow a custom scheme in your links (aka "deep links") -->
        <!-- eg: example://brand1.judo.app/my-experience -->
        <data android:scheme="example" />
    </intent-filter>

</activity>

Now you'll move those intent filters to your TransientLinkLaunchActivity entry instead:

<activity android:name="io.rover.sdk.core.routing.TransientLinkLaunchActivity" android:exported="true">
    <!-- your existing Rover intent filters should remain here -->

    <!-- Your newly copied over intent filter for your Judo domain -->
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />

        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

        <!-- Include the Judo domain(s) you have configured -->
        <data android:host="brand1.judo.app" />

        <!-- Always include these two schemes for standard Experience links -->
        <!-- eg: https://brand1.judo.app/my-experience -->
        <data android:scheme="http" />
        <data android:scheme="https" />

        <!-- Lastly, your deep link scheme -->
        <!-- eg: example://brand1.judo.app/my-experience -->
        <data android:scheme="example" />
    </intent-filter>
</activity>

Now the Rover SDK can open Judo experience links.

Add the former Judo domain to Rover's Associated Domains list

When Rover is initialized, you gave it a list of associated domains. You should now add your Judo domain to this list.

Rover.initialize(
    CoreAssembler(
        // ...
        associatedDomains = listOf("myapp.rover.io", "myapp.judo.app")
    ),
    // ...
)

Be sure that your Judo domain is the second item in the list.

Now the new Rover 4 SDK can open both Judo and Rover experiences.


Event Handling Changes

If you are subscribing to Experience screen views using the Notification Center event, you should replace it with usage of the new API for receiving screen views. This will receive screen views for both experiences and classic experiences:

The following code for the old Rover experiences renderer for registering for screen viewed events will need to be replaced:

Rover.shared?.eventEmitter?.addEventListener(object : RoverEventListener {
    override fun onExperienceScreenPresented(event: RoverEvent.ExperiencePresented) {
        // custom handler code here
    }
})

Note that if you were using other events than "Experience Screen Presented", you will need to continue using the previously available event listener API. However, to indicate that it is only available for Classic Experiences, it has been renamed.

RoverEventListener has been renamed ClassicExperienceEventListener, and the methods have had "Classic" added, eg. onScreenPresented() has been renamed to onClassicScreenPresented().

Replace usages of Rover.shared.eventEmitter.addEventListener with Rover.shared.classicEventEmitter.addClassicExperienceEventListener.

Likewise, if you had registered a Judo screen viewed callback, that too will need to be replaced with the new API for receiving screen views:

Judo.addScreenViewedCallback { event ->
    // custom handler code here
}

These can now be replaced by registering a single screen viewed callback:

Rover.shared.registerScreenViewedCallback { screenViewed ->
    // custom handler code here
}

See Third-party Analytics for more information.


Notification Center renamed to Inbox

The Rover Notification Center UI has been renamed to Rover Inbox. If you used or customized the integrated Notification Center, there are a few renamed types to take into account:

  • NotificationCenterActivity class -> InboxActivity
  • NotificationCenterListView class -> InboxListView
  • notificationCenterIntent parameter to NotificationAssembler() -> inboxIntent

Additionally, the NotificationsRepository has been renamed to NotificationStore. Additionally, the NotificationsRepository has been renamed to NotificationStore. Additionally, the updates publisher property has been renamed notifications, to better reflect that that is how to you subscribe to the list of properties. A wrapping object has been removed as well, and it now directly yields a List<Notification>.

See Inbox for more information.


Remove Judo User Identification calls

You may have been using Judo.identify() to identify your users to the Judo SDK and make custom user info available to experiences. If so, you can remove these calls now, since Rover's user info will be exposed to those experiences going forward.

Remove:

Judo.identify(
    ...
)

Your existing Rover user info update calls (see User Info) should be sufficient, but you may wish to evaluate if there is any custom information you were passing to Judo that you desire to make available to Rover.

See User Info for more information.


Replace Judo Custom Action Handler

You may have been using Judo.registerCustomActionCallback() to handle custom actions in your Judo experiences. This API has been moved into the new Rover SDK, and the usage is virtually the same:

Judo.registerCustomActionCallback { actionEvent ->
    // custom handler code here
}

with:

Rover.shared.registerCustomActionCallback { actionEvent ->
    // custom handler code here
}

See Custom Actions for more information.


Replace Judo Authorizers

You may have been using Judo.authorize() to handle custom authorizers in your Judo experiences. This API has been moved into the new Rover SDK:

val config = Judo.Configuration.Builder(
    ...
)

// this is the actual authorizer closure:
config.authorize("*.example.com") { request ->
    request.headers["X-My-Authorization"] = "my api key"
}

Judo.initialize(
    application = this,
    configuration = config.build()
)

This has been replaced with the Rover.shared.authorize() API call to register an authorizer closure:

Rover.shared.authorize("*.apis.myapp.com") { urlRequest ->
    urlRequest.headers["X-My-Authorization"] = "my api key"
}

See Authorizers for more information.


Replace Judo Experience Embedding

Previously for specific use cases (such as using a Judo experience on an app's Home screen), we supported embedding ExperienceFragment within your own Activity.

This is still supported, but ExperienceFragment has now been moved into the new Rover 4 SDK, and the API has changed somewhat.

Please see the Embedding Experiences for details on how to embed experiences in your app.


Summing Up

Your app should now build, and if you grep your source tree for the string "judo", you should no longer find any references.

Please follow up with your account representative for next steps on User Acceptance Testing.

Previous
Android - Rover