When I set Alarm with fixed schedule(Alarm.Schedule.fixed(date))
LiveActivityIntent just work inconsistently
it sometimes call perfrom but cannot call other's
such as NotificationCenter.default.post
it just work fine with relativeSchedule but not for fixed schedule
i want to know why it happen
tested code is under below
struct StopIntent: LiveActivityIntent {
static var supportedModes: IntentModes = [.foreground(.immediate)]
func perform() throws -> some IntentResult {
guard let id = UUID(uuidString: alarmID) else {
NotificationCenter.default.post(name: .Alarm.stoped, object: alarmDataString)
throw TestAlarmManager._Error.badAlarmID
}
Task { @MainActor in
try TestAlarmManager.shared.stopAlarm(id)
NotificationCenter.default.post(name: .Alarm.stoped, object: alarmDataString)
}
return .result()
}
static var title: LocalizedStringResource = "Stop"
static var description = IntentDescription("Stop an alert")
@Parameter(title: "alarmID")
var alarmID: String
@Parameter(title: "alarmDataString")
var alarmDataString: String
init(alarmID: UUID, alarmDataString: String) {
self.alarmID = alarmID.uuidString
self.alarmDataString = alarmDataString
}
init() {
self.alarmID = ""
self.alarmDataString = ""
}
}
Widgets & Live Activities
RSS for tagDiscuss how to manage and implement Widgets & Live Activities.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I don't see any where how to make my payment
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
For our Live Activity Tokens, when we fire a payload, often apns is returning a response of 410 unregistered.
Docs are saying:
The device token is inactive for the specified topic. There is no need to send further pushes to the same device token, unless your application retrieves the same device token, refer to Registering your app with APNs
Questions:
Why does this happen? Does it only happen because the user changed their permission? Or there are other reasons?
And when it does happen, what should we do about it?
A. Should we keep the token on the server? Because perhaps the user will change their permission and the token becomes valid? That could leave us with lots of invalid tokens and us firing at them unnecessarily.
Docs do say:
Don’t retry notification responses with the error code BadDeviceToken, DeviceTokenNotForTopic, Forbidden, ExpiredToken, Unregistered, or PayloadTooLarge.
B. Or should we remove the token from the server? That then requires app to re-register the token. But the problem with that is:
When I went into App's settings from OS settings and toggled push notifications to on, the app was not launched into the background nor killed i.e. it requires explicit app launch by the user to re-register itself which isn't ideal...
It means a user may turn on notifications from the OS settings and then assume that their push notifications should be back in business, but that won't happen if you toggle things from OS settings.
Hello,
Users are reporting that widgets in my iOS app running on Mac OS are starting to crash after updating to MacOS 26.1.
Everything works fine on iOS 26.1 and MacOS 15.6.
The same bugs I found in iOS 26 beta 4, but then Apple fixed them in iOS 26RC and now they're back in macOS.
Any suggestions?
Crash report:
Process: WidgetWebWidgetExt [23580]
Path: /Volumes/VOLUME/*/WidgetWeb.app/PlugIns/WidgetWebWidgetExt.appex/WidgetWebWidgetExt
Identifier: app.vitalek.widgetapp.web.WidgetWebExt
Version: 7.5 (5796)
AppVariant: 1:MacFamily20,1:18
Code Type: ARM-64 (Native)
Role: unknown
Parent Process: launchd [1]
Coalition: app.vitalek.widgetapp.web.WidgetWebExt [28539]
User ID: 501
Date/Time: 2025-11-04 11:47:19.0746 -0500
Launch Time: 2025-11-04 11:47:18.8035 -0500
Hardware Model: Mac14,6
OS Version: macOS 26.1 (25B78)
Release Type: User
Crash Reporter Key: 39D39455-7F69-746C-2A1D-7A6086F25541
Incident Identifier: 7AC31574-73A4-4320-B17A-C2819252EEDA
Sleep/Wake UUID: 1535756C-44D8-497F-A288-07E53CD9B9E4
Time Awake Since Boot: 18000 seconds
Time Since Wake: 7417 seconds
System Integrity Protection: enabled
Triggered by Thread: 0, Dispatch Queue: com.apple.main-thread
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Termination Reason: Namespace SIGNAL, Code 6, Abort trap: 6
Terminating Process: WidgetWebWidgetExt [23580]
Application Specific Information:
abort() called
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x1926e75b0 __pthread_kill + 8
1 libsystem_pthread.dylib 0x192721888 pthread_kill + 296
2 libsystem_c.dylib 0x192626850 abort + 124
3 libc++abi.dylib 0x1926d5858 __abort_message + 132
4 libc++abi.dylib 0x1926c44d4 demangling_terminate_handler() + 304
5 libobjc.A.dylib 0x1922f0414 _objc_terminate() + 156
6 libc++abi.dylib 0x1926d4c2c std::__terminate(void (*)()) + 16
7 libc++abi.dylib 0x1926d8394 __cxxabiv1::failed_throw(__cxxabiv1::__cxa_exception*) + 88
8 libc++abi.dylib 0x1926d833c __cxa_throw + 92
9 libobjc.A.dylib 0x1922e6580 objc_exception_throw + 448
10 Foundation 0x19495122c -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 288
11 UIKitMacHelper 0x1b0240c80 -[UINSApplicationDelegate init] + 1348
12 UIKitMacHelper 0x1b02406d8 __41+[UINSApplicationDelegate sharedDelegate]_block_invoke + 48
13 libdispatch.dylib 0x19257eac4 _dispatch_client_callout + 16
14 libdispatch.dylib 0x192567a60 _dispatch_once_callout + 32
15 UIKitMacHelper 0x1b02405dc +[UINSApplicationDelegate sharedDelegate] + 324
16 UIKitCore 0x1ca488518 -[UIScene setTitle:] + 188
17 UIKitCore 0x1ca487e90 -[UIScene initWithSession:connectionOptions:] + 1084
18 UIKitCore 0x1cb2a6a54 -[UIWindowScene initWithSession:connectionOptions:] + 92
19 UIKitCore 0x1ca66b44c -[_UIScreenBasedWindowScene initWithScreen:session:lookupKey:] + 292
20 UIKitCore 0x1ca66aff4 +[_UIScreenBasedWindowScene _unassociatedWindowSceneForScreen:create:] + 408
21 UIKitCore 0x1cb09171c -[UIWindow _uiWindowSceneFromFBSScene:] + 704
22 UIKitCore 0x1cb0918cc -[UIWindow _initWithFrame:debugName:scene:attached:] + 92
23 UIKitCore 0x1cb091e68 -[UIWindow _initWithOrientation:] + 56
24 UIKitCore 0x1cb091ebc -[UIWindow init] + 72
25 WidgetWebWidgetExt 0x1027eb250 0x102718000 + 864848
26 WidgetWebWidgetExt 0x1027ea418 0x102718000 + 861208
27 WidgetWebWidgetExt 0x1027f5bc8 0x102718000 + 908232
28 WidgetWebWidgetExt 0x1027f4bfc 0x102718000 + 904188
29 WidgetWebWidgetExt 0x1027cf9f4 0x102718000 + 752116
30 WidgetWebWidgetExt 0x102807c20 0x102718000 + 982048
31 libdispatch.dylib 0x19257eac4 _dispatch_client_callout + 16
32 libdispatch.dylib 0x1925696e4 _dispatch_continuation_pop + 596
33 libdispatch.dylib 0x19257c800 _dispatch_source_latch_and_call + 396
34 libdispatch.dylib 0x19257b4d4 _dispatch_source_invoke + 844
35 libdispatch.dylib 0x19259c008 _dispatch_main_queue_drain.cold.5 + 592
36 libdispatch.dylib 0x192573f48 _dispatch_main_queue_drain + 180
37 libdispatch.dylib 0x192573e84 _dispatch_main_queue_callback_4CF + 44
38 CoreFoundation 0x1927ea980 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16
39 CoreFoundation 0x1927bf7dc __CFRunLoopRun + 1944
40 CoreFoundation 0x19287935c _CFRunLoopRunSpecificWithOptions + 532
41 Foundation 0x194a06890 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 212
42 Foundation 0x194005a50 -[NSRunLoop(NSRunLoop) run] + 64
43 libxpc.dylib 0x19240ce14 _xpc_objc_main + 668
44 libxpc.dylib 0x19241ecf8 _xpc_main + 40
45 libxpc.dylib 0x19241ecd0 xpc_bs_main + 16
46 BoardServices 0x1ac51179c +[BSServicesConfiguration activateXPCService] + 72
47 ExtensionFoundation 0x237a92710 _EXRunningExtension.resume() + 1592
48 ExtensionFoundation 0x237a911a8 _EXRunningExtension.start(withArguments:count:) + 124
49 ExtensionFoundation 0x237a88f24 EXExtensionMain(_:_:) + 668
50 Foundation 0x1940065ec NSExtensionMain + 200
51 dyld 0x192359d54 start + 7184
I want to refresh the content in the stacked component in watch, but when I call WidgetCenter.shared.reloadTimelines to update, there is no guarantee that the content in the component can be refreshed in real time every time. Is this expected? Is there any other way to refresh in real time?
Hi everyone,
I’m seeing a blank Live Activity in my app after the alarm fires. Has anyone encountered this before or knows how to fix it? Any guidance would be greatly appreciated.
At the top of the screen, there’s a blank Live Activity:
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
(I truly appreciate all the responses you all have written for me :bow: )
I was under the assumption that for Live Activity, in order for you to be able to update the Activity, you need an update token. And for the OS to issue you the update token, user must hit the "Allow" from the lock screen.
However based on these screenshots it seems that you don't need to hit "Allow" to be able to update the Live Activity.
Live Activity was updated — even without the user hitting "Allow"
So now I'm wondering if:
Is hitting Allow required for the update token to get issued? Or that assumption is incorrect? In our tests (when connected to Proxyman, the OS emits the update token after user hits "Allow" / "Always Allow")
If you don't hit allow, are there alternate ways to update the Live Activity without having the update token?
I'm guessing you could set a short stale time and then when the OS launches the app in the background you query the server and then update the Live Activity. Is that a worthy approach?
I also noticed that the "The Philly Inquirer" App has 'Background App Refresh" enabled, but this happened in 2 minutes. In our architecture assessments, after reviewing Apple's docs on 'Background Processing", we didn't think of it as a viable option, because it can't guarantee if the OS is given time in the next 2 minutes or 10 hours later when the phone is getting charged again.
Are any of these workarounds viable or are there alternate approaches?
Our requirement is:
be able to use Live Activity between 2-72hrs after app install. (I mention this because perhaps Apple may impost some restrictions for new installs)
be able to update an active Live Activity within 1-2 minutes after it has began.
We are using the MPNowPlayingInfoCenter API to provide information to the “Now Playing” system UI. This works as expected, except that when the app is manually terminated, the information is removed from the UI.
Our question is: Some apps (for example, Audible) are able to appear in the “Recently Played” section of the UI. This section seems to show a history of apps that previously provided “Now Playing” information but are not currently playing anything.
We would like to know which API is used to achieve this behavior.
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Hi,
We design a Live Activity for our app.We find that in iOS26 system, the widget can not display the correct system display model(Light mode or dark mode), always display with dark mode. When our app run in other system ,such as iOS 17, iOS18 ,it work fine.
I find other developer had post a topic three month ago , but it seems there is not any new response about the feedback.
https://developer.apple.com/forums/thread/799684?answerId=857377022#857377022
Anyone have idea?
Thanks .
Below is my code template:
struct BroadcastLiveActivityBackgroundView: View {
@Environment(\.colorScheme) var colorScheme: ColorScheme
var body:some View {
LinearGradient(
stops: [
Gradient.Stop(color: LiveActivityColor.backgroundColors(self.colorScheme).last!, location: 0.00),
Gradient.Stop(color: LiveActivityColor.backgroundColors(self.colorScheme).first!, location: 1.00),
],
startPoint: UnitPoint(x: 1, y: 0),
endPoint: UnitPoint(x: 0.82, y: 1.11)
)
}
}
I want to make a app that indicates that the app is recording in the background using a indicator on the dynamic island or on the top of the phone screen but i can't figure it out on Xcode. Saw a guy do it by making live activities true but can't seem to find that option in background mode in capabilities. any ideas?
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Subject: Request to maintain the "Status Bar Breadcrumb" visibility while Dynamic Island is active
Hi,
I am developing an app using ActivityKit and Dynamic Island. I've noticed a significant UX regression regarding the system status bar behavior.
Current Behavior: When a Live Activity is active in the Dynamic Island (specifically in the compactLeading and compactTrailing presentation), the system automatically hides the "Back to [Previous App]" breadcrumb button (the small arrow and app name) in the top-left corner of the status bar.
This breadcrumb only reappears when the Live Activity switches to the minimal presentation or is dismissed.
The Issue: This behavior makes multitasking cumbersome for users. For example, if a user navigates from Safari to my app and then locks the screen or goes to Home, they expect the "Back to Safari" button to remain accessible. However, because my app's Live Activity is running in the Dynamic Island, the OS removes this navigation shortcut, forcing users to use the app switcher instead.
Why this should be changed:
Screen Real Estate: On larger devices (e.g., iPhone 15/16 Pro Max), there is significant whitespace in the top-left corner between the time and the Dynamic Island's leading edge. The breadcrumb could easily fit there without overlapping the Live Activity content.
Inconsistent UX: Users are confused why the navigation button disappears solely because a background activity is running.
Request: Please consider updating the status bar layout logic to allow the "Back to App" breadcrumb to remain visible if there is no physical overlap with the compactLeading view of the Dynamic Island.
Thank you.
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Since watchOS 26, watch face sharing has stopped working completely.
I tested the following:
Sharing via CLKWatchFaceLibrary
Other public APIs
Sharing via iMessage
In all cases, the watch face cannot be reinstalled after being shared.
This issue is not limited to my app. Large third-party apps such as Facer and other major watch face platforms are also affected, which suggests this is a system-level change or bug.
Everything worked correctly before watchOS 26.
Has Apple officially acknowledged this issue?
Is there a recommended place to report or track this bug?
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Tags:
Face Sharing
watchOS
Watch Complications
WidgetKit
Issue Description:
Tapping the app widget sometimes triggers the Universal Link twice, causing duplicate navigation or actions within the app
Steps to Reproduce:
Add the app widget to the home screen
Tap the widget to open the app via the Universal Link
Observe that the Universal Link is sometimes fired twice
Expected Behavior:
Tapping the widget should trigger the Universal Link only once.
Actual Behavior:
Universal Link is triggered twice, causing duplicate
navigation or actions.
Some of the users of my app reported that, the widgets cannot be loaded, event after restarts and re-installs. It seems that it is not rare, I have tens of reports on this (and probably much more who didn't report).
It seems the widget is blank even on the gallery screen while you are first adding it:
struct SingleWidgetProvider: AppIntentTimelineProvider {
@Environment(\.widgetFamily) var family
private let viewModel: WidgetViewModel = WidgetViewModel()
func placeholder(in context: Context) -> SingleEntry {
SingleEntry(date: Date(), habit: .singleSample)
}
func snapshot(for configuration: SingleWidgetConfigurationIntent, in context: Context) async -> SingleEntry {
guard let habit = Array(PersistenceManager.shared.retrieveHabitList().habits).first else {
return SingleEntry(date: Date(), habit: .singleSample)
}
let displayable = viewModel.displayableFromHabit(habit, separateComponents: true, secondOffset: 0)
return SingleEntry(date: Date(), habit: displayable)
}
func timeline(for configuration: SingleWidgetConfigurationIntent, in context: Context) async -> Timeline<SingleEntry> {
var entries: [SingleEntry] = []
guard let counter = configuration.currentCounter else {
return Timeline(entries: [SingleEntry(date: Date(), habit: .singleSample)], policy: .atEnd)
}
guard let habit = PersistenceManager.shared.retrieveHabit(habitKey: counter.id) else {
return Timeline(entries: [SingleEntry(date: Date(), habit: .singleSample)], policy: .atEnd)
}
let currentDate = Date()
for secondOffset in 0 ..< 100 {
let displayable = viewModel.displayableFromHabit(
habit,
separateComponents: true,
secondOffset: secondOffset,
symbolName: habit.habitSymbol?.name ?? "",
overrideColor: configuration.currentColor.color,
overrideButtonVisibility: configuration.currentButtonVisibility,
overrideDisplayOption: configuration.currentDisplayOption
)
let entryDate = Calendar.current.date(byAdding: .second,
value: secondOffset,
to: currentDate)!
let entry = SingleEntry(date: entryDate, habit: displayable)
entries.append(entry)
}
return Timeline(entries: entries, policy: .atEnd)
}
}
struct SingleEntry: TimelineEntry {
let date: Date
let habit: HabitDisplayable
}
static var singleSample: HabitDisplayable {
return HabitDisplayable(habitKey: nil,
title: LS("sampleWidgetHabitTitle"),
dates: [Date(timeIntervalSince1970: 1507158360)],
displayOption: .dayMonthYear,
secondOffset: 0,
separateComponents: true)
}
func displayableFromHabit(
_ habit: Habit,
separateComponents: Bool,
secondOffset: Int,
symbolName: String = "",
overrideColor: Color? = nil,
overrideButtonVisibility: WidgetButtonVisibility? = nil,
overrideDisplayOption: WidgetDisplayOption? = nil
) -> HabitDisplayable {
let latestDates: [HabitDate]
let displayOption: DisplayOption
if let overrideDisplayOption {
if overrideDisplayOption == .sameAsCounter {
displayOption = habit.settings?.toValue.displayOption ?? .dayMonthYear
} else {
displayOption = DisplayOption(rawValue: overrideDisplayOption.rawValue - 1) ?? .dayMonthYear
}
} else {
displayOption = habit.settings?.toValue.displayOption ?? .dayMonthYear
}
let displayMode = displayOption.mode
switch displayMode {
case .timePassed, .date:
latestDates = PersistenceManager.shared.latestDate(habit: habit).map { [$0] } ?? []
case .activity:
latestDates = PersistenceManager.shared.retrieveHabitDates(habit: habit, limitDate: displayOption.limitDate())
}
let displayButton: Bool
if let overrideButtonVisibility {
if overrideButtonVisibility == .sameAsCounter {
displayButton = habit.settings?.toValue.buttonType == .onRow
} else {
displayButton = overrideButtonVisibility == .show
}
} else {
displayButton = false
}
return HabitDisplayable(
habitKey: habit.habitKey,
title: habit.title,
dates: latestDates.map { $0.date },
displayOption: displayOption,
secondOffset: secondOffset,
separateComponents: separateComponents,
color: overrideColor ?? habit.habitColor?.color ?? .appPrimary,
symbolName: symbolName,
displayButton: displayButton
)
}
I provided a large portion of my code, let me know if you need more. The strange thing here is, even if the DB connection is broken somehow, it should have shown the default option (singleSample).
I am not able to reproduce/fix this for months now, so any help is very appreciated.
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
I am building a widget with configurable options (dynamic option) where the options are pull from api (ultimately the options are return from a server, but during my development, the response is constructed on the fly from locally).
Right now, I am able to display the widget and able to pull out the widget configuration screen where I can choose my config option . I am constantly having an issue where the loading the available options when selected a particular option (e.g. Category) and display them on the UI. Sometime, when I tap on the option "Category" and the loading indicator keeps spinning for while before it can populate the list of topics (return from methods in NewsCategoryQuery struct via fetchCategoriesFromAPI ). Notice that I already made my fetchCategoriesFromAPI call to return the result on the fly and however the widget configuration UI stills take a very long time to display the result. Even worst, the loading (loading indicator keep spinning) sometime will just kill itself after a while and my guess there are some time threshold where the widget extension or app intent is allow to run, not sure on this?
My questions:
How can I improve the loading time to populate the dynamic options in widget configuration via App Intent
Here is my sample code for my current setup
struct NewsFeedConfigurationIntent: AppIntent, WidgetConfigurationIntent {
static let title: LocalizedStringResource = "Configure News Topic Options"
static let description = IntentDescription("Select a topic for your news.")
@Parameter(title: "Category", default: nil)
var category: NewsCategory?
}
struct NewsCategory: AppEntity, Identifiable {
let id: String
let code: String
let name: String
static let typeDisplayRepresentation: TypeDisplayRepresentation = "News Topic"
static let defaultQuery = NewsCategoryQuery()
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: LocalizedStringResource(stringLiteral: name))
}
}
struct NewsCategoryQuery: EntityQuery {
func entities(for identifiers: [NewsCategory.ID]) async throws -> [NewsCategory] {
let categories = fetchCategoriesFromAPI()
return categories.filter { identifiers.contains($0.id) }
}
func suggestedEntities() async throws -> [NewsCategory] {
fetchCategoriesFromAPI()
}
}
func fetchCategoriesFromAPI() -> [NewsCategory] {
let list = [
"TopicA",
"TopicB",
"TopicC",
.......
]
return list.map { item in
NewsCategory(id: item, code: item, name: item.capitalized)
}
}
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Tags:
WidgetKit
Intents
App Intents
Hello everyone,
I am currently developing a media playback app and want to achieve the following functionality:
Display multiple media contents in the Now Playing control center, instead of just showing the currently playing one.
Allow users to select and switch between different contents, such as videos, music, etc., from the control center.
However, I have encountered some issues:
Although I have integrated the Now Playing control center, it only displays the current media being played.
I would like to display multiple selectable media contents (such as a video list, music list, etc.) in the control center, similar to what is done by some media player apps, and allow users to switch between them.
I’ve tried the following methods:
Using MPNowPlayingInfoCenter to update the current playing media information.
Attempting to set MPNowPlayingInfoPropertyPlaybackQueueCount to show multiple items in the queue, but it doesn’t seem to work.
Can anyone provide guidance on how to display multiple media contents in the Now Playing control center? Any experienced developers who could share their insights or suggestions would be greatly appreciated!
Thank you very much for your help and feedback!
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Hi everyone,
I'm working with Live Activities using the ActivityKit(Activity), and I'm trying to find a way to detect when a user manually dismisses a Live Activity by swiping it away — either from the Lock Screen or the Dynamic Island.
Currently, when a Live Activity ends, the activityState changes to .dismissed, which is defined as:
/// The Live Activity ended and is no longer visible because a person or the system removed it.
case dismissed
This doesn’t allow me to determine whether the dismissal was triggered by the user or by the system.
Is there any way — either through ActivityState, notifications, or another approach — to distinguish if a Live Activity was manually dismissed by the user vs. ended by the system?
Thanks in advance!
Is there any way to obtain the ControlWidget installed by user, I use WidgetCenter.shared.getCurrentConfigurations cannot work
Hello,
I am trying to get the elements from my SwiftData databse in the configuration for my widget.
The SwiftData model is the following one:
@Model
class CountdownEvent {
@Attribute(.unique) var id: UUID
var title: String
var date: Date
@Attribute(.externalStorage) var image: Data
init(id: UUID, title: String, date: Date, image: Data) {
self.id = id
self.title = title
self.date = date
self.image = image
}
}
And, so far, I have tried the following thing:
AppIntent.swift
struct ConfigurationAppIntent: WidgetConfigurationIntent {
static var title: LocalizedStringResource { "Configuration" }
static var description: IntentDescription { "This is an example widget." }
// An example configurable parameter.
@Parameter(title: "Countdown")
var countdown: CountdownEntity?
}
Countdowns.swift, this is the file with the widget view
struct Provider: AppIntentTimelineProvider {
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(), configuration: ConfigurationAppIntent())
}
func snapshot(for configuration: ConfigurationAppIntent, in context: Context) async -> SimpleEntry {
SimpleEntry(date: Date(), configuration: configuration)
}
func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline<SimpleEntry> {
var entries: [SimpleEntry] = []
// Generate a timeline consisting of five entries an hour apart, starting from the current date.
let currentDate = Date()
for hourOffset in 0 ..< 5 {
let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
let entry = SimpleEntry(date: entryDate, configuration: configuration)
entries.append(entry)
}
return Timeline(entries: entries, policy: .atEnd)
}
// func relevances() async -> WidgetRelevances<ConfigurationAppIntent> {
// // Generate a list containing the contexts this widget is relevant in.
// }
}
struct SimpleEntry: TimelineEntry {
let date: Date
let configuration: ConfigurationAppIntent
}
struct CountdownsEntryView : View {
var entry: Provider.Entry
var body: some View {
VStack {
Text("Time:")
Text(entry.date, style: .time)
Text("Title:")
Text(entry.configuration.countdown?.title ?? "Default")
}
}
}
struct Countdowns: Widget {
let kind: String = "Countdowns"
var body: some WidgetConfiguration {
AppIntentConfiguration(kind: kind, intent: ConfigurationAppIntent.self, provider: Provider()) { entry in
CountdownsEntryView(entry: entry)
.containerBackground(.fill.tertiary, for: .widget)
}
}
}
CountdownEntity.swift, the file for the AppEntity and EntityQuery structs
struct CountdownEntity: AppEntity, Identifiable {
var id: UUID
var title: String
var date: Date
var image: Data
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: "\(title)")
}
static var defaultQuery = CountdownQuery()
static var typeDisplayRepresentation: TypeDisplayRepresentation = "Countdown"
init(id: UUID, title: String, date: Date, image: Data) {
self.id = id
self.title = title
self.date = date
self.image = image
}
init(id: UUID, title: String, date: Date) {
self.id = id
self.title = title
self.date = date
self.image = Data()
}
init(countdown: CountdownEvent) {
self.id = countdown.id
self.title = countdown.title
self.date = countdown.date
self.image = countdown.image
}
}
struct CountdownQuery: EntityQuery {
typealias Entity = CountdownEntity
static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Countdown Event")
static var defaultQuery = CountdownQuery()
@Environment(\.modelContext) private var modelContext // Warning here: Stored property '_modelContext' of 'Sendable'-conforming struct 'CountdownQuery' has non-sendable type 'Environment<ModelContext>'; this is an error in the Swift 6 language mode
func entities(for identifiers: [UUID]) async throws -> [CountdownEntity] {
let countdownEvents = getAllEvents(modelContext: modelContext)
return countdownEvents.map { event in
return CountdownEntity(id: event.id, title: event.title, date: event.date, image: event.image)
}
}
func suggestedEntities() async throws -> [CountdownEntity] {
// Return some suggested entities or an empty array
return []
}
}
CountdownsManager.swift, this one just has the function that gets the array of countdowns
func getAllEvents(modelContext: ModelContext) -> [CountdownEvent] {
let descriptor = FetchDescriptor<CountdownEvent>()
do {
let allEvents = try modelContext.fetch(descriptor)
return allEvents
}
catch {
print("Error fetching events: \(error)")
return []
}
}
I have installed it in my phone and when I try to edit the widget, it doesn't show me any of the elements I have created in the app, just a loading dropdown for half a second:
What am I missing here?
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Tags:
SwiftUI
WidgetKit
App Intents
SwiftData
I found the live activity process cannot write to the app group and FileManger, can only read the app group.
When I write using FileManager in a live activity process, the console prompts me with a permission error.
When I write using UserDefault(suit:) in the live activity process, I read a null value in the main app.
Is this the case for real-time event design? I haven’t seen any documentation mentioning this.
Does anyone know, thank you very much.