Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Widgets

What it does

RustFerry exposes a restricted, serializable WidgetSnapshot with title, value, caption, progress, deep-link, and one optional text/link/button content node. Both generated adapters render this common model as an Android App Widget and an Apple WidgetKit extension; this is not a general layout engine.

Support matrix

Host snapshot/modelAndroid provider APKiOS WidgetKit .appex
Implemented/testedEnabled provider/backend artifact-inspected; runtime unobservedApp-group publisher, framework, and .appex artifact-inspected; runtime unobserved

Minimal complete example

use rustferry::deep_links::DeepLink;
use rustferry::testing::TestRuntime;
use rustferry::widgets::{self, WidgetId, WidgetSnapshot};

fn main() -> rustferry::Result<()> {
    let runtime = TestRuntime::new();
    let _guard = runtime.enter();
    let id = WidgetId::parse("counter")?;
    let snapshot = WidgetSnapshot::new()
        .title("Counter")
        .value("42")
        .caption("Tap to open")
        .progress(0.42)
        .deep_link(DeepLink::parse("counter://open/current")?);
    widgets::update(&id, snapshot.clone())?;
    assert_eq!(runtime.widget_snapshot(&id), Some(snapshot));
    Ok(())
}

Configuration

[extensions.widget]
enabled = true
app_group = "group.com.example.counter"

Run cargo ferry add widget to add the config/feature and a Rust snapshot fragment.

Permissions and entitlements

iOS shared state requires an application group and compatible signing/provisioning on devices. Android needs generated provider/receiver metadata, not an overlay permission.

Expected result

The host test records the latest snapshot. Apple publisher/extension artifacts and an Android APK with the enabled provider pass inspection. Neither platform has runtime-observation evidence.

Common errors

  • Missing app_group: strict config rejects it.
  • Progress outside 0.0..=1.0: rejected before backend dispatch.
  • Expecting arbitrary Rust UI: platform widgets use the constrained schema.

Platform differences

Android uses RemoteViews/provider scheduling; Apple uses WidgetKit timelines and families. Update timing is controlled by each OS.

Test example

Publish several snapshots and assert widget_snapshot(&id) contains the last valid one; assert invalid progress fails.

Example project

See shared state, snapshots, and an action route in the Widget Counter example.