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

AppIntent perform function is not invoked from ControlWidget
I have an AppIntent that edits an object in my app. The intent accepts an app entity as a parameter, so if you run the intent it will ask which one do you want to edit, then you select one from the list and it shows a dialog that it was edited successfully. I use this same intent in my Home Screen widget initializing it with an objectEntity. The code needs to run in the app's process, not the widget extension process, so the file is added to both targets and it conforms to ForegroundContinuableIntent, and that is supposed to ensure it always runs in the app process. This works great when run from the Shortcuts app and when involved via a button in the Home Screen widget, exactly as expected. Here is that app intent: @available(iOS 17.0, *) struct EditObjectIntent: AppIntent { static let title: LocalizedStringResource = "Edit Object" @Parameter(title: "Object", requestValueDialog: "Which object do you want to edit?", inputConnectionBehavior: .connectToPreviousIntentResult) var objectEntity: ObjectEntity init() { print("INIT") } init(objectEntity: ObjectEntity) { self.objectEntity = objectEntity } @MainActor func perform() async throws -> some IntentResult & ReturnsValue<ObjectEntity> & ProvidesDialog { // Edit the object from objectEntity.id... return .result(value: objectEntity, dialog: "Done") } } @available(iOS 17.0, *) @available(iOSApplicationExtension, unavailable) extension EditObjectIntent: ForegroundContinuableIntent { } I now want to create a ControlButton that uses this intent: struct EditObjectControlWidget: ControlWidget { var body: some ControlWidgetConfiguration { StaticControlConfiguration(kind: "EditObjectControlWidget") { ControlWidgetButton(action: EditObjectIntent()) { Label("Edit Object", systemImage: "pencil") } } } } When I add the button to Control Center and tap it (on iOS 18), init is called 3x in the app process and 2x in the widget process, yet the perform function is not invoked in either process. No error appears in console logs for the app's process, but this appears for the widget process: LaunchServices: store <private> or url <private> was nil: Error Domain=NSOSStatusErrorDomain Code=-54 "process may not map database" UserInfo={NSDebugDescription=process may not map database, _LSLine=72, _LSFunction=_LSServer_GetServerStoreForConnectionWithCompletionHandler} Attempt to map database failed: permission was denied. This attempt will not be retried. Failed to initialize client context with error Error Domain=NSOSStatusErrorDomain Code=-54 "process may not map database" UserInfo={NSDebugDescription=process may not map database, _LSLine=72, _LSFunction=_LSServer_GetServerStoreForConnectionWithCompletionHandler} What am I doing wrong here? Thanks!
1
0
108
Jul ’25
WatchOS26 ControlWidget
WatchOS26 ControlWidget cannot display image copy or click import Foundation import SwiftUI import WidgetKit import AppIntents internal import Combine struct WidgetToggle: ControlWidget { var body: some ControlWidgetConfiguration { StaticControlConfiguration(kind: "com.example.myApp.performActionButton", provider: TimerValueProvider()) { isRunning in ControlWidgetToggle("WidgetToggle", isOn: isRunning, action: ToggleTimerIntent()) { isOn in Label(isOn ? "Running" : "Stopped", systemImage: isOn ? "hourglass.bottomhalf.filled" : "hourglass") } } .displayName("WidgetToggle") .description("WidgetToggle description") } } struct TimerValueProvider: ControlValueProvider { var previewValue: Bool { return false } func currentValue() async throws -> Bool { return TimerManager.shared.isRunning } } struct ToggleTimerIntent: SetValueIntent { static var title: LocalizedStringResource = "WidgetToggle" @Parameter(title: "Toggle") var value: Bool func perform() async throws -> some IntentResult { TimerManager.shared.isRunning = value return .result() } } class TimerManager: ObservableObject { static let shared = TimerManager() @Published var isRunning = false }
0
0
89
Jun ’25
Live Activity not displaying in Dynamic Island
I am developing Live Activities using Swift. The same code can display the lock screen view and Dynamic Island on most devices, but on one specific iPhone 16 Pro Max, the Dynamic Island is not shown. The system version is iOS 18.0. However, other apps on this phone can display the Dynamic Island normally. How should I troubleshoot the issue? Can anyone help me? Thank you.
0
0
47
Jun ’25
生产版本clip轻应用无法展示
我们在使用clip轻应用功能,在App Store Connect中配置了高级轻应用体验,并配置了相关的https链接(在构建版本页面此域名是已验证状态),但是我们在使用此链接进行NFC触碰时,不会拉起来clip轻应用,只会显示“XXXX NFC标签”,使用Apple的官方链接:https://appclip.apple.com/id?p=xxxx,是可以拉起来轻应用的,请问各位大佬,我们的问题出现在哪?该如何解决?
0
0
69
Jun ’25
Surfacing time-sensitive shortcuts with AppIntents framework
I'm currently working on enhancing our app’s support for App Intents. We're aiming to suggest time-sensitive shortcuts to Spotlight and Siri — for example, proactively surfacing certain shortcut from 2 hours before some event the user has registered in their database until 2 hour after that. I’ve been reviewing the AppIntents framework documentation but haven’t found a definitive answer on whether this is currently achievable. From what we understand, the RelevantIntent and RelevantContext APIs appear to support time-based suggestions, but they seem to apply only to Widgets, not to standalone app shortcuts. Is this understanding correct, and is there a recommended approach for achieving time-sensitive shortcut suggestions outside of a Widget context? Any guidance would be greatly appreciated. Best regards,
0
0
55
Jun ’25
How to start live activity in terminated state?
Hi everyone and Apple support, I’ve built an app that continuously runs and receives temperature data from a sensor. When a threshold is reached, I use Live Activities with the push notification flow to display alerts on the Dynamic Island. The Live Activity and push notification flow work fine in foreground and background states. However, I’m trying to support push-triggered Live Activities when the app is in the terminated state. Since my app rarely terminates, I can’t confirm if the Live Activity push token is generated in that state. It seems like it isn’t, which blocks the Live Activity from starting via push. I tried with both pushtostarttoken and pushtostarttokenupdates. None of them worked. Has anyone dealt with this or found a workaround to ensure the push token is available even when the app is terminated?
0
0
116
Jul ’25
Feature Flagging Widgets & Widget Families
I am trying to feature flag widgets in my Widget extension. This feature flag value is stored remotely, read by my main app, and written to UserDefaults, then read from UserDefaults in my widget target. I understand that providing an empty array of WidgetFamilys will not show my app when the user goes to add a widget. However, even when this flag flips to true, hard-closing and reopening my app will not show my app in the list of apps you can add a widget for. But I notice that if I recompile my app from Xcode (running the app's scheme, not the widget scheme), then my app will show when you search for an app to add a widget for, making me think that these Widget objects are only created by the system once when the app is initially installed/updated. My concern is that I will not be able to flip this flag from false to true after the user has installed my app to do a rollout of my widget. Is this expected? Or is there an alternative or otherwise recommended way of doing this? struct MyWidget: Widget { let kind = "MyWidget" var supportedFamilies: [WidgetFamily] { let manager = ExtensionManager() if manager.widgetsEnabled { return [.systemSmall, .systemMedium, .systemLarge] } else { return [] } } var body: some WidgetConfiguration { IntentConfiguration( kind: kind, intent: MyWidgetIntent.self, provider: MyWidgetProvider() ) { entry in MyWidgetView(entry: entry) } .configurationDisplayName("My Widget") .description("Install my widget!") .supportedFamilies(supportedFamilies) } }
0
0
112
Jul ’25
How to track a Live Activity started via push when the app is terminated and hasn't been relaunched from long time?
Hi all, I'm currently implementing Live Activities using ActivityKit and facing a real-world limitation that I hope the community (or Apple) can clarify. 🔹 I can successfully start a Live Activity via APNs push (event: "start") even when the app is terminated — the Live Activity appears as expected on the Lock Screen and Dynamic Island. However, I need to update that Live Activity using the name I assigned in the push payload (e.g., match-123). This requires calling: Airship.channel.trackLiveActivity(activity, name: activity.attributes.matchID) …or equivalent code in native implementations to associate the activity with its push token. ❓The problem: If the user has never launched the app, or hasn't opened it after the Live Activity was started via push, then there’s no chance for the app to run this tracking code. So: ✅ Live Activity starts fine via APNs ❌ I can't track the activity and register it for future push updates (by name) until the app is launched ❌ Therefore, I can't update the Live Activity without knowing the token-name mapping 🔍 My question: Is there any way to programmatically track or associate a Live Activity (started via push) with a name for APNs updates, without requiring the app to launch? Or put differently: Can the system automatically track the name → token mapping if the activity is started via push? Is there any way (via entitlement, plist config, or system event) to allow registering the activity in the background (without user launch)? 💡 Notes: I already use pushType: .token and NSSupportsLiveActivitiesFrequentUpdates Live Activity content is fine; only the ability to send future updates is blocked without initial app launch Using Airship SDK for push + activity tracking, but the question is general to iOS + ActivityKit behavior Any insight on how apps like FotMob, Uber, or sports apps handle this situation would be really helpful! Thanks in advance.
1
0
203
Jul ’25
How to opt out of tinting widget content on visionOS
During the WWDC Session called "Design widgets for visionOS" the presenter says: You can choose whether the background of your widget participates in tinting. If you opted out, for example to preserve a photo or illustration, make sure it still looks good alongside the selected color palette. Unfortunately, this session has no example code. Can someone point me to the correct way to do this? Is there a modifier we can use on views? (reposting this in the correct topic/subtopic)
3
0
141
Aug ’25
Can custom user images be displayed as backgrounds on Lock Screen?
Background I'm developing an iOS app with Live Activities that allows users to select custom background images. While these custom images display correctly in widgets, they fail to appear in Live Activities on both Lock Screen and Dynamic Island, despite successful image loading and data transfer. Technical Details iOS Version: Testing on iOS 17.2+ Image Storage: Using App Group shared container for image sharing between main app and widget extension Image Loading: Successfully confirmed via logs - images load correctly with proper dimensions UI Framework: SwiftUI with ActivityKit What Works ✅ Custom images display correctly in Home Screen widgets ✅ Built-in bundled images work in Live Activities ✅ Image data successfully transfers via App Group shared container ✅ Image loading logs show successful UIImage creation with correct dimensions What Doesn't Work ❌ Custom user images don't display in Live Activities (Lock Screen) ❌ Custom user images don't display in Dynamic Island ❌ Images appear as black/gray background despite successful loading Code Implementation I've tried multiple approaches: 1. SwiftUI Image approach: Image(uiImage: customImage) .resizable() .aspectRatio(contentMode: .fill) 2. containerBackground API approach: .containerBackground(for: .widget) { Image(uiImage: customImage) .resizable() .aspectRatio(contentMode: .fill) } 3. UIKit wrapper approach: struct UIImageViewWrapper: UIViewRepresentable { let image: UIImage func makeUIView(context: Context) -> UIImageView { let imageView = UIImageView(image: image) imageView.contentMode = .scaleAspectFill return imageView } func updateUIView(_ uiView: UIImageView, context: Context) { uiView.image = image } } Observations Images load successfully (confirmed via console logs) File paths are correct and accessible Same image loading code works perfectly in widgets When testing with UIKit approach, a red prohibition icon appears, suggesting system restrictions Questions Is there a technical limitation preventing user-provided images from displaying in Live Activities? Are there specific security restrictions for Live Activity backgrounds that don't apply to widgets? Is this behavior intentional based on Apple's design guidelines for Live Activities? What's the recommended approach for custom backgrounds in Live Activities? Apple Documentation Reference I found this guidance in "10 questions with the Live Activities team": "The Dynamic Island is most immersive when you don't provide background color or imagery — think of it purely as a canvas of foreground view elements." However, this seems to be design guidance rather than a technical restriction, and it doesn't specifically address Lock Screen Live Activities. Expected Behavior Custom user images should display as backgrounds in Live Activities, similar to how they work in widgets. Current Workaround I've implemented a color extraction system that generates gradients based on the dominant colors of user images, but users specifically want to see their actual images. Has anyone successfully implemented custom user images as Live Activity backgrounds, or can Apple clarify the intended behavior and limitations? Thank you for any insights!
0
0
90
Aug ’25
watchOS 26 Control Widget AppEnum Localize issue
I’m implementing a Control Widget for watchOS 26 Beta 5, using .promptsForUserConfiguration() so that users can select an option from an enum when adding the widget. The overall functionality works fine, but when users configure the option, the enum’s corresponding text is not properly localized. My enum is defined like this: static var caseDisplayRepresentations: [XXXType: DisplayRepresentation] { [ XX1: .init(title: .init("text1", table: "xxx")), XX2: .init(title: .init("text2", table: "xxx")), ] } After the configuration is completed and the Control Widget appears in the Control Center or Smart Stack, the text is displayed correctly. Same code on iOS work perfect.
0
0
56
Aug ’25
Activity.request MACH_Exception EXC_BAD_ACCESS KERN_INVALID_ADDRESS
When I use the Activity.request method to start the Dynamic Island widget, there have been continuous crash reports online, Could you please provide some ideas on how to fix this crash? Thanks! Crash backtraces: 0ActivityKitblock_copy_helper.101 (in ActivityKit)+21416 1CombinePublishers.FlatMap.Outer.receive(B.Output) (in Combine)+296 2Combineprotocol witness for Subscriber.receive(A.Input) in conformance Publishers.FlatMap<A, B>.Outer<A1> (in Combine)+20 3CombinePublishers.HandleEvents.Inner.receive(A.Output) (in Combine)+204 4Combineprotocol witness for Subscriber.receive(A.Input) in conformance Publishers.HandleEvents<A>.Inner<A1> (in Combine)+20 5CombineFilterProducer.receive(B) (in Combine)+2508 6Combineprotocol witness for Subscriber.receive(A.Input) in conformance FilterProducer<A, B, C, D, E> (in Combine)+20 7Combinepartial apply for closure #4 (C) in Publishers._Merged.request(Subscribers.Demand) (in Combine)+52 8CombinePublishers._Merged.guardedApplyDownstream<A>((C)) (in Combine)+180 9CombinePublishers._Merged.receive(A, Int) (in Combine)+400 10CombinePublishers._Merged.Side.receive(A) (in Combine)+20 11CombineJust.Inner.request(Subscribers.Demand) (in Combine)+692 12Combineprotocol witness for Subscription.request(Subscribers.Demand) in conformance Just<A>.Inner<A1> (in Combine)+20 13CombinePublishers._Merged.receive(subscription: Subscription, _: Int) (in Combine)+496 14CombinePublishers._Merged.Side.receive(subscription: Subscription) (in Combine)+20 15CombineJust.receive<A>(subscriber: A1) (in Combine)+420 16CombinePublishers.Merge.receive<A>(subscriber: A1) (in Combine)+380 17CombinePublisherBox.receive<A>(subscriber: A1) (in Combine)+104 18CombineAnyPublisher.receive<A>(subscriber: A1) (in Combine)+60 19CombinePublishers.RemoveDuplicates.receive<A>(subscriber: A1) (in Combine)+220 20CombinePublishers.HandleEvents.receive<A>(subscriber: A1) (in Combine)+300 21CombinePublisherBox.receive<A>(subscriber: A1) (in Combine)+104 22CombineAnyPublisher.receive<A>(subscriber: A1) (in Combine)+60 23CombinePublishers.FlatMap.receive<A>(subscriber: A1) (in Combine)+416 24CombinePublishers.RemoveDuplicates.receive<A>(subscriber: A1) (in Combine)+220 25CombinePublisherBox.receive<A>(subscriber: A1) (in Combine)+104 26CombineAnyPublisher.receive<A>(subscriber: A1) (in Combine)+60 27CombinePublishers.CompactMap.receive<A>(subscriber: A1) (in Combine)+440 28CombinePublisherBox.receive<A>(subscriber: A1) (in Combine)+104 29CombineAnyPublisher.receive<A>(subscriber: A1) (in Combine)+60 30CombinePublishers.SetFailureType.receive<A>(subscriber: A1) (in Combine)+420 31CombinePublishers.FlatMap.receive<A>(subscriber: A1) (in Combine)+416 32CombinePublishers.RemoveDuplicates.receive<A>(subscriber: A1) (in Combine)+220 33CombinePublisherBox.receive<A>(subscriber: A1) (in Combine)+104 34CombineAnyPublisher.receive<A>(subscriber: A1) (in Combine)+60 35CombinePublishers.CompactMap.receive<A>(subscriber: A1) (in Combine)+440 36CombinePublisherBox.receive<A>(subscriber: A1) (in Combine)+104 37CombineAnyPublisher.receive<A>(subscriber: A1) (in Combine)+60 38CombinePublishers.ReceiveOn.receive<A>(subscriber: A1) (in Combine)+660 39CombinePublisher.sink(receiveCompletion: (Subscribers.Completion<A.Failure>), receiveValue: (A.Output)) (in Combine)+316 40ActivityKitblock_copy_helper.101 (in ActivityKit)+33364 41ActivityKitblock_copy_helper.101 (in ActivityKit)+26716 42ActivityKitblock_copy_helper.101 (in ActivityKit)+53192 43ActivityKitblock_copy_helper.101 (in ActivityKit)+52408 44ActivityKitblock_destroy_helper.25 (in ActivityKit)+1140 45ActivityKitblock_destroy_helper.62 (in ActivityKit)+8220 46ActivityKitblock_destroy_helper.62 (in ActivityKit)+9364 47libswiftDispatch.dylibpartial apply for thunk for @callee_guaranteed () -> (@out A, @error @owned Error) (in libswiftDispatch.dylib)+24 48libswiftDispatch.dylibthunk for @callee_guaranteed () -> (@out A, @error @owned Error)partial apply (in libswiftDispatch.dylib)+12 49libswiftDispatch.dylibclosure #1 () in closure #1 (()) in OS_dispatch_queue._syncHelper<A>(fn: (()), execute: (), rescue: (Error)) (in libswiftDispatch.dylib)+188 50libswiftDispatch.dylibpartial apply for thunk for @callee_guaranteed () -> () (in libswiftDispatch.dylib)+24 51libswiftDispatch.dylibthunk for @escaping @callee_guaranteed () -> () (in libswiftDispatch.dylib)+24 52libdispatch.dylib__dispatch_client_callout (in libdispatch.dylib)+16 53libdispatch.dylib__dispatch_lane_barrier_sync_invoke_and_complete (in libdispatch.dylib)+52 54libswiftDispatch.dylibimplicit closure #2 (()) in implicit closure #1 (OS_dispatch_queue) in OS_dispatch_queue.asyncAndWait<A>(execute: ()) (in libswiftDispatch.dylib)+188 55libswiftDispatch.dylibpartial apply for implicit closure #2 (()) in implicit closure #1 (OS_dispatch_queue) in OS_dispatch_queue.sync<A>(execute: ()) (in libswiftDispatch.dylib)+72 56libswiftDispatch.dylibOS_dispatch_queue._syncHelper<A>(fn: (()), execute: (), rescue: (Error)) (in libswiftDispatch.dylib)+400 57libswiftDispatch.dylibOS_dispatch_queue.asyncAndWait<A>(execute: ()) (in libswiftDispatch.dylib)+136 58libswiftDispatch.dylibOS_dispatch_queue.sync<A>(execute: ()) (in libswiftDispatch.dylib)+60 59ActivityKitblock_destroy_helper.62 (in ActivityKit)+3272 60ActivityKitblock_destroy_helper.62 (in ActivityKit)+724 61ActivityKit___swift_store_extra_inhabitant_indexTm (in ActivityKit)+24928 62ActivityKit___swift_store_extra_inhabitant_indexTm (in ActivityKit)+23900 63 XXXApp static LiveActivityService.request() ......
1
0
32
Aug ’25
ManagedSettings doesn't block Live Activities in the Dynamic Island
When using the ManagedSettings API to block apps everything is blocked as expected (the app itself, Notifications, Live Activities on the Lock Screen etc) except for Compact Live Activities of those apps (that are shown in the Dynamic Island). I feel the expected behavior would be to block also the Compact Live Activities. Our use case: In Spoilerblock we want to prevent users from being exposed to spoilers before they've had time to watch for example a sports game. Current workaround: Right now the best we can do is to ask the user to disable Live Activities for apps that could expose results, to not risk being exposed to a spoiler.
3
0
36
Aug ’25
connection to service created from an endpoint
The execution of the shortcut command is abnormal. An App Intents was created through xcode, a test example was written, and an exception was executed. error: couldn`t communicate with a helper application. log: Shortcut <WFWorkflow: 0x600003008b40, name: Test, actions: 1> failed with error Error Domain=NSCocoaErrorDomain Code=4097 "connection to service created from an endpoint" UserInfo={NSDebugDescription=connection to service created from an endpoint, WFActionIndex=0}. -[WFBackgroundShortcutRunner callWorkflowRunningCompletionBlockWithResult:] Workflow Did Finish: Calling Completion Block -[WFBackgroundShortcutRunner listener:shouldAcceptNewConnection:]_block_invoke XPC connection invalidated -[WFBackgroundShortcutRunnerStateMachine invalidateWithReason:] connection invalidated/interrupted while finishing shortcut or exiting runner. Exiting should already be in process, not transitioning. -[WFBackgroundShortcutRunner unaliveProcess]_block_invoke_2 Exiting process
0
0
50
Aug ’25
Cannot install any widgets. Crash in SBHRippleSimulation.
I cannot install any widgets on my simulator, even the system provided ones. I just finished removing all dev software from my machine and reinstalling only Xcode 16.3. Springboard always crashes: Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Subtype: KERN_INVALID_ADDRESS at 0xfffffffffffffff8 Exception Codes: 0x0000000000000001, 0xfffffffffffffff8 VM Region Info: 0xfffffffffffffff8 is not in any region. REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL UNUSED SPACE AT START ---> UNUSED SPACE AT END Termination Reason: SIGNAL 11 Segmentation fault: 11 Terminating Process: exc handler [5015] Triggered by Thread: 0 Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0 SpringBoardHome 0x10f0f8e50 -[SBHRippleSimulation clear] + 74 1 SpringBoardHome 0x10f0f8f0f -[SBHRippleSimulation createRippleAtGridCoordinate:strength:] + 73 2 libdispatch.dylib 0x12de8e5b6 _dispatch_client_callout + 6 3 libdispatch.dylib 0x12de78a33 _dispatch_continuation_pop + 859 4 libdispatch.dylib 0x12de8baae _dispatch_source_invoke + 2178 5 libdispatch.dylib 0x12de8388e _dispatch_main_queue_drain + 732 6 libdispatch.dylib 0x12de835a4 _dispatch_main_queue_callback_4CF + 31 7 CoreFoundation 0x12c25fd5c __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9 8 CoreFoundation 0x12c25a7c8 __CFRunLoopRun + 2511 9 CoreFoundation 0x12c2599f1 CFRunLoopRunSpecific + 536 10 GraphicsServices 0x118d35c09 GSEventRunModal + 137 11 UIKitCore 0x15732a580 -[UIApplication _run] + 875 12 UIKitCore 0x15732f707 UIApplicationMain + 123 13 SpringBoard 0x10fe9c4e2 SBSystemAppMain + 7639 14 ??? 0x10ada43da ??? 15 dyld 0x10fd7d530 start + 3056 So it's crashing when it tries to make the little animation when a widget is dropped. I removed all the runtimes, every cache and preference I could find, emptied the trash, rebooted (to release any open file descriptors), and reinstalled Xcode. Nothing helped.
0
0
115
Aug ’25