Data Integrations and Customization

Embedding Experiences

A Rover SDK experience can be added to other other UI in your app as a possible customization point. This customization can be furthered by handling custom actions.

Intrinsic Size

Experiences do not have an intrinsic size - so for both platforms, the experience will adopt whatever size you offer it, but cannot be auto-sized to fit its content.


iOS

Using UIKit

An experience may be embedded within another view controller, by adding the ExperienceViewController as a child view controller, using the standard pattern for embedding view controllers.

Once the view controller has been added as a child, its frame must be given a fixed size, then its view can be added to the parent. Once the view has been added to the parent, call ViewController.didMove(toParent:). When done with the experience, call ViewController.removeParent().

The ExperienceViewController does not support autosizing from content, so it will need to be given a fixed size.

Additional details are available at: Implementing a Container View Controller

View Controller Containment:

import UIKit
import RoverExperiences

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        if let url = URL(string: "<Your Experience URL>") {
            let experienceVC = ExperienceViewController.openExperience(with: url)
            addChild(experienceVC)
            experienceVC.view.frame = view.bounds //Fixed size is required here.
            view.addSubview(experienceVC.view)
            experienceVC.didMove(toParent: self)
        }
    }
}

Using SwiftUI

In SwiftUI, you can use an ExperienceViewController within a View by creating a type that conforms to the UIViewControllerRepresentable protocol. A struct of this type can then be used just like any other SwiftUI view. The type should have the URL off the experience as well.

Additional details are available at: UIViewControllerRepresentable

UIViewController Representable:

import SwiftUI
import UIKit
import RoverExperiences

struct ExperienceView: UIViewControllerRepresentable {
    var url: URL
    
    init(url: URL) {
        self.url = url
    }
    
    func makeUIViewController(context: Context) -> ExperienceViewController {
        return ExperienceViewController.openExperience(with: self.url)
    }
    
    func updateUIViewController(_ uiViewController: ExperienceViewController, context: Context) {
        //NO-OP
    }
}

Usage within SwiftUI:

import SwiftUI
import RoverExperiences

struct RoverExampleView: View {
    
    var body: some View {
        VStack {
            if let url = URL(string: "<Your Experience URL>") {
              ExperienceView(url: url)
            }
        }
    }
}

Android

Android offers two options for embedding your experiences. You can use a Fragment or a Composable.

Using a Fragment

The SDK ncludes ExperienceFragment, a fragment which can be embedded into an activity.

Within a FragmentActivity, you can use the Fragment Manager to add the fragment to the activity in the typical way.

In this example implementation of onCreate(), the built-in Android content placeholder is replaced with the fragment, which fills the entire activity with the fragment:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    this.supportFragmentManager
        .beginTransaction()
        .replace(
            android.R.id.content,
            ExperienceFragment("<EXAMPLE-EXP-URL>")
        )
        .commit()
}

Using a Composable

The SDK includes ExperienceComposable, a Jetpack Compose composable function which can be embedded into a Compose UI.

Sizing Behavior

ExperienceComposable will expand to fill the maximum space given to it by its constraints. It does not size down to fit content. If you wish to limit the size it will take up, use a modifier such as size(), width(), or height().

ExperienceComposable(
    Uri.parse("<EXAMPLE-EXP-URL>"),

    // Example use of a modifier to constrain size:
    // ExperienceComposable's sizing behavior is to expand
    // to the maximum size given. In many instances, you will
    // want to limit it. For example, by using the height
    // modifier below, the Experience will expand to fill
    // width of the display but only take 300dp in height.
    modifier = Modifier.height(300.dp),
)
Previous
Authorizers