Using AssistantEntity with existing AppEntities for iOS17+

Hi, I have an existing app with AppEntities defined, that works on iOS17+. The AppEntities also have EntityPropertyQuery defined, so they work as 'find intents'. I want to use the new @AssistantEntity which is iOS18+ where possible, while supporting the previous versions. What's the best way to do this?

For e.g. I have a 'log' AppEntity:

@available(iOS 17.0,  *)
struct CJLogAppEntity: AppEntity {
    
    static var defaultQuery = CJLogAppEntityQuery()
....
}
struct CJLogAppEntityQuery: EntityPropertyQuery {
        ...
}

How do I adopt this with @AssistantEntity(schema: .journal.entry) for iOS18, while maintaining compatibility with iOS17? I don't want to include two different versions of the same AppEntity. Would it just with with the correct @available annotations on both entities?

Answered by Frameworks Engineer in 897421022

Thanks for filing the bug report — we'll take a look. In the meantime, you can work around this macro limitation by creating two versions of your App Intent: one available on iOS 17+ and another available on iOS 27+. I recommend overriding the isAssistantOnly property to true on the iOS 27 version so it's available to Siri AI, while the iOS 17 version remains available to other clients like Shortcuts and the Action Button.

You could add the required properties from the journal.entry schema to your CJLogAppEntity and wrap them around the Property macro. This will allow you to share the same struct between iOS 17 and iOS 18+ while conditionally adding the macro on iOS 18+.

Example:

@available(iOS 17.0,  *)
struct CJLogAppEntity: AppEntity {
        @Property var title: String?
        @Property var message: AttributedString?
        @Property var mediaItems: [IntentFile]
        @Property var entryDate: Date?
        @Property var location: CLPlacemark?
}

@AppEntity(schema: .journal.entry)
@available(iOS 18.0,  *)
extension CJLogAppEntity {}

Note the code above requires you build with the latest SDK while back-deploying it all the way back to iOS 17.

This sample code exhibits the error I mentioned in my comment: 'extension' macro cannot be attached to extension (extension of 'CJLogAppEntity')

import AppIntents
import CoreLocation

@available(iOS 17.0,  *)
struct CJLogAppEntity: AppEntity {
    static var defaultQuery = CJLogEntityQuery()
    let id: String
    static let typeDisplayRepresentation: TypeDisplayRepresentation = "Folder"

    let displayRepresentation: DisplayRepresentation
        @Property var title: String?
        @Property var message: AttributedString?
        @Property var mediaItems: [IntentFile]
        @Property var entryDate: Date?
        @Property var location: CLPlacemark?
}

@AppEntity(schema: .journal.entry)
@available(iOS 18.0,  *)
extension CJLogAppEntity {}

struct CJLogEntityQuery: EntityQuery {
    func entities(for ids: [String]) async throws -> [CJLogAppEntity] {
        return [CJLogAppEntity]()
    }

    func suggestedEntities() async throws -> [CJLogAppEntity] {
        return [CJLogAppEntity]()
    }
}

I also got the same error:

'extension' macro cannot be attached to extension (extension of 'CJLogAppEntity')

Can you please file a bug report using the feedback app?

@Frameworks Engineer here's the ID of the bug report: FB23092038.

Thanks for filing the bug report — we'll take a look. In the meantime, you can work around this macro limitation by creating two versions of your App Intent: one available on iOS 17+ and another available on iOS 27+. I recommend overriding the isAssistantOnly property to true on the iOS 27 version so it's available to Siri AI, while the iOS 17 version remains available to other clients like Shortcuts and the Action Button.

Using AssistantEntity with existing AppEntities for iOS17+
 
 
Q