Data & Customization
Embedding Experiences
A Rover SDK experience can be embedded into other UI in your app, as opposed to the typical use case of presenting a full screen experience.
This enables use cases such as populating a tab in a tab bar with content designed in Rover, adding a section of Rover content to a large screen, and many more.
Additionally you can use handling custom actions to enable custom buttons within an embedded experience to perform arbitrary behaviour in the app.
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),
)