I am using NSUserActivity
and CoreSpotlight
APIs following closely along with the NSUserActivity
example code sections from the WWDC Introduction to Siri Shortcuts and Building for Voice with Siri Shortcuts videos, but I'm having problems deleting activities once my user deletes the corresponding data. My app is a book reading app where users can download and read books, so I want to have shortcuts to each book the user has downloaded, but delete the shortcut when/if they delete the book.
I have code here defining the NSUserActivity
and its associated properties:
self.activity = [[[NSUserActivity alloc] initWithActivityType: @"Read a book"] autorelease];
self.activity.eligibleForSearch = true;
self.activity.eligibleForHandoff = true;
self.activity.eligibleForPublicIndexing = true;
self.activity.userInfo = @{ @"productID" : productID };
self.activity.requiredUserInfoKeys = [NSSet setWithArray: @[@"productID"]];
if (@available(iOS 12.0, *))
{
self.activity.eligibleForPrediction = true;
self.activity.suggestedInvocationPhrase = @"Read";
self.activity.persistentIdentifier = NSUserActivityPersistentIdentifier(productID);
}
I also have code defining a CSSearchableItemAttributeSet
, its associated properties, connecting it to the NSUserActivity
, and making it active:
CSSearchableItemAttributeSet *attributes = [[[CSSearchableItemAttributeSet alloc] initWithItemContentType: (NSString *)kUTTypeItem] autorelease];
attributes.title = bookTitle;
attributes.keywords = @[keywords];
attributes.contentDescription = author;
attributes.thumbnailData = [NSData dataWithContentsOfURL: self.bookCover];
attributes.domainIdentifier = productID;
self.activity.contentAttributeSet = attributes;
self.userActivity = self.activity;
[self.activity becomeCurrent];
I've found out through research that using attributes.relatedUniqueIdentifier
gets rid of the userInfo
dictionary, and in my case this makes the shortcut not show up at all, so I am using attributes.domainIdentifier
instead.
Now in another file I go to delete the shortcut. I've tried using this code which uses the self.activity.persistentIdentifier
property:
if (@available(iOS 12.0, *)) {
[NSUserActivity deleteSavedUserActivitiesWithPersistentIdentifiers: @[NSUserActivityPersistentIdentifier(productID)] completionHandler: ^{}];
}
I've also tried using this code which uses the attributes.domainIdentifier
property:
[[CSSearchableIndex defaultSearchableIndex] deleteSearchableItemsWithDomainIdentifiers: @[productID] completionHandler: ^(NSError * _Nullable error) {}];
And neither of these solutions have worked. In both cases I have checked the productID
parameter that is passed into the functions and it has beent the correct value both times.
Is there something I'm doing wrong or something I'm missing?
Thank you all in advance for the help. This is my first post, let me know if I need to provide more information.
I figured out what I was missing. I needed to create a CSSearchableItem
, set its uniqueIdentifier
and domainIdentifier
properties to be equal to the NSUserActivity
's. Then I needed to index the CSSearchableItem
.
This is the code I was missing:
attributes.relatedUniqueIdentifier = productID
CSSearchableItem *item = [[[CSSearchableItem alloc] init] autorelease];
item.uniqueIdentifier = productID;
item.domainIdentifier = productID;
[[CSSearchableIndex defaultSearchableIndex] indexSearchableItems: @[item] completionHandler: ^(NSError * _Nullable error) {}];