In current iOS system, content of application can be indexed and searched in search panel. This is a good feature for APP developer.
First we need to know what CoreSpotlight framework can do.
The Core Spotlight framework helps your app participate in search by providing ways to index the content within your app (including user-generated content) and manage the on-device index.
Which means, we need to package information of content and provided to iOS system. Therefore, by Apple Developer Document, the steps needed to implement.
To get started indexing app content, perform these steps:
- Create a CSSearchableItemAttributeSet object and specify properties that describe the item you want to index.
- Create a CSSearchableItem object to represent the item. A CSSearchableItem object has a unique identifier that lets you refer to it later.
- If needed, specify a domain identifier so that you can gather multiple items together and manage them as a group.
- Associate the attribute set with the searchable item.
- Add the searchable item to the index.
Like above picture, I set the name, thumbnail, description as meta for content. The following code is how to package necessary data.
The list of content looks like below picture, we can chose to add the items into search list or we remove all of them. Add and Delete buttons perform the action as the code below.
#pragma mark - Spotlight framework
-(void)addToSpotLight:(id)sender{
NSMutableArray * sps = [[NSMutableArray alloc]init];
for (Content * cot in self.items) {
CSSearchableItem * si = [self generateContentToSpotlightSearchAbleItem:cot];
[sps addObject:si];
}
[[CSSearchableIndex defaultSearchableIndex]indexSearchableItems:sps completionHandler:^(NSError * _Nullable error) {
NSString * message=@"Success Add";
if (error) {
NSLog(@"add search able item error: %@",error);
message = @"Fail Add";
}
UIAlertController * alert = [UIAlertController alertControllerWithTitle:nil message:message preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
}]];
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:alert animated:YES completion:^{
}];
});
}];
}
-(void)deleteFromSpotLight:(id)sender{
[[CSSearchableIndex defaultSearchableIndex]deleteSearchableItemsWithDomainIdentifiers:@[SpotlightDomain] completionHandler:^(NSError * _Nullable error) {
NSString * message=@"Success Deleted";
if (error) {
NSLog(@"delete items error :%@",error);
message = @"Fail Deleted";
}
UIAlertController * alert = [UIAlertController alertControllerWithTitle:nil message:message preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
}]];
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:alert animated:YES completion:^{
}];
});
}];
}
-(CSSearchableItem *)generateContentToSpotlightSearchAbleItem:(Content *)content{
CSSearchableItem * result = nil;
CSSearchableItemAttributeSet * ats = [[CSSearchableItemAttributeSet alloc]initWithItemContentType:(NSString*)kUTTypeImage];
ats.title = content.name;
ats.contentDescription = content.contentDescription;
ats.keywords = @[@"CodeTemplate",@"Homer",content.name];
ats.thumbnailData = UIImagePNGRepresentation([UIImage imageNamed:content.name]);
result = [[CSSearchableItem alloc]initWithUniqueIdentifier:[[content.objectID URIRepresentation] absoluteString] domainIdentifier:SpotlightDomain attributeSet:ats];
return result;
}
By the code above, I set the keywords for each item. Keywords are indexed for spotlight search. It is a very important attribute.
When you select item from spotlight search list. we can present the detail page about this image. And how to handle the selection, we can use following function of AppDelegate.
-(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler{
if ([userActivity.activityType isEqualToString:CSSearchableItemActionType]) {
[LoadNotificationViewController showWithUserActivity:userActivity];
return YES;
}
return NO;
}
//In LoadNotificationViewController
+(void)showWithUserActivity:(NSUserActivity *)userActivity{
NSLog(@"%@",userActivity);
NSManagedObjectContext * context = [[TemplateUtility shareInstance] coredataManagerContext];
NSString * objectIdString = [userActivity.userInfo objectForKey:CSSearchableItemActivityIdentifier];
NSURL * theURL = [NSURL URLWithString:objectIdString];
NSManagedObjectID * objectID = [context.persistentStoreCoordinator managedObjectIDForURIRepresentation:theURL];
Content * c = [Content getContentWithId:objectID withContext:context];
if (c) {
... ...
}
}
In useractivity, there are userInfo which is a NSDictionary that contains meta data about this content. When I print out this dictionary, the result as following image.
Above is a implement of spotlight framework. More code can be found in GitHub CodeTemplate. If you have any suggestions and questions about this blog, please feel free to leave a comment. I will appreciate that.