I am working to add Spotlight indexing for my app entities as discussed in WWDC24's video "What's New in App Intents".
That video goes over the IndexedEntity protocol and the integration with Spotlight via CSSearchableItemAttributeSet.
What I'm seeing though does not match the video. In the video, the presenter goes through the sort of progressive approach you can take to getting this data into Spotlight starting with the basics and then expanding to include more support depending on how much the developer wants to do.
What I'm seeing is that if you conform to IndexedEntity, your entities will appear in Spotlight using the name derived from
public var displayRepresentation: DisplayRepresentation
So, that works. Name appears... BUT the next part of the video goes into how to expand your implementation with more metadata for Spotlight via CSSearchableItemAttributeSet. The issue I'm seeing is that once that's implemented, the items disappear from Spotlight, almost like that implementation is overriding the base implementation in a way that no longer functions.
My expectation is that an item with custom attributes would use them in Spotlight as appropriate, not disappear from search, i.e. what's shown in the video should work.
I've got a sample project here:
https://hanchor.s3.amazonaws.com/misc/IndexingTest.zip
To reproduce with the sample:
Build and run. Indexing is setup in the init() method so it will just run.
Go to Spotlight and search for 'Huntersblau', a string included in the content set. At this point you should see a result - good!
Stop the app and go back and uncomment the var attributeSet: CSSearchableItemAttributeSet implementation in IndexingTestApp.swift. This will provide custom attributes to Spotlight.
Repeat steps 1 and 2 - you'll see now, it no longer appears in the search results - when CSSearchableItemAttributeSet is implemented, the item drops out of Spotlight.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Howdy,
I'm following along with this sample:
https://developer.apple.com/documentation/appintents/making-onscreen-content-available-to-siri-and-apple-intelligence
I've got everything up and building. I can confirm that the userActivity modifier is associating my App Intent via EntityIdentifier but my custom Transferable representation (text) is never being called and when Siri is doing the ChatGPT handoff, it's just offering to send a screenshot which is what it does when it has no custom representation.
What could I doing wrong? Where should I be looking?
Topic:
Machine Learning & AI
SubTopic:
Apple Intelligence
Tags:
Siri and Voice
App Intents
Apple Intelligence
Howdy,Let's say I've got an 'Order' record type and a 'Transaction' record type. Transaction has a reference to order.I have an array of recordNames of orders and I want to get transactions that match any of the orders. Can I do this? I've been having trouble. var orderReferences = [];
orderIdentifiers.forEach(function(orderIdentifier) {
var orderReference = {
recordName: orderIdentifier,
action: "NONE"
};
orderReferences.push(orderReference);
});
var query = {
recordType: "Transaction",
filterBy: [{
fieldName: 'order',
comparator: 'IN',
fieldValue: {
value: orderReferences
}
}]
};(forgive my perhaps terrible JS - it's not a language I use a lot)This doesn't work, I get an error back from the server saying it could not decode my reference (I assume because I'm trying to query with an array of references?)How is this supposed to work?Thanks!
I'm trying to use CreateML to build a model I can use with the new Natural Language framework for domain-specific named entity recognition in scanning some text. It's actually very very similar to the example in the WWDC '18 video introducing the Natural Language Framework where they add a bunch of products and recognize them.The problem I'm having is that the results I'm getting when I run text through an NLTagger with this model are very inaccurate.Imagine an app for people visiting Las Vegas, NV. I want to be able to identify names of hotels, restaurants and other activities as such. I have training data that looks like this (there's a lot more but it all follows this pattern).{"tokens":["Bellagio","Buffet at Bellagio","Fix Restaurant and Bar","Harvest","Jasmine","Lago","Le Cirque","Michael Mina","Noodles","Picasso","Prime","Spago","Yellowtail","Spa \u0026 Salon","Fountains of Bellagio","Gallery of Fine Art","Hyde Lounge","Lily Bar and Lounge","O ","Petrossian Bar"],"labels":["Hotel","Restaurant","Restaurant","Restaurant","Restaurant","Restaurant","Restaurant","Restaurant","Restaurant","Restaurant","Restaurant","Restaurant","Restaurant","Activity","Activity","Activity","Activity","Activity","Activity","Activity"]}Here's a Playground with my test code. With the below, I'd expect 'Bellagio' to come back as 'Hotel' but when I print the tokens and tags, they all come back as... not that. And some times, the same token comes back as two different tags (i.e. 'MGM Grand' below).What am I doing wrong? Bad training data? Bad training data format? Unrealistic expectations? I have no idea what I'm doing?The last one is definitely true.In the WWDC video demo, it seems to work great and it seems very similar to what I'm doing so not sure where I'm off.import CreateML
import Foundation
import NaturalLanguage
let wordFilePath = Bundle.main.path(forResource:"vegas_words", ofType: "json")!
let wordFileURL = URL(fileURLWithPath: wordFilePath)
let trainingData = try MLDataTable(contentsOf: wordFileURL)
let model = try MLWordTagger(trainingData: trainingData, tokenColumn: "tokens", labelColumn: "labels")
let compiledModel = try NLModel(mlModel: model.model)
let text = "When in Las Vegas I like to stay at the luxury hotel Bellagio or perhaps Wynn Las Vegas but not MGM Grand or the Luxor. Sometimes I like to dine at Delmonico at The Venetian or at one of the places at MGM Grand."
let range = text.startIndex..<text.endIndex
var vegasTagScheme = NLTagScheme("Vegas")
var tagger = NLTagger(tagSchemes: [.nameType, vegasTagScheme])
tagger.string = text
tagger.setModels([compiledModel], forTagScheme: vegasTagScheme)
tagger.setLanguage(NLLanguage("en"), range: range)
tagger.enumerateTags(in: range, unit: .word, scheme: vegasTagScheme, options: [.omitWhitespace, .joinNames, .omitPunctuation]) { (tag, tokenRange) -> Bool in
let token = text[tokenRange]
if let tag = tag {
print("\(token): \(tag.rawValue)")
}
return true
}When: Hotel
in: Hotel
Las Vegas: Hotel
I: Restaurant
like: Restaurant
to: Restaurant
stay: Restaurant
at: Restaurant
the: Restaurant
luxury: Restaurant
hotel: Restaurant
Bellagio: Restaurant
or: Restaurant
perhaps: Restaurant
Wynn Las Vegas: Restaurant
but: Restaurant
not: Restaurant
MGM Grand: Restaurant
or: Restaurant
the: Restaurant
Luxor: Restaurant
Sometimes: Activity
I: Activity
like: Activity
to: Activity
dine: Activity
at: Activity
Delmonico: Activity
at: Activity
The: Activity
Venetian: Activity
or: Activity
at: Activity
one: Activity
of: Activity
the: Activity
places: Activity
at: Activity
MGM Grand: Activity
Since running on iOS 14b1, I'm getting this in my log (I have Core Data logging enabled):
error: Store opened without NSPersistentHistoryTrackingKey but previously had been opened with NSPersistentHistoryTrackingKey - Forcing into Read Only mode store at 'file:///private/var/mobile/Containers/Shared/AppGroup/415B75A6-92C3-45FE-BE13-7D48D35909AF/StoreFile.sqlite'
As far as I can tell, it's impossible to open my store without that key set - it's in the init() of my NSPersistentContainer subclass, before anyone calls it to load stores.
Any ideas?
Hi,
New in iOS 17 and the aligned releases is a modifier "toolbarTitleDisplayMode". What does this do exactly?
https://developer.apple.com/documentation/SwiftUI/View/toolbarTitleDisplayMode(_:)
I've experimenting with it a bunch and can't ever see it do really anything so I'm sure I'm using it wrong. What is this for?
I'm using Swift Data for an app that requires iOS 18.
All of my models conform to a protocol that guarantees they have a 'serverID' String variable.
I wrote a function that would allow me to pass in a serverID String and have it fetch the model object that matched. Because I am lazy and don't like writing the same functions over and over, I used a Self reference so that all of my conforming models get this static function.
Imagine my model is called "WhatsNew". Here's some code defining the protocol and the fetching function.
protocol RemotelyFetchable: PersistentModel {
var serverID: String { get }
}
extension WhatsNew: RemotelyFetchable {}
extension RemotelyFetchable {
static func fetchOne(withServerID identifier: String, inContext modelContext: ModelContext) -> Self? {
var fetchDescriptor = FetchDescriptor<Self>()
fetchDescriptor.predicate = #Predicate<Self> { $0.serverID == identifier }
do {
let allModels = try modelContext.fetch(fetchDescriptor)
return allModels.first
} catch {
return nil
}
}
}
Worked great! Or so I thought...
I built this and happily ran a debug build in the Simulator and on devices for months while developing the initial version but when I went to go do a release build for TestFlight, that build reliably crashed on every device with a message like this:
SwiftData/DataUtilities.swift:65: Fatal error: Couldn't find \WhatsNew. on WhatsNew with fields [SwiftData.Schema.PropertyMetadata(name: "serverID", keypath: \WhatsNew., defaultValue: nil, metadata: Optional(Attribute - name: , options: [unique], valueType: Any, defaultValue: nil, hashModifier: nil)), SwiftData.Schema.PropertyMetadata(name: "title", keypath: \WhatsNew., defaultValue: nil, metadata: nil), SwiftData.Schema.PropertyMetadata(name: "bulletPoints", keypath: \WhatsNew.)>, defaultValue: nil, metadata: nil), SwiftData.Schema.PropertyMetadata(name: "dateDescription", keypath: \WhatsNew., defaultValue: nil, metadata: nil), SwiftData.Schema.PropertyMetadata(name: "readAt", keypath: \WhatsNew.)>, defaultValue: nil, metadata: nil)]
It seems (cannot confirm) that something in the release build optimization process is stripping out some metadata / something about these models that makes this predicate crash.
Tested on iOS 18.0 and 18.1 beta.
How can I resolve this? I have two dozen types that conform to this protocol. I could manually specialize this function for every type myself but... ugh.
The new Core Spotlight APIs in 18.4 and aligned releases for using Apple Intelligence models to summarize messages sort of work? But I'd say in my testing that only about 80% of the requests I send to Spotlight come back to the delegate with summaries and the rest are never returned. No errors logged in the delegate methods.
I can't figure out if there's a pattern. Before I dig apart my code, I'm wondering if anyone else here is using these brand-new APIs and has seen anything similar.
It's odd because my code to submit to Spotlight to be summarized is the same for all of my entities but some just never seem to be returned.
Sorry for the cross-post but it's now two days in and this isn't fixed.
If you try to use Xcode 16.3b3 with visionOS, it won't download the visionOS SDK, gives a 'network error' so you can't use the latest beta for Apple Vision Pro.
FB16927025
FB16917874
FB16910449
Hi,
Are there rules around using Foundation Models:
In a background task/session?
Concurrently, i.e. a bunch simultaneously using Swift Concurrency?
I couldn't find this in the docs (sorry if I missed it) so wondering what's supported and what the best practice is here.
In case it matters, my primary platform is Vision Pro (so, M2).
Seeing this error from time to time:
Context(debugDescription: "Content contains 4089 tokens, which exceeds the maximum allowed context size of 4096.", underlyingErrors: [])
Of course, 4089 is less than 4096 so what is this telling me and how do I work around it? Is the limit actually lower than 4096?
Topic:
Machine Learning & AI
SubTopic:
Foundation Models
FB9509674
"Failed to start remote service "com.apple.debugserver" on device"
Anyone seeing the above error trying to debug apps on the device? The app does get installed but the debug session does not start and instead this error pops up.
I've tried rebooting both the Mac and the device but no luck.
Mac is M1 MBP device is iPhone 12 Pro.
I'm trying to use SwiftData for a new app after ~20 years of Core Data (and EOF before that). So while I'm new to SwiftData, I'm not new to Apple persistence frameworks.
I've got a pretty typical workflow - need to load some JSON from the network, convert that into model objects.
I've created an actor using the @ModelActor macro and I'm using that to do the network fetch and insert. I can set breakpoints in this code and see that it does indeed run and it's running on a non-main queue. That all seems fine.
The problem is that my @Query powered variable in my SwiftUI user interface does not get updated when this data is loaded and saved as I would expect it to.
I'm passing in the container to the actor using modelContext.container from the same modelContext that is powering the view / in the environment. My understanding was that like Core Data before it, the SwiftData framework was listening for the relevant notifications passed by the container/context, processing those and updating the UI but I can only see my data if I quit and relaunch the app.
This seems like it should be a very common use case but I've not found much online. Not sure if that means I'm just doing something fundamentally wrong or what.
Tested on both iOS 18 and 17 with the same results.
Anyone else doing this successfully? What could I be doing wrong?
I am working on adding indexing to my App Entities via IndexedEntity. I already, separately index my content via Spotlight.
Watching 'What's New in App Intents', this is covered well but I have a question.
Do I need to implement both CSSearchableItem's associateAppEntity AND also a custom implementation of attributeSet in my IndexedEntity conformance? It seems duplicative but I can't tell from the video if you're supposed to do both or just one or the other.
Hi,
With iOS 15 we can now update the nsPredicate and nsSortDescriptors properties on a @FetchRequest which is great.
What I'm wondering though is the correct way to apply/re-apply user data stored in @State and/or @SceneStorage for predicates when a view is init'd.
Something like @SceneStorage isn't available in the init method but I find that onAppear isn't called in some circumstances.
For example, let's say I have a picker that drives the NSPredicate and the user picks a non-default value. If the app goes into the background and then back to the foreground and that same view is visible, it looks like SwiftUI re-runs the init for the view but does not re-run the onAppear modifier, leaving my UI in an inconsistent state.
What's the right way to handle this? Feels like I must be fighting the framework / there must be a better way.