live_island_kit 0.4.0
live_island_kit: ^0.4.0 copied to clipboard
iOS Live Activities and Android Live Updates with a single Dart API, no Swift or Kotlin. Dynamic Island, lock screen, presets, charts and a live preview.
0.4.0 #
New:
- Activity life cycle:
LiveIsland.stateChangesandLiveActivity.statesreportactive,stale,endedanddismissed(newLiveActivityStateandLiveActivityStateChange). iOS reports the four through ActivityKit, also when the user swipes the card away; Android reportsactive,endedanddismissed(swiped away or timed out). - Tap to open a screen:
LiveActivity.update(deepLink:)changes where a tap on the activity goes (the reserved state key$url, which a push can also send), anddart run live_island_kit:setup --url-scheme myappregisters the URL scheme on iOS (CFBundleURLTypes) and Android (an intent filter). The example app opens the tapped case, also from a cold start. New README section.
Fixed:
- Several listeners of the plugin's events now share one native subscription. Each
EventChannellisten replaced the previous one on the native side, so using two streams at once (for exampleLiveIsland.stateChangesandactivity.states, orpushTokensandstartedByPush, or twoonActioncalls) silently cut the first one. A test covers it. - iOS:
dismissedis always preceded byended. With an immediate dismissal ActivityKit goes straight fromactivetodismissed; the plugin now emitsendedfirst, as Android does. dart run live_island_kit:setupnow raises the app'sPodfileplatform and the Xcode project's iOS deployment target to 15.0 (the plugin's minimum). On a new app made with Flutter 3.29 the template leaves# platform :ios, '12.0'commented, and the firstflutter runfailed with "requires a higher minimum iOS deployment version". A test covers the Podfile rewrite.dart run live_island_kit:setupnow also raises the Android app'sminSdkto 26 inandroid/app/build.gradle(.kts)(it never lowers a bigger value or Flutter's own). A new app usesflutter.minSdkVersion(24), and the first Android build failed with "minSdkVersion 24 cannot be smaller than version 26". Apps without anios/folder are configured for Android only.- Three messages that were still in Spanish are now in English: the iOS error for versions earlier than 16.1, the Android error when a permission request is replaced, and the titles of the button App Intent ("live_island action", "Button") that Shortcuts shows.
Docs and tooling:
- New "Troubleshooting" section in the README (English and Spanish) with the checks for a card that does not show, the build errors above and the
LiveIslandExceptioncodes. - Integration tests against the real platform (
example/integration_test, run withtool/integracion.sh <device>): ActivityKit on an iPhone simulator and notifications on an Android emulator. They start, update and end activities, check the life cycle events in order, the own id (customId), the tap link andendAll.
Upgrading: nothing breaks. update gains an optional deepLink, and setup gains --url-scheme; re-run dart run live_island_kit:setup to pick up the Podfile and minSdk fixes.
0.3.0 #
Behavior changes to be aware of when upgrading:
-
eq/neqcompare numerically when both sides are numbers (a numeric string counts, a boolean does not),gt/gte/lt/lteonly accept numbers,truthy: falseinverts the condition and the text"false"is truthy. The same rules now apply on Dart, Swift and Kotlin. -
Numbers print without decimals when they are whole (
5, not5.0) in every{field}template. -
The sample texts of every preset and the example app are in English. State keys (
titulo,nombre,llegaA…) are unchanged. -
iOS: the privacy manifest (App Group
UserDefaults, reason1C8F.1) was checked against the compiled binaries of the plugin and the extension: they use no other required-reason API. A new test fails if one is added without declaring it. -
Cross-platform conformance:
doc/contract/conformance.jsonholds 52 cases ({field}templates, conditions and the countdown) that Dart, Swift and Kotlin run with their real logic (tool/conformidad.sh). The rules are now written in the contract. -
Differences the suite found are fixed: the preview wrote
5.0where the device writes5;eqand the numeric operators treat a number and a numeric string the same on all three platforms;truthy: falseinverts the condition; the text"false"is truthy; a boolean is not a number; and on iOS{ x }or{}no longer disappear from a template. -
Resolved texts:
doc/contract/resolved_texts.jsonholds, for each of the 32 presets, its layout, its sample state and the texts it shows. Dart generates it; Swift and Kotlin walk the same JSON with their own logic (if,{field},bind) and must list the same texts. -
A test checks that every node type the presets emit is drawn by the three interpreters (Flutter preview, SwiftUI and the Android card), so a new node cannot ship without support on a platform.
-
The messages the package shows developers are now in English:
LiveIsland.check()warnings, errors thrown by the Dart API and the iOS and Android plugins, the labels of the preview, and thedart run live_island_kit:setupcommand and the files it generates. Runtime text meant for end users (for example the relative time "en 5 min") is unchanged. -
The API documentation (every
///comment, about 1,100 lines) is now in English, so pub.dev's API reference reads in English. The sample texts the presets show are in English too ("Your driver is on the way", "Pickup in 2 min"…); the README gallery images are regenerated with them. -
The README is now in English (Spanish version:
README.es.md), and so are the pub.dev description and screenshot captions.
0.2.0 #
- iOS: the right zone of the expanded island has a 4 pt margin, so the island's curve does not clip the "78'" of the sports score.
- iOS: in the expanded island, a one-line text shrinks down to 65 % before being cut with "…" (Public transport, Waiting room and File upload no longer lose "3 stops", "We'll call you soon" or "3 min left").
- iOS: fixes an app crash when starting an activity (a data race while watching ActivityKit push tokens).
- New "Run" designs:
RideArrivalPreset(arrival, with a sedan and its plate),RideTripPreset(trip with phase, destination and fare),RidePinPreset(trip start with the PIN code),RideStopPreset(driver with a stop before pickup),RideDestinationPreset(on the way to the destination),TrainPreset(train line with stations in Lima) andDeliveryOrderPreset(delivery order in four stages with icons). They ship their own images: a car with a plate, a car and a train seen from above, and the order icons. - Bar:
LiveProgressStyle.endMarkerattaches a ring or a square to the end of the bar, with the car on top;LiveSegments.stageIconsputs an icon on each stage (gray until reached, colored after); andLiveProgressStyle.markerLabelswrites text inside a marker (a numbered stop). - Lock screen: if the root is a box with an opaque color, that color is the background of the whole card (a single container) on iOS and in the preview.
tool/sincronizar_swift.shandswift_sincronizado_testkeep the example's copy of the iOS renderer identical to the source.- The preview cuts long text next to a spacer with "…", like SwiftUI.
- Android: the card paints the theme background (
accentandlight), like the iOS one. - Android: every example design uses the card (
LiveAndroidStyle.card) by default, so Android draws the same design as iOS from the same JSON. WithandroidStyle: LiveAndroidStyle.liveUpdateyou go back to the native template (and to the Live Update promotion). - The README gallery changes: "Trip start with PIN" and "Delivery order" replace "Trip with details" and "Fare and tip".
RideDriverPreset(trip as the driver sees it) is removed: the new designs replace it.
0.1.1 #
- No analyzer warnings on Flutter 3.47 (
dart:uiimports flagged as unnecessary). - The repository is renamed
live_island_kit:repository,issue_trackerand the README image links are updated.
0.1.0 #
First published version.
- A single Dart API (
LiveIsland.start/update/end) for iOS Live Activities and Android 16+ Live Updates. - JSON contract v1 (design once, state ≤ 4,096 bytes) shared by Dart, Swift and Kotlin.
- iOS: a generic SwiftUI Widget Extension (compact, expanded and minimal island, lock screen, StandBy), buttons with
LiveActivityIntent(iOS 17+), push tokens and push-to-start (iOS 17.2). - Android:
Notification.ProgressStyle, chip, Live Update promotion, buttons, action queue and FCM push entry point. dart run live_island_kit:setupconfigures the Xcode project (--pushfor APNs).- Components: text, countdowns, icons and images, avatar, bar, ring, stages, tracker, buttons.
- Editable progress bar: color, thickness, dots, labels, moving icon and end marker (
LiveProgressStyle). - Stage dots to taste: count, with or without text, and shape (
LivePointShape: circle, square, rounded). - Live bar:
LiveRouteturns a position into progress andLiveActivity.followkeeps the activity up to date from aStream, spacing out the updates. LiveIslandMorph: the island drops a blob that opens into a card (preview and in-app notice), dismissible by gesture.- iOS: a privacy manifest that declares the App Group
UserDefaultsuse (reason1C8F.1), packaged with the plugin and copied into the extension bydart run live_island_kit:setup; the podspec takes the package version. - Activities with your own id:
start(customId:)creates or updates,LiveIsland.activity(customId)finds them after reopening the app,LiveIsland.endAll()ends them andactiveActivities()returns theircustomId. Android pushes acceptcustomIdinstartand asidinupdate/end. - Alerts:
update(alert: LiveAlert(...))expands the island and plays a sound on iOS; on Android it uses a channel with sound and shows as a heads-up. The Android push accepts"alert": true. - Stale state:
LiveBind.stale(reserved field$stale) changes the design oncestaleAfterpasses without a push (iOS 16.2+). - Example: starting a case ends the previous one and uses
relevance: 100, so the island always shows the one just started (iOS shows only one activity in the island). - Scheduled end:
LiveActivity.scheduleEnd(at)andLiveDismiss.at(DateTime). On Android the notification stays alive and the system removes it at that time; on iOS it ends now and the card stays until then. - iOS: Swift Package Manager support (
ios/live_island_kit/Package.swift) as well as CocoaPods; both use the same sources. Tested with Flutter 3.29, 3.41 and 3.47. - Reference designs with their own names and images, in Spanish:
RidePickupPreset(light and dark,RideBar.dottedorRideBar.linebar),RideDriverPreset(driver view),StorePickupPreset,RunPreset,MatchPreset, and a train line built withTransitPreset. LiveProgressStyle.dashed(the remainder as a dashed stroke),LiveProgressStyle.markers(markers on the bar),LivePointShape.ring,LiveImage.withSizeandLiveImage.withHeight(fixed height for wide images).LiveIsland.check()validates the design and the state with the same warnings as the prototype HTML.LiveIslandPreview: a Flutter preview of the island, the lock screen and the Android notification.- 15 ready-made presets (
TripPreset,DeliveryPreset,CourierPreset…) and an example app. - Android: card mode (
LiveAndroidStyle.card): your whole design withRemoteViews(two crests, a big score, a chart), with no chip or Live Update;MatchPresetandStockPresetuse it by default. - Android:
LiveAndroid(largeIcon, subText), a split bar as colored segments and markers asProgressStylepoints; the example designs set their own image, subtext and texts. - Effects:
LiveProgressStyle.glow(glowing cable),LiveBox(border, borderWidth, glow)(glowing border),LiveSplitBar(proportional colored segments) andLiveText(italic: true); withChargePresetandFareSplitPreset. - Charts:
LiveSparkline(line with area and end dot),LiveGauge(arc with a moving dot) andLiveFlightPath(curved route with a moving icon); withStockPreset,FlightPathPresetandOrbitPreset. On Android the arc and the route are a bar and the line is omitted.
Known limitations: on Android the bar's thickness, spacing and labels are decided by the system; buttons are not drawn in the expanded iOS island; no SwiftUI snapshot tests.
