Post

Replies

Boosts

Views

Activity

Shortcuts: Invalid action metadata
I have a habit tracker app that uses App Intents and Shortcuts. The app uses SwiftData to persist data, just in case that's important. One of the shortcuts serves to log habits. However, when the app has been in the background for a good while (over an hour or so), that particular shortcut always fails when I try to run it in the Shortcuts app with the system error "Invalid action metadata" caused by "a bug in the host app". The app has a total of 9 shortcuts, and it's just this one particular shortcut that seems to be failing – the others continue to run without any issues even after the app has been in the background for a long time. The app intent/shortcut that is problematic is the one called HabitEntryAppIntent. For example purposes, I've also included one of the non-problematic intents in the code snippet below called HabitEntryCounterForTodayAppIntent. Both of these intents have one @Parameter value of type HabitEntity. I'll post code snippets in the replies because the character limit is not large enough to include them here, or view them in this GitHub gist: Code snippets on GitHub I've tried everything I can think of whilst debugging, but none of the following fixed the error: Removed all usage of @MainActor and mainContext by replacing the ModelContext used in perform() with a locally created property. Removed all usage of static shared properties like Calendar.shared and ModelContainer.shared and replaced them with local properties. Removed all non-essential code such as the code for context.undoManager and WidgetManager.shared.reload(.all) and really striped it all down to the absolute essentials. Reduced the number of shortcut phrases in the problematic shortcut because there was perhaps too many (>10) originally. You might have noticed that the perform() method in the problematic intent manipulates the database whilst the non-problematic intent only reads the database. Given that the two intents in the snippet above both have the same @Property(...) var habitEntity: HabitEntity values, I tried to swap the contents of the perform() methods over to see what would happen. And here's what's strange: When the perform() method from the problematic HabitEntryAppIntent is used in HabitEntryCounterForTodayAppIntent, it works without any issues and successfully logs habits! And then when the perform() method from the non-problematic HabitEntryCounterForTodayAppIntent is used in HabitEntryAppIntent it fails with the system error "Invalid action metadata". This suggests that the problem is not in the code that logs the habit entries but rather something is wrong with HabitEntryAppIntent itself. I also tried changing the metadata used in HabitEntryAppIntent and its shortcut. I copied all the metadata used in HabitEntryCounterForTodayAppIntent (the title, description, parameterSummary etc) and pasted it into HabitEntryAppIntent. And did the same with the metadata in the shortcut (phrases, shortTitle etc) so that all the metadata used in HabitEntryAppIntent matched that used in HabitEntryCounterForTodayAppIntent. However, the shortcut for HabitEntryAppIntent continued to fail. Thus, it doesn't seem to be an issue with the code in perform() because that code succeeds when used in another app intent. And, despite the "metadata" error message, it doesn't seem to be an issue with the metadata in the app intent because I've tried using metadata from the non-problematic intent but it still fails. I have watched all WWDC videos related to app intents and shortcuts, and looked through the developer forum for similar questions, but I'm completely stumped by this issue and why it's only affecting one of my shortcuts. Also worth mentioning is that the widgets in the app that log habits using the same app intent do not suffer the same issue; they continue to work even after the Shortcut has failed. Moreover, if I try running the problematic shortcut for HabitEntryAppIntent and see the system error message, then run the shortcut for HabitEntryCounterForTodayAppIntent (which always succeeds), and then try running the HabitEntryAppIntent shortcut again, it then runs successfully on the second attempt. It seems that running HabitEntryCounterForTodayAppIntent fixes the issue, at least temporarily.
2
0
108
May ’25
Set 12 vs 24 hour with the new date formatting API in iOS 15
Using the new date formatting API available in iOS 15, I would like to respect the 12 vs 24 hour setting on a user-by-user basis. With DateFormatter it can be done as follows, for example, to force a 24 hour time irrespective of the user locale. let formatter = DateFormatter() formatter.dateFormat = "HH:mm" // or hh:mm for 12 h However, I cannot figure out how to force the new date formatting API in iOS 15 to do the same thing, i.e. force displaying 12 vs 24 h. I'm using a format style like this: var formatStyle = dateTime formatStyle.calendar = calendar if let timeZone = timeZone { formatStyle.timeZone = timeZone } return formatStyle And applying it like this, for example, for a given Date instance: date.formatted(formatStyle.hour(.defaultDigits(amPM: .abbreviated))) However, this seems to always give a formatted string relevant to the locale, for example, it's always 12h for the US and always 24h for the UK. This is not the behaviour I really need though, and I'd like to allow each individual user to control what they see irrespective of the locale setting. (Note that there is an in-app setting that allows the user to toggle between the 12 and 24 hour preference, which is the value I'd like to use to set the preference.)
7
0
11k
Mar ’22
Set time zones with the new date formatting API in iOS 15
I would like to update some code that uses DateFormatter, for example, code like this: let date = Date() let formatter = DateFormatter() formatter.dateStyle = .medium formatter.timeStyle = .short formatter.timeZone = TimeZone(identifier: "Europe/London") formatter.string(from: date) With the new date formatting API available in iOS 15, date formatting can be achieved by calling the formatted() method on the date directly, without explicitly requiring a DateFormatter instance, for example: date.formatted(.dateTime.year().month().day().hour().minute()) However, using this new API, I cannot find any way to set the time zone, i.e., the equivalent of the line formatter.timeZone = TimeZone(identifier: "Europe/London"). I'm aware that time zone can be used to format the output, for example date.formatted(.dateTime.timeZone()), but this does not allow one to actually set the time zone. Does anyone know if it is possible?
4
0
8.2k
Feb ’22