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

Widget Previews in visionOS 26 Beta (Xcode 26 Beta)
Hello, I'm currently developing for visionOS using Xcode's latest beta version. I have a question regarding Widget Previews for visionOS 26: When I create a new Widget Extension target directly from a visionOS project, the generated code does not include the #Preview macro. Following the documentation, I manually added the #Preview macro to a Widget created within a visionOS project, but Xcode then displays an error stating that "This platform does not support previewing widgets." My interpretation is that Widget Previews are currently not supported for Widgets created specifically for visionOS in this beta version. Is this understanding correct? Or am I missing a specific way to implement previews for visionOS Widgets, or is there a particular project setting I might have overlooked? Any clarification or guidance on this matter would be greatly appreciated. Thank you.
1
0
110
Jun ’25
Update Complications in WatchOS from iOS using WatchConnectivity?
I'm trying to update data displayed in my Watch Complications (WidgetKit). I have an iOS app that sends data to the Apple Watch using WCSession.default.transferUserInfo. However, the data only updates on the complications or widgets after I open the watchOS app manually. Ideally, I'd like the Watch widget/complication to reflect the updated data as soon as it's sent from the iPhone, without requiring the user to open the Watch app.
1
0
106
Jun ’25
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
Live Activity in terminated state
Hi. I need some help in starting the live activity in terminated state using push notification. I have developed an app which does not sleep and always run even in the background state. It is pressure calculator. From sensor, it will receive the pressure and display the values in the app. Whenever the pressure reaches a certain point, it should display the alert in the dynamic island. As of now, it is displaying live activity in the foreground state. Working partially fine in the background state. But not working in the terminated state. but in the documentation it have been mentioned we can start the live activity using push notification from any state. Please help me to find a solution.
1
1
62
Jul ’25
Large Gap Between Published and Delivered Broadcast Notifications for Live Activities in iOS 18
Hi All, I’m working on a football live score app with Dynamic Island support, using iOS 18 Broadcast Notifications for Live Activities. Our workflow is: We use the Push-to-Start token to initiate the Live Activity. For updates, we use the Channel ID. Start, update, and end events for Live Activities are all handled via remote notifications. We tested on 3-4 devices simultaneously, but noticed inconsistent UI updates: some devices update properly while others do not, even when using the same Channel ID. Checking the notification console dashboard, last week we had around 1,397 notifications published but only 555 delivered — a significant discrepancy. All devices are active and connected to reliable internet, so we’re unsure why delivery rates are so low. Additional details: For the start event, we set notification priority to 10. For updates, we lowered priority to 5 per Apple’s documentation, to reduce throttling. This adjustment improved the situation compared to sandbox testing where all notifications were priority 10. Despite this, during weekend matches, we observed a drastic drop: out of 140 published notifications, only 2 were delivered. This large delivery gap risks missing critical update deadlines in our app. Could anyone help us understand what might be causing this and how to improve notification delivery reliability? Thanks in advance!
1
0
72
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
Live Activity PushToken Not Callback
I have start new live activity with push notifications,but sometimes this code"activity.pushTokenUpdates" can not callback to me,so I can't update the activity with push notifications. And I already click “Allow” button in my live activity widget.How can I solve this problem. Here are my code: fileprivate func observeLiveActivityForRemoteCreate() { // obverser pushToStartToken Task { if #available(iOS 17.2, *) { var beforeToken = "" for await pushToken in Activity<HLPlatformActivityAttributes>.pushToStartTokenUpdates { let pushTokenStr = pushToken.map{String(format: "%02.2hhx", arguments: [$0])}.joined() // avoid send duplication if beforeToken == pushTokenStr { return } beforeToken = pushTokenStr // send pushToStartToken to service await HLPlatformLiveActivityBridge.registerLiveActivity(withAttributesName: self.activityAttributesName, pushToStartToken: pushToken, seq: seqCreate(), pushType: .jPush) } }else { // Fallback on eralier versions } // obverser live activity update Task { for await activity in Activity<HLPlatformActivityAttributes>.activityUpdates { if let businessLiveActivityId = activity.attributes.businessLiveActivityId, let liveActivityId = activity.attributes.liveActivityId { Task { var beforeToken = "" for await pushToken in activity.pushTokenUpdates { // here the problem:sometimes pushToken not update to me let pushTokenStr = pushToken.map{String(format: "%02.2hhx", arguments: [$0])}.joined() // avoid send duplication if beforeToken == pushTokenStr { return } beforeToken = pushTokenStr // send pushToken to service } } Task { for await stateUpdate in activity.activityStateUpdates { if stateUpdate == .active { // live activity create } } } } } } }
1
2
159
Jul ’25
How to automatically set the `timestamp` field for Live Activity updates events?
I know for start events, sending the timestamp isn't required. So that's easy. However when I'm testing Live Activity using the Apple Push Notification Console. A lot of times I just need to copy/paste the payload and resend it again. But then the timestamp field needs to get updated each time, because if it's from a time in the past, then it won't trigger. This requires me to have to use an EPOCH converter to find the right time and then copy/paste it. Is there a better solution to this? I know I can use curl, but that is not in the scope of my question.
1
0
63
Jul ’25
Widget Memory Limit - Per Widget Kind/Size or Per Target?
I am building a widget that supports 2 different widget kinds, each supporting systemSmall, systemMedium, and systemLarge size families. My widget does download and display images so I expect memory usage to be on the higher end, but in debugging some memory issues, I notice that when I build my widget scheme to a physical device, things start off reasonable at ~12MB of memory usage. But as I change the widgets intent, add the other widget kind, or add different widget size families, this memory usage grows until it ultimately hits the 30MB cap. My question is, is the 30MB memory limit spread across all my supported widget kinds/sizes? Or does each individual widget get its own 30MB cap? i.e., if I have systemMedium Widget A and systemLarge Widget B, are they sharing that 30MB memory limit?
1
0
89
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
iOS 26 - Widget not updated with respect to main app's system preferred language
Hi, My iOS app's home screen widget content was implemented to base on the preferred language of my main app (e.g. my app has the following preferred language options with this order English, Japanese, Traditional Chinese, Korean, Simplify Chinese). Say the main app is currently using English as their preferred language, I can change the preferred language in the iOS Settings -> Apps -> My App -> Preferred Language. My widget's content will respect to the preferred language option that I selected with only exception if I switch back to English language and my Widget's content won't get updated. The Main app content is always update with respect to the selected preferred language. My app and widget is working without any issue in iOS 18. Other things that I had discovered during my testing under iOS 26, the "first" language appeared in my preferred language always being the issue (e.g. if the first language is Japanese , once I change to other languages and than switch back to Japanese, my widget content won't respect to this but the main app content are ok). Any one has a similar issues regarding the preferred language?
1
0
86
Aug ’25
Live Activity doesn't update as frequently as it should
I'm developing an app which will show the driver ETA and rendering the progress bar of the current ETA. Intuitively the backend server sends the push notification every 3 seconds through firebase cloud message service to APNS so that the device can refresh the dynamic island smoothly. But the live activity doesn't refresh as frequently as the backend service does. It should refresh every 3 seconds but it turns out like refresh 30 ~ 60 seconds, sometimes it didn't refresh at all. any body facing the same?
1
0
62
Aug ’25
Should `input-push-token` be added to all live-activity based payloads?
I'm struggling to understand what the impact of this flag is. Docs only say: For devices running iOS 18 and iPadOS 18 or later, you can add input-push-token: 1 to your payload to start a Live Activity and receive a new push token. After you receive a new push token, you can use it to send updates to a Live Activity. But things were working fine for iOS 17. Right? Does it somehow make the OS emit update tokens faster/more successfully? Should I include in all start, update, end events?
1
0
120
Aug ’25
What is the purpose of the `alert` field for live activities payloads?
Does the alert only serve the following purposes: required for start events require for any event that needs to alert the user (with sound or having the live activity show in expanded presentation) while its content DO NOT matter. Only the presence of the field and its attributes matter. The only time its content matter are when the receiving device is an Apple Watch. Is that correct?
1
0
95
Sep ’25
scenePhase not work consistently on watchOS
Hi there, I'm using WCSession to communicate watchOS companion with its iOS app. Every time watch app becomes "active", it needs to fetch data from iOS app, which works e.g. turning my hand back and forth. But only when the app is opened after it was minimised by pressing digital crown, it didn't fetch data. My assumption is that scenePhase doesn't emit a change on reopen. Here is the ContentView of watch app: import SwiftUI struct ContentView: View { @EnvironmentObject private var iOSAppConnector: IOSAppConnector @Environment(\.scenePhase) private var scenePhase @State private var showOpenCategories = true var body: some View { NavigationStack { VStack { if iOSAppConnector.items.isEmpty { WelcomeView() } else { ScrollView { VStack(spacing: 10) { ForEach(iOSAppConnector.items, id: \.self.name) { item in ItemView(item: item) } } } .task { DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { loadItems() } } .onChange(of: scenePhase, initial: true) { newPhase, _ in if newPhase == .active { loadItems() } } } fileprivate func loadItems() -> Void { if iOSAppConnector.items.isEmpty { iOSAppConnector.loadItems() } } } What could be the issue? Thanks. Best regards Sanjeev
1
0
235
3w