We have an app that supports iOS 18+ We have a couple of AppEntity(s) that we are keen to make work with the new schemas along with several AppIntent(s).
We cannot increase our floor to iOS 27 for obvious reasons.
All the documentation suggests using the macros, e.g.
@AppEntity(schema: .audio.song)
struct SongEntity { ... }
This refuses to compile below iOS 26.
It's possible to add availability checks, e.g.
@available(anyAppleOS 27, *)
@AppEntity(schema: .audio.song)
struct SongEntity { ... }
But then the whole entity becomes unavailable on pre-27 OSes. So I tried moving the macro onto an extension, e.g.
struct SongEntity { ... }
@available(anyAppleOS 27, *)
@AppEntity(schema: .audio.song)
extension SongEntity { ... }
But this results in a compiler error:
'extension' macro cannot be attached to extension (extension of 'SongEntity')
One other option is to create a new entity with a totally different name and mark it as isAssistantOnly but this has a lot of quite negative downstream effects that make it unworkable. For example:
- a lot of code duplication
- duplication in search indexes if we index both sets of entities
- awkwardness trying to use NSUserActivity when we have 2 different entity types
- pain in downstream AppIntent arguments which would require duplicating every AppIntent which has more cascading effects
The same issues are present in AppIntent schemas too where even trying to add the most basic @AppIntent(schema: .system.open) to our existing OpenIntent doesn't seem possible for all the same reasons.
I am really struggling with how to structure code so we can support schemas, currently I don't really see a path forward here until our floor raises to iOS 27.
Is there a way to make this work nicely with the current APIs? What are others doing here? How can apps can ship in September and support both this and pre iOS 27 cleanly?
Thinking about solutions here, my ideal would be that the macros are improved to either:
- be able to be applied to an extension rather than the structure itself.
- expand in such a way that they still build the core AppEntity / AppIntent on pre 27 OSes but then add the iOS 27 schema additions behind
@availableinternally so they can be used with older targets as essentially no-ops on the current definitions.