the Stay Exercise begins and renders on the Lock Display screen/Dynamic Island, and Flutter logs report that updateActivity(…) calls succeed with the complete payload. Nonetheless, the widget UI by no means displays these updates—it solely exhibits the default values outlined in Swift.
Setting
-
Flutter: secure (iOS, bodily gadget)
-
Plugin:
live_activities: ^2.4.2 -
System iOS: 26.0.1
-
Runner (app) min iOS: 13
-
Extension min iOS: 18.2 (Stay Actions supported; additionally annotated with
@accessible(iOSApplicationExtension 16.1, *)) -
Xcode: 26.0.1
-
Entitlements:
- App and Extension: Stay Actions + App Teams
- App Group:
group.com.instance.app(redacted)
-
Embedding: Extension embedded by way of Construct Phases → Embed Basis Extensions → Vacation spot: Plugins and Basis Extensions
-
Runner Goal Dependencies consists of the extension; Skip Set up = Sure on extension
Symptom
createActivity(...)returns an ID and Stay Exercise renders.- Repeated
updateActivity(...)calls log “up to date efficiently” with full state. - UI stays on Swift defaults (by no means displays Flutter-sent values).
Minimal Repro (Dart)
await reside.init(appGroupId: 'group.com.instance.app', urlScheme: 'vns');
closing id = await reside.createActivity(
'LiveActivitiesAppAttributes', // additionally tried '<EXTENSION_TARGET_NAME>.LiveActivitiesAppAttributes'
{
'title': 'Stress Session',
'state': 'energetic',
'endTime': '16:33',
'statusMessage': 'Session began',
'depth': 1,
'isPaused': false,
},
);
await reside.updateActivity(id, {
'title': 'Stress Session',
'state': 'energetic',
'endTime': '16:33',
'statusMessage': 'Depth degree 2',
'depth': 2,
'isPaused': false,
});
Widget (Swift, simplified)
I attempted each paths: studying straight from
context.state.*and studying from App GroupUserDefaultsutilizing a prefixed key. Neither path displays Flutter updates; the UI stays on defaults.
import ActivityKit
import WidgetKit
import SwiftUI
import AppIntents
non-public func appGroupId() -> String { "group.com.instance.app" }
let sharedDefaults = UserDefaults(suiteName: appGroupId())!
struct LiveActivitiesAppAttributes: ActivityAttributes, Identifiable {
public typealias LiveDeliveryData = ContentState
public struct ContentState: Codable, Hashable {
var title: String?
var emoji: String?
var state: String?
var endTime: String?
var statusMessage: String?
var depth: Int?
var isPaused: Bool?
}
var id = UUID()
}
@accessible(iOSApplicationExtension 16.1, *)
struct SessionLiveActivity: Widget {
var physique: some WidgetConfiguration {
ActivityConfiguration(for: LiveActivitiesAppAttributes.self) { context in
// Path A: direct ContentState (tried this)
// let sessionName = context.state.title ?? "Default"
// Path B: App Group defaults (tried this as a sanity check)
let sessionName = sharedDefaults.string(forKey: context.attributes.prefixedKey("title")) ??
let endTime = sharedDefaults.string(forKey: context.attributes.prefixedKey("endTime")) ?? "00:00"
let statusMsg = sharedDefaults.string(forKey: context.attributes.prefixedKey("statusMessage")) ?? "energetic"
let depth = sharedDefaults.integer(forKey: context.attributes.prefixedKey("depth"))
let isPaused = sharedDefaults.bool(forKey: context.attributes.prefixedKey("isPaused"))
VStack {
Textual content(sessionName)
Textual content(endTime)
Textual content(statusMsg)
Textual content("(depth)")
Textual content(isPaused ? "paused" : "energetic")
}
}
}
}
extension LiveActivitiesAppAttributes {
func prefixedKey(_ key: String) -> String { "(id)_(key)" }
}
Logs (trimmed)
[log] Stay Actions service initialized efficiently
[log] Creating new Stay Exercise: {title: Stress Session, emoji: ⚡, state: energetic, endTime: 16:33, statusMessage: Session began, depth: 1, isPaused: false}
[log] Stay Exercise created efficiently with ID: 148D781F-E307-446B-AEC4-DA2D80A9B012
[log] Sending Stay Exercise replace with full state: {title: Stress Session, emoji: ⚡, state: energetic, endTime: 16:33, statusMessage: Depth degree 1, depth: 1, isPaused: false}
[log] Stay Exercise up to date efficiently
[log] Sending Stay Exercise replace with full state: {... depth: 2, ...}
[log] Stay Exercise up to date efficiently
What I’ve already tried
- ✅ Runner → Goal Dependencies consists of extension
- ✅ Extension Skip Set up = Sure
- ✅ Entitlements on each targets: Stay Actions, App Teams (
group.com.instance.app) - ✅ Construct as soon as in Xcode; bodily gadget
- ✅ Tried passing module-qualified sort:
'<EXTENSION_TARGET_NAME>.LiveActivitiesAppAttributes' - ✅ Renamed
state→sessionStatein each keys and Swift struct (to dodge any reserved-name quirks) - ✅ iOS 17-only
Button(intent:)controls are availability-gated (not related to this decode difficulty) - ✅ Additionally examined studying state by way of UserDefaults (App Group) with prefixed key—UI nonetheless exhibits defaults
Redaction
- Bundle IDs, group IDs, and product names are changed with placeholders like
group.com.instance.appand<EXTENSION_TARGET_NAME>.
Any concept how can I resolve this?


