Widgets & Live Activities

RSS for tag

Discuss how to manage and implement Widgets & Live Activities.

WidgetKit Documentation

Posts under Widgets & Live Activities subtopic

Post

Replies

Boosts

Views

Activity

Live Activity (ActivityKit) always defaults to dark colorScheme on iOS 27
Environment: iOS Version: iOS 27.0 Framework: ActivityKit Xcode Version: Xcode 26.1 Issue Description: In iOS 27, Live Activities fail to adapt to the system colorScheme. Regardless of whether the system theme is set to Light or Dark mode, @Environment(.colorScheme) inside the Live Activity view always returns .dark. This behavior worked as expected on iOS 26, where the Live Activity correctly responded to light/dark mode changes and rendered the appropriate theme. Expected Behavior: The Live Activity view should respect the system's current colorScheme (returning .light when the system is in Light Mode) on iOS 27, consistent with the behavior on iOS 26. Actual Behavior: The Live Activity view strictly defaults to .dark mode on iOS 27, even when the device is explicitly set to Light Mode. struct LockScreenView<T: BaseLiveActivityAttributes>: View { let context: ActivityViewContext<T> @Environment(\.colorScheme) var colorScheme var isLight: Bool { colorScheme == .light } var body: some View { Color(isLight ? .white : .black) .overlay(alignment: .topTrailing) { VStack(alignment: .trailing, spacing: 2) { Text("colorScheme: \(String(describing: colorScheme))") } .font(.system(size: 9, weight: .bold, design: .monospaced)) .foregroundColor(.yellow) .padding(4) .background(Color.black.opacity(0.6)) .cornerRadius(4) .padding(.trailing, 8) .padding(.top, 4) } } } Any insights or workarounds would be greatly appreciated. Thanks!
0
0
13
7h
Lack of Native CJK Serif Font Support in WidgetKit (Font.design(.serif))
Hello everyone, I am encountering an inconsistent typography behavior when developing for WidgetKit. Specifically, there is no native serif font fallback for Chinese characters (CJK) in the Widget environment, whereas Latin characters are fully supported. When using the .serif design modifier in SwiftUI: Text("Hello 世界").font(.system(size: 16, design: .serif)) English/Latin characters ("Hello"): System correctly renders using the pre-installed serif font (New York). Chinese characters ("世界"): System ignores the .serif design and falls back to the default sans-serif font (PingFang SC). Can I find any pre-installed native serif font for CJK in iOS that I can reliably invoke within my Widget Extension without bundling .ttf files? If not, do you have plans to map Font.design(.serif) to a pre-installed CJK serif font in future iOS releases so I can maintain design consistency across my localized widgets? Thank you for any insights or recommended workarounds.
0
0
95
4d
WidgetKit complications won't update
We are migrating ClockKit complications to WidgetKit in our watch app (watchOS 9+). The migration went smoothly, UI part works just fine. However, we've hit the wall with widgets not updating when requested by the watch app. I believe we are missing something very simple and fundamental, but couldn't find what exactly so far. Advice and tips would be very welcome! 🙇‍♂️ Our implementation details: Whenever data is changed in the main app, the updated data is submitted to the watch app via WatchConnectivity framework using WCSession.default.transferCurrentComplicationUserInfo(_:). According to documentation, this method should be used to transfer complication-related data, since it will wake the watch app even if it is in the background or not opened at all. Watch app receives updated data and stores it in UserDefaults shared with Watch Widget Extension hosting WidgetKit complications via App Group. Watch app then request widget timeline reload via WidgetCenter.shared.reloadAllTimelines(). According to documentation, it reloads the timelines for all configured widgets belonging to the containing app, so it seems the appropriate way to reload WidgetKit complications. Widget Timeline Provider class in Watch Widget Extension reads updated data from shared UserDefaults and uses it to provide the updated snapshot for widget views to render. We believe our implementation logic is correct, but it doesn't work, for some reason. Widgets sometimes update when the watch app is opened, but not always. The most definitive way to force widgets to update is to switch to a different watch face, which confirms that the Widget Timeline Provider has access to properly updated data. P.S. We are aware of the daily reload budget imposed on widgets, so we use widgets reload trigger sparingly. Anyway, according to documentation, reload budget is not effective when in DEBUG mode, but widgets won't reload even in DEBUG mode. Thank you!
20
10
7.7k
2w
AudioRecordingIntent: AVAudioSession.setActive() fails with OSStatus 561015905 on Lock Screen
Hello, I'm implementing AudioRecordingIntent on iOS 26. My goal is to support Action Button exactly like Apple's Voice Memos: • press Action Button • device remains locked • recording starts immediately • no Face ID • Live Activity is shown • no application UI My intent conforms to AudioRecordingIntent. Inside perform() I do: AVAudioSession.sharedInstance().setCategory(.record) AVAudioSession.sharedInstance().setActive(true) AVAudioRecorder.record() The result is: setCategory succeeds. setActive always fails with NSOSStatusErrorDomain Code = 561015905 "Session activation failed" The failure happens before AVAudioRecorder starts. If I instead forward execution to the main application, iOS requests Face ID before recording begins. Questions: Is AVAudioSession activation inside AudioRecordingIntent actually supported for third-party apps? If not, what is the expected architecture for implementing lock-screen recording using AudioRecordingIntent? Is there an official sample project demonstrating the intended implementation? Thank you.
0
0
266
2w
Recommended approach for updating a push-to-start Live Activity when the app is force-quit?
I create a Live Activity remotely via push-to-start, then use its per-activity token (Activity.pushTokenUpdates) so my server can send update/end pushes. To make sure I'm not missing tokens, I observe Activity.activityUpdates and prime from the Activity.activities snapshot at launch and on sceneWillEnterForeground, then subscribe each activity's pushTokenUpdates and POST the token to my server. This works reliably while the app is running or backgrounded/suspended — the system wakes it and I capture the token. The problem is the user force-quit case (swiped from the App Switcher, never reopened): Push-to-start still creates the Live Activity and it renders correctly on the Lock Screen. But pushTokenUpdates never fires, so my server never receives the per-activity token and can't update or end that activity. A backgrounded (not force-quit) app, as a control, captures the token every time. So it seems specific to user-termination rather than all "not running" states. I understand force-quit apps generally aren't granted background runtime — I'm trying to confirm whether that applies here and what the right pattern is. What's the recommended approach? Specifically: Is there any supported way to get the per-activity token to my server while the app stays force-quit — e.g. from the widget extension (does it have any access to Activity.pushToken, or only ActivityViewContext?) or a Notification Service Extension? 2. If not, is setting stale-date on the start push the intended way to let the card expire gracefully when it can never be ended via push? 3. Is there a better pattern for keeping a push-started Live Activity correct when the app is never relaunched?
1
0
502
2w
Widget and Core Data with CloudKit
I have two apps that use App Groups, CloudKit and Core Data for sharing data between multiple devices and users (one is a sample for the issue, the other one the full fledged one). In the sample app I have the following model: Collection (name) -> many Items (names and count) and corresponding views to increment the count. I also have the widget share the proper App Group and CloudKit container. It has a button that triggers an increment app intent. A create a shared collection "Shares" and add two items in it - "A" & "B". Sharing from the applications and updates of the count takes about 2 seconds. I.e. I open the item view and I tap an increment button, the second phone screen updates almost immediately. Upon each update I also call WidgetCenter.shared.reloadAllTimelines(). What I see is that widgets have are not in sync with the data of the app. I have an explicit button to trigger the reload of the timelines, I can follow along with the debugger and the Core Data data is different, i.e. different count. I also show a date property, so I know that the widget is redrawn. I think that as soon as I added the target for the widget and added it to the app group I started seeing: BUG IN CLOUDKIT: Error submitting background task request: Error Domain=BGSystemTaskSchedulerErrorDomain Code=3 "(null)". The sync between the widget and the app on the same device is inconsistent. I also see a lot of when interactions happen fast. submitTaskRequest failed for com.apple.coredata.cloudkit.activity.import. submitTaskRequest failed for com.apple.coredata.cloudkit.activity.export. I least I hope is that after the app has synchronised, the widget will catch-up and show the same data - i.e. at least the same device will show data consistently. This does not happen though. Even on the device on which I'm doing the changes, and tapping multiple times the manual reload of widgets button, the Core Data is stale, and the time of reload of the widget is fine. The relevant threads this I've found are (none of them can shed any light): https://developer.apple.com/forums/thread/653112?answerId=697974022 https://developer.apple.com/forums/thread/650192?answerId=614112022#614112022 https://developer.apple.com/forums/thread/651648?answerId=827386022 I have tested with iOS 26.5.2 and iOS 27 Beta. The widget is it out sync
2
0
354
3w
AlarmKit leaves an empty zombie Live Activity in Dynamic Island after swipe-dismiss while unlocked
Hi, We are the developers of Morning Call (https://morningcall.info), and we believe we may have identified an AlarmKit / system UI bug on iPhone. We can reproduce the same behavior not only in our app, but also in Apple’s official AlarmKit sample app, which strongly suggests this is a framework or system-level issue rather than an app-specific bug. Demonstration Video of producing zombie Live Activity https://www.youtube.com/watch?v=cZdF3oc8dVI Related Thread https://developer.apple.com/forums/thread/812006 https://developer.apple.com/forums/thread/817305 https://developer.apple.com/forums/thread/807335 Environment iPhone with Dynamic Island Alarm created using AlarmKit Device is unlocked when the alarm begins alerting Steps to reproduce Schedule an AlarmKit alarm. Wait for the alarm to alert while the device is unlocked. The alarm appears in Dynamic Island. Instead of tapping the intended stop or dismiss button, swipe the Dynamic Island presentation away. Expected result The alarm should be fully dismissed. The Live Activity should be removed. No empty UI should remain in Dynamic Island. Actual result The assigned AppIntent runs successfully. Our app code executes as expected. AlarmKit appears to stop the alarm correctly. However, an empty “zombie” Live Activity remains in Dynamic Island indefinitely. The user cannot clear it through normal interaction. Why this is a serious user-facing issue This is not just a cosmetic issue for us. From the user’s perspective, it looks like a Live Activity is permanently stuck in Dynamic Island. More importantly: Force-quitting the app does not remove it Deleting the app does not remove it In practice, many users conclude that our app has left a broken Live Activity running forever We receive repeated user complaints saying that the Live Activity “won’t go away” Because the remaining UI appears to be system-owned, users often do not realize that the only reliable recovery is to restart the phone. Most users do not discover that workaround on their own, so they instead assume the app is severely broken. Cases where the zombie state disappears Rebooting the phone Waiting for the next AlarmKit alert, then pressing the proper stop button on that alert Additional observations Inside our LiveActivityIntent, calling AlarmManager.shared.stop(id:) reports that the alarm has already been stopped by the system. We also tried inspecting Activity<AlarmAttributes<...>>.activities and calling end(..., dismissalPolicy: .immediate), but in this state no matching activity is exposed to the app. This suggests that the alarm itself has already been stopped, but the system-owned Live Activity UI is not being cleaned up correctly after the swipe-dismiss path. Why this does not appear to be an app logic issue The intent is invoked successfully. The alarm stop path is reached. The alarm is already considered stopped by the system. The remaining UI appears to be system-owned. The stuck UI persists even after our own cleanup logic has run. The stuck UI also survives app force-quit and app deletion.
7
10
1.3k
3w
Live Activities Push-to-Start flows
Good morning, We are implementing Live Activities in a push-to-start flow. We wrap the listener for push to start tokens in a high priority task: if ptsListenerTask == nil || ptsListenerTask?.isCancelled == true { ptsListenerTask = Task(priority: .high) { [weak self] in for await pushToken in Activity<LiveAuctionAttributes>.pushToStartTokenUpdates { //Send token to back-end } } I've tried a few variations of this and they work well on most devices. I have seen a couple of devices that refuse to issue a push to start token. The user will have logging for the init flow and starting the PTS listener then the logs just go silent, nothing happens. One thing that seemed to work was getting the user to start a Live Activity manually (from our debugging tool) then the PTS token gets issued. This is not very reliable and working a mock live activity into the flow for obtaining a PTS token is a poor solution. Is anyone else seeing this and is there a known issue with obtaining PTS tokens? Thanks! Brad
12
2
1.1k
3w
TimeDataSource .dateRange(endingAt:) won't update
Hello, I'm trying to add a new Live Activity to my app showing a timer to a specific date and time. I thought I could use some TimeDataSource so that the timer would be updated automatically by SwiftUI without relying on Live Activity updates. That's not the case with .dateRange(endingAt:) though. Text(.dateRange(endingAt: targetDate), format: .components(style: .narrow)) Something like this correctly shows the timer exactly how I want it, but it never updates. Other TimeDataSource like .currentDate and .durationOffset(to:) do update automatically, but are not what I'm looking for. Am I missing something? Should I use another formatter to make it work?
0
0
307
3w
Live Activity Stops Updating After 30 Seconds in Background During Audio Playback
Hi I developed a music app that plays offline audio and displays lyrics using Live Activities. According to ActivityKit documentation, Live Activities can be updated from the background. However, in my case, updates stop after ~30 seconds when the app goes to the background or the device is locked. Important points: The app continues running in the background (audio playback works fine using AVAudioSession with .playback) Background code execution is working as expected Only the Live Activity stops updating I am not using push updates since this is an offline app. Is there any limitation or requirement for updating Live Activities continuously in the background during audio playback? Audio Session Configuration let session = AVAudioSession.sharedInstance() try session.setCategory( .playback, mode: .default, options: [.mixWithOthers] // ✅ DO NOT interrupt other audio ) try session.setActive(true) print("✅ [AudioSession] Activated with mixWithOthers") } catch { print("❌ [AudioSession] Error: \(error)") } Live Activity Update Methods guard let activity = getLiveActivity(for: recordID) else{ print("⚠️ No Live Activity found for recordID: \(recordID)") return } guard activity.activityState == .active else { print("⚠️ Activity is not active") return } Task { let content = ActivityContent( state: state, staleDate: Date().addingTimeInterval(60 * 60 * 12), relevanceScore: 1.0 ) await activity.update(content) print("✅ Live Activity updated with ActivityContent") } }
1
0
875
3w
LiveActivity push-to-start flow inconsistency
Problem: unable to retrieve push-to-start token upon app start Environment: simulator, iPhone 15 Pro, iOS 18.1 (also reproduced on physical devices) First image is a start from XCode with "Run" option (Cmd+R) where debugger is linked Second image is a "cold" start - starting app by tapping the icon Difference is: Start observing (line 2), push token changed (last line). Everything is okay Push token changed (7 line), start observing (9 line). liveactivitysd generates token before we reach pushToStartTokenUpdates loop - we losing token The question is: how is this possible (case 2)?
0
0
318
3w
iOS 26.5 breaks AppIntents with AppEnums defined in Swift Package
For some reason since iOS 26.5, a ControlWidgetButton or a Button in a widget configured with an AppIntent conforming to OpenIntent fails to receive its AppEnum parameter correctly if the intent and enum are defined inside a shared Swift Package. Tapping the control widget button opens the main application, but it doesn't pass the AppEnum parameter value in, leaving the app on its default screen instead of navigating to the intended view. This was working perfectly in iOS 26.4, where the app would launch and receive the correct enum case from the intent. No code, configuration, or scheme changes were made between the two runs, only the simulator/OS version differs. Has anyone else run into what seems to be a regression on iOS 26.5? I filed feedback with a sample project: FB22848510
1
2
743
3w
Push to Start Live Activity — dismissal-date not supported in start payload causes un-dismissable notifications
Hey everyone, We're using Push to Start Live Activities in our app (District: Movies Events Dining) where all Live Activities are entirely server-driven. At District, we've taken a unique approach to Live Activities. Since our customers often plan ahead reserving restaurant tables early in the week or booking movies days in advance we needed a way to surface timely, relevant information without requiring the app to be open. We power our Live Activities entirely from the server using Push to Start and Push to Update. This means the Live Activity is initiated and kept up to date by our backend from reservation confirmation all the way to the day of the experience. Whether it's a dining slot or a movie showtime, the Live Activity automatically appears in the notification tray with all relevant details, right when you need it no app launch required. FB Number: FB22062904 Problem: When a Push to Start payload is sent from the server, the user sees an Allow / Don't Allow prompt on their lock screen. If the user ignores this prompt (neither taps Allow nor Don't Allow), the Live Activity card stays stuck in the notification tray permanently with zero way to dismiss it programmatically. This happens because: The activity never officially "starts" on device Activity.end() cannot be called — there's nothing to end Sending an update/end push has no effect dismissal-date is not honoured in the start payload Steps to Reproduce Send a push-to-start APNs payload to a device Do NOT tap Allow or Don't Allow on the prompt Observe — card stays in notification tray indefinitely Send an end push from server — no effect Current Payload { "aps": { "timestamp": 1234567890, "event": "start", "alert": { "title": "Your table is reserved", "body": "Tap to view your reservation" }, "content-state": { ... }, "attributes-type": "ReservationActivityAttributes", "attributes": { ... } // ❌ dismissal-date has no effect here } } Expected Behaviour dismissal-date should be honoured in the push-to-start payload, so that if the user ignores the prompt, the notification auto-dismisses after the specified time — consistent with how standard Live Activity expiry works. Suggested Fix { "aps": { "timestamp": 1234567890, "event": "start", "content-state": { ... }, "dismissal-date": 1234568490 // ✅ honour this } } Impact This affects any app using server-driven Live Activities — dining reservations, movie bookings, food delivery, ride hailing, ticketing etc. Without this, there is no way to prevent permanent notification tray pollution for users who ignore the Allow prompt. Has anyone found a workaround for this? Would love to know if others are hitting the same issue.
0
3
416
3w
UI Regession for array widget configuration in iOS 27 Beta 1
Not sure if this is an intented change in terms of UI on 27 beta 1, but I think the previous implementation of configuring array of App Entity is better with a list and options and reorder and remove items. My widget configuration code: struct BusWidgetConfiguration: WidgetConfigurationIntent { static var title: LocalizedStringResource { "Bus Stop Configuration" } static var description: IntentDescription { "Configure youe top 3 most commonly used bus stop to open in app." } @Parameter(title: "Bus Stop", default: [], size: IntentCollectionSize(min: 0, max: 3)) var busStops: [BusStopEntity] @Parameter(title: "Open in Maps", default: false) var openInMaps: Bool } iOS 27 Beta 1: iOS 26.5:
1
0
539
4w
Live Activity reports .active via ActivityKit but widget extension never renders or appears in process list (works fine in isolated test project)
I'm seeing a Live Activity that successfully starts via Activity.request() — activityState returns .active, a valid ActivityKit push token is issued and works correctly — but nothing ever appears on the Lock Screen, and the widget extension process never shows up in Xcode's Debug → Attach to Process list (the main app process does appear). This happens consistently across many clean rebuilds. Setup: Flutter app (using the live_activities Flutter plugin, which wraps ActivityKit) with a native iOS Widget Extension target for the Live Activity Xcode 26.5, iOS 18.7.9 on a physical iPhone XS Max Bundle ID: com.santitech.foodboda, extension: com.santitech.foodboda.FoodbodaLiveActivity NSSupportsLiveActivities = YES confirmed in both the main app's Info.plist and the extension's Info.plist (verified in the compiled .appex binary itself, not just source) App Group entitlement confirmed present in both compiled provisioning profiles via security cms -D on embedded.mobileprovision Deployment target 16.6 on both targets (Live Activities require 16.1+) Settings → [App] → Live Activities toggle confirmed ON; Low Power Mode OFF What I've already ruled out: Target membership of Swift source files — confirmed correct in File Inspector WidgetBundle only references the real Live Activity widget (removed unused Control/home-widget/AppIntent boilerplate) Info.plist NSExtensionPointIdentifier = com.apple.widgetkit-extension — correct Built a brand-new, separate, minimal test app+extension from Xcode's default template, using the exact same Attributes/ContentState/SwiftUI view code as the main app (copy-pasted verbatim) — this minimal test successfully renders on the Lock Screen on the same physical device. This proves the Swift code itself, the device, and the Apple ID/provisioning are all capable of supporting Live Activities correctly. Confirmed areActivitiesEnabled() returns true and getActivityState() returns .active on every test Tested with full app delete + device restart + DerivedData wipe between attempts — no change Question: Given that identical code works in an isolated minimal project but not in the main app's bundle ID, what could cause this specific symptom — ActivityKit registering an activity as active while WidgetKit never instantiates the extension to render it — tied to one specific app/bundle identifier rather than the device or account in general? Is there a known interaction with App Groups that have been reconfigured many times during development, or any way to fully reset WidgetKit's registration state for a specific bundle ID short of changing the bundle identifier entirely?
0
0
388
4w
Snippet Views don't render consistently, width not always respected
I've created a Snippet for my iOS app which I want to be able to run from the LockScreen via a Shortcuts widget. All works fine except when I run the shortcut and the App Snippet appears, it doesn't always render the SwiftUI view in the same way. Sometimes the width boundaries are respected and sometimes not. I've tested this on iOS 26.1 and iOS 26.2 beta 3 I think this is a bug but it would be great if anyone could see what I might be doing wrong if it's not. Incase it is a bug I've filed a feedback (FB21076429) and I've created a stripped down sample project showing the issue and added screenshots showing the issue. Basic code to reproduce issue: // Intent.swift // SnippetBug import AppIntents import Foundation import SwiftUI struct SnippetEntryIntent: AppIntent { static let title: LocalizedStringResource = "Open Snippet" static let description = IntentDescription("Shows a snippet.") // Don’t open the app – stay in the snippet surface. static let openAppWhenRun: Bool = false func perform() async throws -> some ShowsSnippetIntent { .result(snippetIntent: TestSnippetIntent()) } } struct TestSnippetIntent: SnippetIntent { static let title: LocalizedStringResource = "Snippet Intent" static let description = IntentDescription("Action from snippet.") @MainActor func perform() async throws -> some IntentResult & ShowsSnippetView { .result(view: SnippetView(model: SnippetModel.shared)) } } @MainActor final class SnippetModel { static let shared = SnippetModel() private init() { } } struct SnippetView: View { let model: SnippetModel var body: some View { HStack { Text("Test Snippet with information") Spacer() Image(systemName: "heart") }.font(.headline) } } struct Shortcuts: AppShortcutsProvider { static var appShortcuts: [AppShortcut] { AppShortcut( intent: SnippetEntryIntent(), phrases: [ "Snippet for \(.applicationName)", "Test Snippet \(.applicationName)" ], shortTitle: "Snippet", systemImageName: "barcode" ) } } You also need these lines in your main App entry point: import AppIntents @main struct SnippetBugApp: App { init() { let model = SnippetModel.shared AppDependencyManager.shared.add(dependency: model) } var body: some Scene { WindowGroup { ContentView() } } } This is correct This is incorrect
2
1
658
Jun ’26
Live Activity (ActivityKit) always defaults to dark colorScheme on iOS 27
Environment: iOS Version: iOS 27.0 Framework: ActivityKit Xcode Version: Xcode 26.1 Issue Description: In iOS 27, Live Activities fail to adapt to the system colorScheme. Regardless of whether the system theme is set to Light or Dark mode, @Environment(.colorScheme) inside the Live Activity view always returns .dark. This behavior worked as expected on iOS 26, where the Live Activity correctly responded to light/dark mode changes and rendered the appropriate theme. Expected Behavior: The Live Activity view should respect the system's current colorScheme (returning .light when the system is in Light Mode) on iOS 27, consistent with the behavior on iOS 26. Actual Behavior: The Live Activity view strictly defaults to .dark mode on iOS 27, even when the device is explicitly set to Light Mode. struct LockScreenView<T: BaseLiveActivityAttributes>: View { let context: ActivityViewContext<T> @Environment(\.colorScheme) var colorScheme var isLight: Bool { colorScheme == .light } var body: some View { Color(isLight ? .white : .black) .overlay(alignment: .topTrailing) { VStack(alignment: .trailing, spacing: 2) { Text("colorScheme: \(String(describing: colorScheme))") } .font(.system(size: 9, weight: .bold, design: .monospaced)) .foregroundColor(.yellow) .padding(4) .background(Color.black.opacity(0.6)) .cornerRadius(4) .padding(.trailing, 8) .padding(.top, 4) } } } Any insights or workarounds would be greatly appreciated. Thanks!
Replies
0
Boosts
0
Views
13
Activity
7h
Lack of Native CJK Serif Font Support in WidgetKit (Font.design(.serif))
Hello everyone, I am encountering an inconsistent typography behavior when developing for WidgetKit. Specifically, there is no native serif font fallback for Chinese characters (CJK) in the Widget environment, whereas Latin characters are fully supported. When using the .serif design modifier in SwiftUI: Text("Hello 世界").font(.system(size: 16, design: .serif)) English/Latin characters ("Hello"): System correctly renders using the pre-installed serif font (New York). Chinese characters ("世界"): System ignores the .serif design and falls back to the default sans-serif font (PingFang SC). Can I find any pre-installed native serif font for CJK in iOS that I can reliably invoke within my Widget Extension without bundling .ttf files? If not, do you have plans to map Font.design(.serif) to a pre-installed CJK serif font in future iOS releases so I can maintain design consistency across my localized widgets? Thank you for any insights or recommended workarounds.
Replies
0
Boosts
0
Views
95
Activity
4d
Some users doesn't get live activities
Some users are reporting that they don't see Live Activities, but our logs show that the trigger was sent successfully. Is there a way to investigate on the client side why the Live Activity didn't appear? Logs on client side? anything?
Replies
1
Boosts
0
Views
182
Activity
1w
Control Center and other music apps
Now, my app "iSwitcher" can switch songs only in Apple Music. How to switch songs in any app that are playing? It is available in Android system.
Replies
1
Boosts
0
Views
199
Activity
1w
WidgetKit complications won't update
We are migrating ClockKit complications to WidgetKit in our watch app (watchOS 9+). The migration went smoothly, UI part works just fine. However, we've hit the wall with widgets not updating when requested by the watch app. I believe we are missing something very simple and fundamental, but couldn't find what exactly so far. Advice and tips would be very welcome! 🙇‍♂️ Our implementation details: Whenever data is changed in the main app, the updated data is submitted to the watch app via WatchConnectivity framework using WCSession.default.transferCurrentComplicationUserInfo(_:). According to documentation, this method should be used to transfer complication-related data, since it will wake the watch app even if it is in the background or not opened at all. Watch app receives updated data and stores it in UserDefaults shared with Watch Widget Extension hosting WidgetKit complications via App Group. Watch app then request widget timeline reload via WidgetCenter.shared.reloadAllTimelines(). According to documentation, it reloads the timelines for all configured widgets belonging to the containing app, so it seems the appropriate way to reload WidgetKit complications. Widget Timeline Provider class in Watch Widget Extension reads updated data from shared UserDefaults and uses it to provide the updated snapshot for widget views to render. We believe our implementation logic is correct, but it doesn't work, for some reason. Widgets sometimes update when the watch app is opened, but not always. The most definitive way to force widgets to update is to switch to a different watch face, which confirms that the Widget Timeline Provider has access to properly updated data. P.S. We are aware of the daily reload budget imposed on widgets, so we use widgets reload trigger sparingly. Anyway, according to documentation, reload budget is not effective when in DEBUG mode, but widgets won't reload even in DEBUG mode. Thank you!
Replies
20
Boosts
10
Views
7.7k
Activity
2w
AudioRecordingIntent: AVAudioSession.setActive() fails with OSStatus 561015905 on Lock Screen
Hello, I'm implementing AudioRecordingIntent on iOS 26. My goal is to support Action Button exactly like Apple's Voice Memos: • press Action Button • device remains locked • recording starts immediately • no Face ID • Live Activity is shown • no application UI My intent conforms to AudioRecordingIntent. Inside perform() I do: AVAudioSession.sharedInstance().setCategory(.record) AVAudioSession.sharedInstance().setActive(true) AVAudioRecorder.record() The result is: setCategory succeeds. setActive always fails with NSOSStatusErrorDomain Code = 561015905 "Session activation failed" The failure happens before AVAudioRecorder starts. If I instead forward execution to the main application, iOS requests Face ID before recording begins. Questions: Is AVAudioSession activation inside AudioRecordingIntent actually supported for third-party apps? If not, what is the expected architecture for implementing lock-screen recording using AudioRecordingIntent? Is there an official sample project demonstrating the intended implementation? Thank you.
Replies
0
Boosts
0
Views
266
Activity
2w
Recommended approach for updating a push-to-start Live Activity when the app is force-quit?
I create a Live Activity remotely via push-to-start, then use its per-activity token (Activity.pushTokenUpdates) so my server can send update/end pushes. To make sure I'm not missing tokens, I observe Activity.activityUpdates and prime from the Activity.activities snapshot at launch and on sceneWillEnterForeground, then subscribe each activity's pushTokenUpdates and POST the token to my server. This works reliably while the app is running or backgrounded/suspended — the system wakes it and I capture the token. The problem is the user force-quit case (swiped from the App Switcher, never reopened): Push-to-start still creates the Live Activity and it renders correctly on the Lock Screen. But pushTokenUpdates never fires, so my server never receives the per-activity token and can't update or end that activity. A backgrounded (not force-quit) app, as a control, captures the token every time. So it seems specific to user-termination rather than all "not running" states. I understand force-quit apps generally aren't granted background runtime — I'm trying to confirm whether that applies here and what the right pattern is. What's the recommended approach? Specifically: Is there any supported way to get the per-activity token to my server while the app stays force-quit — e.g. from the widget extension (does it have any access to Activity.pushToken, or only ActivityViewContext?) or a Notification Service Extension? 2. If not, is setting stale-date on the start push the intended way to let the card expire gracefully when it can never be ended via push? 3. Is there a better pattern for keeping a push-started Live Activity correct when the app is never relaunched?
Replies
1
Boosts
0
Views
502
Activity
2w
Widget and Core Data with CloudKit
I have two apps that use App Groups, CloudKit and Core Data for sharing data between multiple devices and users (one is a sample for the issue, the other one the full fledged one). In the sample app I have the following model: Collection (name) -> many Items (names and count) and corresponding views to increment the count. I also have the widget share the proper App Group and CloudKit container. It has a button that triggers an increment app intent. A create a shared collection "Shares" and add two items in it - "A" & "B". Sharing from the applications and updates of the count takes about 2 seconds. I.e. I open the item view and I tap an increment button, the second phone screen updates almost immediately. Upon each update I also call WidgetCenter.shared.reloadAllTimelines(). What I see is that widgets have are not in sync with the data of the app. I have an explicit button to trigger the reload of the timelines, I can follow along with the debugger and the Core Data data is different, i.e. different count. I also show a date property, so I know that the widget is redrawn. I think that as soon as I added the target for the widget and added it to the app group I started seeing: BUG IN CLOUDKIT: Error submitting background task request: Error Domain=BGSystemTaskSchedulerErrorDomain Code=3 "(null)". The sync between the widget and the app on the same device is inconsistent. I also see a lot of when interactions happen fast. submitTaskRequest failed for com.apple.coredata.cloudkit.activity.import. submitTaskRequest failed for com.apple.coredata.cloudkit.activity.export. I least I hope is that after the app has synchronised, the widget will catch-up and show the same data - i.e. at least the same device will show data consistently. This does not happen though. Even on the device on which I'm doing the changes, and tapping multiple times the manual reload of widgets button, the Core Data is stale, and the time of reload of the widget is fine. The relevant threads this I've found are (none of them can shed any light): https://developer.apple.com/forums/thread/653112?answerId=697974022 https://developer.apple.com/forums/thread/650192?answerId=614112022#614112022 https://developer.apple.com/forums/thread/651648?answerId=827386022 I have tested with iOS 26.5.2 and iOS 27 Beta. The widget is it out sync
Replies
2
Boosts
0
Views
354
Activity
3w
AlarmKit leaves an empty zombie Live Activity in Dynamic Island after swipe-dismiss while unlocked
Hi, We are the developers of Morning Call (https://morningcall.info), and we believe we may have identified an AlarmKit / system UI bug on iPhone. We can reproduce the same behavior not only in our app, but also in Apple’s official AlarmKit sample app, which strongly suggests this is a framework or system-level issue rather than an app-specific bug. Demonstration Video of producing zombie Live Activity https://www.youtube.com/watch?v=cZdF3oc8dVI Related Thread https://developer.apple.com/forums/thread/812006 https://developer.apple.com/forums/thread/817305 https://developer.apple.com/forums/thread/807335 Environment iPhone with Dynamic Island Alarm created using AlarmKit Device is unlocked when the alarm begins alerting Steps to reproduce Schedule an AlarmKit alarm. Wait for the alarm to alert while the device is unlocked. The alarm appears in Dynamic Island. Instead of tapping the intended stop or dismiss button, swipe the Dynamic Island presentation away. Expected result The alarm should be fully dismissed. The Live Activity should be removed. No empty UI should remain in Dynamic Island. Actual result The assigned AppIntent runs successfully. Our app code executes as expected. AlarmKit appears to stop the alarm correctly. However, an empty “zombie” Live Activity remains in Dynamic Island indefinitely. The user cannot clear it through normal interaction. Why this is a serious user-facing issue This is not just a cosmetic issue for us. From the user’s perspective, it looks like a Live Activity is permanently stuck in Dynamic Island. More importantly: Force-quitting the app does not remove it Deleting the app does not remove it In practice, many users conclude that our app has left a broken Live Activity running forever We receive repeated user complaints saying that the Live Activity “won’t go away” Because the remaining UI appears to be system-owned, users often do not realize that the only reliable recovery is to restart the phone. Most users do not discover that workaround on their own, so they instead assume the app is severely broken. Cases where the zombie state disappears Rebooting the phone Waiting for the next AlarmKit alert, then pressing the proper stop button on that alert Additional observations Inside our LiveActivityIntent, calling AlarmManager.shared.stop(id:) reports that the alarm has already been stopped by the system. We also tried inspecting Activity<AlarmAttributes<...>>.activities and calling end(..., dismissalPolicy: .immediate), but in this state no matching activity is exposed to the app. This suggests that the alarm itself has already been stopped, but the system-owned Live Activity UI is not being cleaned up correctly after the swipe-dismiss path. Why this does not appear to be an app logic issue The intent is invoked successfully. The alarm stop path is reached. The alarm is already considered stopped by the system. The remaining UI appears to be system-owned. The stuck UI persists even after our own cleanup logic has run. The stuck UI also survives app force-quit and app deletion.
Replies
7
Boosts
10
Views
1.3k
Activity
3w
Hotspot not disabled on control center through the widget with multiple network
Hotspot not being disabled through the widget with multiple network buttons (dont remember the name of it, it has multiple connection widgets as one). The hotspot is however is shown disabled but its not the correct state as we can discover in settings that is still enabled.
Replies
1
Boosts
0
Views
305
Activity
3w
Live Activities Push-to-Start flows
Good morning, We are implementing Live Activities in a push-to-start flow. We wrap the listener for push to start tokens in a high priority task: if ptsListenerTask == nil || ptsListenerTask?.isCancelled == true { ptsListenerTask = Task(priority: .high) { [weak self] in for await pushToken in Activity<LiveAuctionAttributes>.pushToStartTokenUpdates { //Send token to back-end } } I've tried a few variations of this and they work well on most devices. I have seen a couple of devices that refuse to issue a push to start token. The user will have logging for the init flow and starting the PTS listener then the logs just go silent, nothing happens. One thing that seemed to work was getting the user to start a Live Activity manually (from our debugging tool) then the PTS token gets issued. This is not very reliable and working a mock live activity into the flow for obtaining a PTS token is a poor solution. Is anyone else seeing this and is there a known issue with obtaining PTS tokens? Thanks! Brad
Replies
12
Boosts
2
Views
1.1k
Activity
3w
TimeDataSource .dateRange(endingAt:) won't update
Hello, I'm trying to add a new Live Activity to my app showing a timer to a specific date and time. I thought I could use some TimeDataSource so that the timer would be updated automatically by SwiftUI without relying on Live Activity updates. That's not the case with .dateRange(endingAt:) though. Text(.dateRange(endingAt: targetDate), format: .components(style: .narrow)) Something like this correctly shows the timer exactly how I want it, but it never updates. Other TimeDataSource like .currentDate and .durationOffset(to:) do update automatically, but are not what I'm looking for. Am I missing something? Should I use another formatter to make it work?
Replies
0
Boosts
0
Views
307
Activity
3w
Live Activity Stops Updating After 30 Seconds in Background During Audio Playback
Hi I developed a music app that plays offline audio and displays lyrics using Live Activities. According to ActivityKit documentation, Live Activities can be updated from the background. However, in my case, updates stop after ~30 seconds when the app goes to the background or the device is locked. Important points: The app continues running in the background (audio playback works fine using AVAudioSession with .playback) Background code execution is working as expected Only the Live Activity stops updating I am not using push updates since this is an offline app. Is there any limitation or requirement for updating Live Activities continuously in the background during audio playback? Audio Session Configuration let session = AVAudioSession.sharedInstance() try session.setCategory( .playback, mode: .default, options: [.mixWithOthers] // ✅ DO NOT interrupt other audio ) try session.setActive(true) print("✅ [AudioSession] Activated with mixWithOthers") } catch { print("❌ [AudioSession] Error: \(error)") } Live Activity Update Methods guard let activity = getLiveActivity(for: recordID) else{ print("⚠️ No Live Activity found for recordID: \(recordID)") return } guard activity.activityState == .active else { print("⚠️ Activity is not active") return } Task { let content = ActivityContent( state: state, staleDate: Date().addingTimeInterval(60 * 60 * 12), relevanceScore: 1.0 ) await activity.update(content) print("✅ Live Activity updated with ActivityContent") } }
Replies
1
Boosts
0
Views
875
Activity
3w
LiveActivity push-to-start flow inconsistency
Problem: unable to retrieve push-to-start token upon app start Environment: simulator, iPhone 15 Pro, iOS 18.1 (also reproduced on physical devices) First image is a start from XCode with "Run" option (Cmd+R) where debugger is linked Second image is a "cold" start - starting app by tapping the icon Difference is: Start observing (line 2), push token changed (last line). Everything is okay Push token changed (7 line), start observing (9 line). liveactivitysd generates token before we reach pushToStartTokenUpdates loop - we losing token The question is: how is this possible (case 2)?
Replies
0
Boosts
0
Views
318
Activity
3w
iOS 26.5 breaks AppIntents with AppEnums defined in Swift Package
For some reason since iOS 26.5, a ControlWidgetButton or a Button in a widget configured with an AppIntent conforming to OpenIntent fails to receive its AppEnum parameter correctly if the intent and enum are defined inside a shared Swift Package. Tapping the control widget button opens the main application, but it doesn't pass the AppEnum parameter value in, leaving the app on its default screen instead of navigating to the intended view. This was working perfectly in iOS 26.4, where the app would launch and receive the correct enum case from the intent. No code, configuration, or scheme changes were made between the two runs, only the simulator/OS version differs. Has anyone else run into what seems to be a regression on iOS 26.5? I filed feedback with a sample project: FB22848510
Replies
1
Boosts
2
Views
743
Activity
3w
KEEP WALKIE TALKIE
Pls apple i daily drive this and is a core part of the apple ecosystem i even bought my cousin a watch to solely talk to him whenever
Replies
1
Boosts
0
Views
357
Activity
3w
Push to Start Live Activity — dismissal-date not supported in start payload causes un-dismissable notifications
Hey everyone, We're using Push to Start Live Activities in our app (District: Movies Events Dining) where all Live Activities are entirely server-driven. At District, we've taken a unique approach to Live Activities. Since our customers often plan ahead reserving restaurant tables early in the week or booking movies days in advance we needed a way to surface timely, relevant information without requiring the app to be open. We power our Live Activities entirely from the server using Push to Start and Push to Update. This means the Live Activity is initiated and kept up to date by our backend from reservation confirmation all the way to the day of the experience. Whether it's a dining slot or a movie showtime, the Live Activity automatically appears in the notification tray with all relevant details, right when you need it no app launch required. FB Number: FB22062904 Problem: When a Push to Start payload is sent from the server, the user sees an Allow / Don't Allow prompt on their lock screen. If the user ignores this prompt (neither taps Allow nor Don't Allow), the Live Activity card stays stuck in the notification tray permanently with zero way to dismiss it programmatically. This happens because: The activity never officially "starts" on device Activity.end() cannot be called — there's nothing to end Sending an update/end push has no effect dismissal-date is not honoured in the start payload Steps to Reproduce Send a push-to-start APNs payload to a device Do NOT tap Allow or Don't Allow on the prompt Observe — card stays in notification tray indefinitely Send an end push from server — no effect Current Payload { "aps": { "timestamp": 1234567890, "event": "start", "alert": { "title": "Your table is reserved", "body": "Tap to view your reservation" }, "content-state": { ... }, "attributes-type": "ReservationActivityAttributes", "attributes": { ... } // ❌ dismissal-date has no effect here } } Expected Behaviour dismissal-date should be honoured in the push-to-start payload, so that if the user ignores the prompt, the notification auto-dismisses after the specified time — consistent with how standard Live Activity expiry works. Suggested Fix { "aps": { "timestamp": 1234567890, "event": "start", "content-state": { ... }, "dismissal-date": 1234568490 // ✅ honour this } } Impact This affects any app using server-driven Live Activities — dining reservations, movie bookings, food delivery, ride hailing, ticketing etc. Without this, there is no way to prevent permanent notification tray pollution for users who ignore the Allow prompt. Has anyone found a workaround for this? Would love to know if others are hitting the same issue.
Replies
0
Boosts
3
Views
416
Activity
3w
UI Regession for array widget configuration in iOS 27 Beta 1
Not sure if this is an intented change in terms of UI on 27 beta 1, but I think the previous implementation of configuring array of App Entity is better with a list and options and reorder and remove items. My widget configuration code: struct BusWidgetConfiguration: WidgetConfigurationIntent { static var title: LocalizedStringResource { "Bus Stop Configuration" } static var description: IntentDescription { "Configure youe top 3 most commonly used bus stop to open in app." } @Parameter(title: "Bus Stop", default: [], size: IntentCollectionSize(min: 0, max: 3)) var busStops: [BusStopEntity] @Parameter(title: "Open in Maps", default: false) var openInMaps: Bool } iOS 27 Beta 1: iOS 26.5:
Replies
1
Boosts
0
Views
539
Activity
4w
Live Activity reports .active via ActivityKit but widget extension never renders or appears in process list (works fine in isolated test project)
I'm seeing a Live Activity that successfully starts via Activity.request() — activityState returns .active, a valid ActivityKit push token is issued and works correctly — but nothing ever appears on the Lock Screen, and the widget extension process never shows up in Xcode's Debug → Attach to Process list (the main app process does appear). This happens consistently across many clean rebuilds. Setup: Flutter app (using the live_activities Flutter plugin, which wraps ActivityKit) with a native iOS Widget Extension target for the Live Activity Xcode 26.5, iOS 18.7.9 on a physical iPhone XS Max Bundle ID: com.santitech.foodboda, extension: com.santitech.foodboda.FoodbodaLiveActivity NSSupportsLiveActivities = YES confirmed in both the main app's Info.plist and the extension's Info.plist (verified in the compiled .appex binary itself, not just source) App Group entitlement confirmed present in both compiled provisioning profiles via security cms -D on embedded.mobileprovision Deployment target 16.6 on both targets (Live Activities require 16.1+) Settings → [App] → Live Activities toggle confirmed ON; Low Power Mode OFF What I've already ruled out: Target membership of Swift source files — confirmed correct in File Inspector WidgetBundle only references the real Live Activity widget (removed unused Control/home-widget/AppIntent boilerplate) Info.plist NSExtensionPointIdentifier = com.apple.widgetkit-extension — correct Built a brand-new, separate, minimal test app+extension from Xcode's default template, using the exact same Attributes/ContentState/SwiftUI view code as the main app (copy-pasted verbatim) — this minimal test successfully renders on the Lock Screen on the same physical device. This proves the Swift code itself, the device, and the Apple ID/provisioning are all capable of supporting Live Activities correctly. Confirmed areActivitiesEnabled() returns true and getActivityState() returns .active on every test Tested with full app delete + device restart + DerivedData wipe between attempts — no change Question: Given that identical code works in an isolated minimal project but not in the main app's bundle ID, what could cause this specific symptom — ActivityKit registering an activity as active while WidgetKit never instantiates the extension to render it — tied to one specific app/bundle identifier rather than the device or account in general? Is there a known interaction with App Groups that have been reconfigured many times during development, or any way to fully reset WidgetKit's registration state for a specific bundle ID short of changing the bundle identifier entirely?
Replies
0
Boosts
0
Views
388
Activity
4w
Snippet Views don't render consistently, width not always respected
I've created a Snippet for my iOS app which I want to be able to run from the LockScreen via a Shortcuts widget. All works fine except when I run the shortcut and the App Snippet appears, it doesn't always render the SwiftUI view in the same way. Sometimes the width boundaries are respected and sometimes not. I've tested this on iOS 26.1 and iOS 26.2 beta 3 I think this is a bug but it would be great if anyone could see what I might be doing wrong if it's not. Incase it is a bug I've filed a feedback (FB21076429) and I've created a stripped down sample project showing the issue and added screenshots showing the issue. Basic code to reproduce issue: // Intent.swift // SnippetBug import AppIntents import Foundation import SwiftUI struct SnippetEntryIntent: AppIntent { static let title: LocalizedStringResource = "Open Snippet" static let description = IntentDescription("Shows a snippet.") // Don’t open the app – stay in the snippet surface. static let openAppWhenRun: Bool = false func perform() async throws -> some ShowsSnippetIntent { .result(snippetIntent: TestSnippetIntent()) } } struct TestSnippetIntent: SnippetIntent { static let title: LocalizedStringResource = "Snippet Intent" static let description = IntentDescription("Action from snippet.") @MainActor func perform() async throws -> some IntentResult & ShowsSnippetView { .result(view: SnippetView(model: SnippetModel.shared)) } } @MainActor final class SnippetModel { static let shared = SnippetModel() private init() { } } struct SnippetView: View { let model: SnippetModel var body: some View { HStack { Text("Test Snippet with information") Spacer() Image(systemName: "heart") }.font(.headline) } } struct Shortcuts: AppShortcutsProvider { static var appShortcuts: [AppShortcut] { AppShortcut( intent: SnippetEntryIntent(), phrases: [ "Snippet for \(.applicationName)", "Test Snippet \(.applicationName)" ], shortTitle: "Snippet", systemImageName: "barcode" ) } } You also need these lines in your main App entry point: import AppIntents @main struct SnippetBugApp: App { init() { let model = SnippetModel.shared AppDependencyManager.shared.add(dependency: model) } var body: some Scene { WindowGroup { ContentView() } } } This is correct This is incorrect
Replies
2
Boosts
1
Views
658
Activity
Jun ’26