Живое действие запускается и отображается на экране блокировки/динамическом острове, а журналы Flutter сообщают, что вызовы updateActivity(...) завершаются успешно с полной полезной нагрузкой. Однако пользовательский интерфейс виджета никогда не отражает эти обновления — он показывает только значения по умолчанию, определенные в Swift.
Среда
Flutter: стабильная версия (iOS, физическое устройство)
Плагин: live_activities: ^2.4.2
Устройство iOS: 26.0.1
Runner (приложение) мин. iOS: 13
Расширение мин iOS: 18.2 (поддерживаются Live Activity; также помечено @available(iOSApplicationExtension 16.1, *))
Xcode: 26.0.1
Права:
Приложение и Расширение: Живые действия + Группы приложений
Группа приложений: group.com.example.app (отредактировано)
[*]Внедрение: расширение, встроенное через Фазы сборки → Внедрение базовых расширений → Назначение: плагины и фундамент Расширения
[*]Целевые зависимости бегуна включают расширение; Пропустить установку = Да для расширения
Я попробовал оба пути: чтение непосредственно из context.state.* и чтение из группы приложений UserDefaults с использованием префиксного ключа. Ни один из путей не отражает обновления Flutter; пользовательский интерфейс остается по умолчанию.
Попробовал передать тип с указанием модуля: '.LiveActivitiesAppAttributes'
Переименовал состояние → sessionState как в ключах, так и в структуре Swift (чтобы избежать любых особенностей зарезервированных имен)
Элементы управления Button(intent:) только для iOS 17 закрыты по доступности (не имеют отношения к этой проблеме декодирования)
Также проверено состояние чтения через UserDefaults (группа приложений) с префиксным ключом — пользовательский интерфейс по-прежнему отображает значения по умолчанию
Редактирование
Идентификаторы пакетов, идентификаторы групп и названия продуктов заменяются заполнителями, такими как group.com.example.app и .
Живое действие запускается и отображается на экране блокировки/динамическом острове, а журналы Flutter сообщают, что вызовы updateActivity(...) завершаются успешно с полной полезной нагрузкой. Однако пользовательский интерфейс виджета никогда не отражает эти обновления — он показывает только значения по умолчанию, определенные в Swift. [img]https://i.sstatic.net/vTJYn4So.png[/img]
Среда [list] [*][b]Flutter[/b]: стабильная версия (iOS, физическое устройство)
[*][b]Плагин[/b]: live_activities: ^2.4.2
[*][b]Устройство iOS[/b]: 26.0.1
[*][b]Runner (приложение) мин. iOS[/b]: 13
[*][b]Расширение мин iOS[/b]: 18.2 (поддерживаются Live Activity; также помечено @available(iOSApplicationExtension 16.1, *))
[*][b]Внедрение[/b]: расширение, встроенное через [b]Фазы сборки → Внедрение базовых расширений → Назначение: плагины и фундамент Расширения[/b]
[*][b]Целевые зависимости бегуна[/b] включают расширение; [b]Пропустить установку = Да[/b] для расширения
Симптом [list] [*][code]createActivity(...)[/code] возвращает идентификатор и визуализирует интерактивную активность. [*]Повторяющийся updateActivity(...) вызывает журнал [b]«обновлено успешно»[/b] с полным состоянием. [*][b]UI остается с настройками Swift по умолчанию[/b] (никогда не отражает значения, отправленные Flutter). [/list]
Я попробовал [b]оба пути[/b]: чтение непосредственно из context.state.* и чтение из [b]группы приложений[/b] UserDefaults с использованием префиксного ключа. Ни один из путей не отражает обновления Flutter; пользовательский интерфейс остается по умолчанию.
struct LiveActivitiesAppAttributes: ActivityAttributes, Identifiable { public typealias LiveDeliveryData = ContentState public struct ContentState: Codable, Hashable { var name: String? var emoji: String? var state: String? var endTime: String? var statusMessage: String? var intensity: Int? var isPaused: Bool? } var id = UUID() }
@available(iOSApplicationExtension 16.1, *) struct SessionLiveActivity: Widget { var body: some WidgetConfiguration { ActivityConfiguration(for: LiveActivitiesAppAttributes.self) { context in // Path A: direct ContentState (tried this) // let sessionName = context.state.name ?? "Default"
// Path B: App Group defaults (tried this as a sanity test) let sessionName = sharedDefaults.string(forKey: context.attributes.prefixedKey("name")) ??
let endTime = sharedDefaults.string(forKey: context.attributes.prefixedKey("endTime")) ?? "00:00" let statusMsg = sharedDefaults.string(forKey: context.attributes.prefixedKey("statusMessage")) ?? "active" let intensity = sharedDefaults.integer(forKey: context.attributes.prefixedKey("intensity")) let isPaused = sharedDefaults.bool(forKey: context.attributes.prefixedKey("isPaused"))
Журналы (обрезанные) [code][log] Live Activities service initialized successfully [log] Creating new Live Activity: {name: Stress Session, emoji: ⚡, state: active, endTime: 16:33, statusMessage: Session started, intensity: 1, isPaused: false} [log] Live Activity created successfully with ID: 148D781F-E307-446B-AEC4-DA2D80A9B012 [log] Sending Live Activity update with full state: {name: Stress Session, emoji: ⚡, state: active, endTime: 16:33, statusMessage: Intensity level 1, intensity: 1, isPaused: false} [log] Live Activity updated successfully [log] Sending Live Activity update with full state: {... intensity: 2, ...} [log] Live Activity updated successfully [/code]
То, что я уже пробовал [list] [*] ✅ Runner → [b]Целевые зависимости[/b] включает расширение [*] ✅ Расширение [b]Пропустить установку = Да[/b] [*] ✅ Права на [b]оба[/b] цели: живые действия, группы приложений ([code]group.com.example.app[/code]) [*] ✅ Создайте один раз в Xcode; физическое устройство [*] ✅ Попробовал передать [b]тип с указанием модуля[/b]: '.LiveActivitiesAppAttributes' [*] ✅ Переименовал состояние → sessionState как в ключах, так и в структуре Swift (чтобы избежать любых особенностей зарезервированных имен) [*] ✅ Элементы управления Button(intent:) только для iOS 17 [b]закрыты по доступности[/b] (не имеют отношения к этой проблеме декодирования) [*] ✅ Также проверено состояние чтения через [b]UserDefaults[/b] (группа приложений) с префиксным ключом — пользовательский интерфейс по-прежнему отображает значения по умолчанию [/list]
Редактирование [list] [*]Идентификаторы пакетов, идентификаторы групп и названия продуктов заменяются заполнителями, такими как group.com.example.app и . [/list]