Onboarding and guidance

Most of your users have never scanned a property before. The scan view teaches them how before they start, and coaches them while they scan, so you don't have to design that yourself. This page covers what it shows, when you'd change it, and how to make it look like your app.

Onboarding

Before a scan, RoomioScanView shows a few pages of tips on how to scan well. When the user finishes or skips them, the SDK asks for the camera and recording begins. Users who skip the onboarding a few times stop seeing it.

While the onboarding shows, session.isShowingOnboarding is true. Hide any controls you put over the scan view until it's false, so they don't cover the tips.

Turning it off

Keep the onboarding unless your app already teaches scanning its own way, for example with your own video or walkthrough before the scan screen. Users who scan without any instructions tend to move too fast and miss parts of the property.

let session = try Roomio.startScan(
    config: RoomioScanConfig(showsOnboarding: false)
)
val session = Roomio.startScan(
    activity,
    RoomioScanConfig(showsOnboarding = false),
)
const session = await Roomio.startScan({ showsOnboarding: false });

Without the onboarding, the SDK asks for the camera and starts recording as soon as you call start().

Guidance during the scan

While the user scans, the scan view tells them when something is about to cost them a good result. "Slow down" and "Tracking Lost" appear in the middle of the screen, where the user is looking. Warnings about the phone itself, such as full storage, low memory, a low battery or overheating, appear in a bar at the top, since they mean the user should finish soon. Tips on technique share that bar: moving slowly while tracking starts, pointing at more detail, and (on Android) finding more light. Guidance can't be turned off: it's what keeps scans usable.

The bar starts with the camera preview, before recording. It says when Low Power Mode (iOS) or Battery Saver (Android) is on, or when storage is too full to scan, until that's fixed. Storage under 3 GB only gets the warning sheet when Start is tapped, not a bar.

At the start of a scan, the user may see a moment of setup first. On iOS, Apple's coaching overlay asks them to move the phone until tracking is ready. On some Android phones, the view shows "Getting ready…" for a few seconds. Recording carries on underneath in both cases, and the buttons stay available.

Using guidance in your own UI

Everything the scan view shows also reaches your app as guidanceChanged events. You'd use these to log what your users struggle with, or to adjust your own controls. The guidance is empty when there's nothing to tell the user.

Guidance Tells the user
initializing Tracking is starting. Move the device slowly.
slow_down The device is moving too fast.
need_more_detail Point at a more textured surface.
need_more_light Move somewhere brighter. Android only.
return_to_scanned_area Tracking is lost. Go back to somewhere already scanned.
memory_low The device is low on memory. Finish the scan soon.
storage_full The device is nearly out of storage. Before a scan, free some space; during one, finish now.
battery_low The battery is low. Before a scan, charge the device; during one, finish soon.
device_hot The device is overheating. Finish the scan soon.
power_saving Low Power Mode (iOS) or Battery Saver (Android) is on. A scan can't start until it's off; during a scan, turning it off gives a better scan.

New guidance may be added in future releases, so include a default or else branch when you switch on it.

Before a scan

A scan that runs out of battery or storage before it's saved is lost, and one recorded in Low Power Mode or Battery Saver comes out poorer. So when start() is called, the view checks the device first, and shows a sheet instead of starting if something would spoil the scan:

Situation Sheet Buttons
Camera access is declined Asks the user to allow it in Settings Open settings or Cancel
Low Power Mode (iOS) or Battery Saver (Android) is on The scan can't start Go back
Under 200 MB of free storage The scan can't start Free up space
Battery at 25% or less The scan can't start Go back
Under 3 GB of free storage A warning Continue anyway or Free up space
Battery under 50% A warning Continue anyway or Go back

The view checks them in that order and shows the first that applies. Continue anyway moves on to the next check, then starts the scan. Open settings opens your app's page in Settings and leaves the sheet up; when the user comes back with camera access allowed, the sheet closes and the scan carries on. Every other button leaves the scan unstarted, and the session moves to cancelled, as if the user had exited. Take the user back to where the scan began, so they can fix the cause and try again.

When the scan can't start, start() is also refused with a recoverable error: permission_denied, power_saving, insufficient_storage or low_battery.

Hide your own controls while session.isShowingDialog is true.

During a scan

Nothing stops a scan once it's recording, so a user who is nearly done can finish. Instead, the bar warns:

  • when Low Power Mode or Battery Saver is turned on, that turning it off gives a better scan
  • when the battery reaches 25%, to finish soon
  • when free storage drops under 200 MB, to finish now

Running out of storage, memory or battery outranks "Slow down" and "Tracking Lost", since the scan could be lost. The Low Power Mode and hot-phone warnings only cost quality, so they give way to them.

Your brand's colours

The scan view's buttons can use your colours, so the scan feels like part of your app. primaryColor fills the main buttons, such as Complete scan and the onboarding's Next, and colours the text and outline of the others. secondaryColor is the text on the main buttons and the fill of the others, such as Cancel in the exit confirmation and Free up space in the low-storage sheet. Yes, exit and every sheet's Continue anyway stay red, so discarding a scan or pressing on past a warning always looks like what it is.

The SDK uses your colours as given, so pick a pair with enough contrast to read outdoors.

RoomioScanView(session: session, style: RoomioScanStyle(primaryColor: .teal, secondaryColor: .white))
RoomioScanView(context).apply {
    style = RoomioScanStyle(primaryColor = 0xFF00796B.toInt(), secondaryColor = Color.WHITE)
    bind(session)
}
<RoomioScanView session={session} primaryColor="#00796B" secondaryColor="#FFFFFF" />
Roomio SDK 0.0.15