flutter_home_widget 0.1.0
flutter_home_widget: ^0.1.0 copied to clipboard
A Flutter plugin for iOS home-screen widgets with App Group data sync, widget reload, deep-link callbacks, and device-lock state.
flutter_home_widget #
A Flutter plugin for iOS home-screen widgets with App Group data sync, widget reload, deep-link callbacks, and a built-in device-lock state API.
v0.1.0 supports iOS only. Android support is planned for v0.2.0.
Why another widget plugin? #
Most plugins in this space stop at "write data, reload widget". flutter_home_widget adds one thing they miss: device-lock state. iOS makes App Group UserDefaults unavailable while the device is locked and protected data hasn't been unlocked yet — widgets can render stale or empty UI in that window. This plugin writes a flutter_home_widget.device_locked flag to your App Group automatically (via applicationProtectedData… hooks) and ships a Swift helper widget extensions can import to render a locked-state fallback.
Features #
- App Group
UserDefaultssync (String,int,double,bool). - Widget reload via
WidgetCenter, optionally targeting a specific widget kind. - Cold-start and runtime widget-tap deep links as
Uri(initial future + stream). - Device-lock state flag, written automatically on protected-data lifecycle events.
FlutterHomeWidgetReaderSwift helper to read App Group values from a widget extension.
Install #
dependencies:
flutter_home_widget: ^0.1.0
iOS setup #
- Add an App Group to both the host app target and the widget extension target (e.g.
group.com.example.myapp). - Call
FlutterHomeWidget.setAppGroupId(...)once at app start. - Tap-handling: widgets emit deep links via
widgetURL(URL(string: "myscheme://...")). The plugin captures the URL inapplication(_:open:url:)and exposes it viainitialLaunchUri/widgetTaps.
import 'package:flutter_home_widget/flutter_home_widget.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await FlutterHomeWidget.setAppGroupId('group.com.example.myapp');
// Cold-start tap
final initial = await FlutterHomeWidget.initialLaunchUri();
if (initial != null) handleDeepLink(initial);
// Live taps
FlutterHomeWidget.widgetTaps.listen(handleDeepLink);
runApp(const MyApp());
}
Future<void> syncWidget(String policiesJson) async {
await FlutterHomeWidget.saveData('policies_list', policiesJson);
await FlutterHomeWidget.reloadWidget(iOSName: 'PolicyExpiryWidget');
}
Reading data from your widget extension #
In your widget target's Swift code:
import flutter_home_widget
struct PolicyExpiryProvider: TimelineProvider {
let reader = FlutterHomeWidgetReader(appGroupId: "group.com.example.myapp")
func placeholder(in context: Context) -> Entry {
Entry(date: .now, payload: reader.string("policies_list") ?? "")
}
// ...
}
To render a locked-state fallback:
if reader.isDeviceLocked {
LockedView()
} else {
PolicyView(data: data)
}
API #
class FlutterHomeWidget {
static Future<void> setAppGroupId(String groupId);
static Future<bool> saveData<T>(String key, T? value); // String / int / double / bool
static Future<T?> getData<T>(String key);
static Future<bool> reloadWidget({String? iOSName});
static Future<Uri?> initialLaunchUri();
static Stream<Uri> get widgetTaps;
}
Roadmap #
- v0.2.0 — Android
AppWidgetProviderbridge. - v0.3.0 — App Intents helper for interactive widgets (iOS 17+).
License #
BSD-3-Clause. See LICENSE.