Is there an example code for corespotlight search feature - iOS 9 API?

15.7k Views Asked by At

Is there an example code for corespotlight search feature - iOS 9 API? Really appreciate if can look at sample code to implement/test.

6

There are 6 best solutions below

5
On
CSSearchableItemAttributeSet *attributeSet;
attributeSet = [[CSSearchableItemAttributeSet alloc]
                                 initWithItemContentType:(NSString *)kUTTypeImage];

attributeSet.title = @"My First Spotlight Search";
attributeSet.contentDescription = @"This is my first spotlight Search";

attributeSet.keywords = @[@"Hello", @"Welcome",@"Spotlight"];

UIImage *image = [UIImage imageNamed:@"searchIcon.png"];
NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(image)];
attributeSet.thumbnailData = imageData;

CSSearchableItem *item = [[CSSearchableItem alloc]
                                       initWithUniqueIdentifier:@"com.deeplink"
                                               domainIdentifier:@"spotlight.sample"
                                                   attributeSet:attributeSet];

[[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:@[item]
                                 completionHandler: ^(NSError * __nullable error) {
    if (!error)
        NSLog(@"Search item indexed");
}];

Note: kUTTypeImage requires that you import the MobileCoreServices framework.

1
On
let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeImage as String)
attributeSet.title = "Searchable Item"
attributeSet.contentDescription = "Code for creating searchable item"
attributeSet.keywords = ["Item","Searchable","Imagine"]
attributeSet.thumbnailURL = NSURL(string: "https://blog.imagine.com/")

let searchableItem = CSSearchableItem(uniqueIdentifier: "com.imagine.objectA", domainIdentifier: "spotlight.search", attributeSet: attributeSet)
CSSearchableIndex.defaultSearchableIndex().indexSearchableItems([searchableItem]) {_ in}
0
On

I am using similar implementation as mentioned by @mayqiyue but I am also checking the existence of the item variable for backwards compatibility with iOS 8.

- (void)setupCoreSpotlightSearch
{
    CSSearchableItemAttributeSet *attibuteSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:(__bridge NSString *)kUTTypeImage];
    attibuteSet.title = NSLocalizedString(@"Be happy!", @"Be happy!");
    attibuteSet.contentDescription = @"Just like that";
    attibuteSet.keywords = @[@"example", @"stackoverflow", @"beer"];

    UIImage *image = [UIImage imageNamed:@"Image"];
    NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(image)];
    attibuteSet.thumbnailData = imageData;

    CSSearchableItem *item = [[CSSearchableItem alloc] initWithUniqueIdentifier:@"1"
                                                             domainIdentifier:@"album-1"
                                                                 attributeSet:attibuteSet];
    if (item) {
        [[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:@[item] completionHandler:^(NSError * _Nullable error) {
            if (!error) {
                NSLog(@"Search item indexed");
            }
        }];
    }
}

To handle the tap on the search item from Spotlight you need to implement following method in your AppDelegate:

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
{
    if ([userActivity.activityType isEqualToString:CSSearchableItemActionType]) {
        NSString *uniqueIdentifier = userActivity.userInfo[CSSearchableItemActivityIdentifier];

        // Handle 'uniqueIdentifier'
        NSLog(@"uniqueIdentifier: %@", uniqueIdentifier);
    }

    return YES;
}
0
On

To complete the spotlight search functionality, once you have implemented mayqiyue's answer, you'll be able to see the results in the search but on selection of the result simply your app would open not the related view with related content.

In order to do so, go to your AppDelegate.m and add the following method.

 -(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler

        {

            //check if your activity has type search action(i.e. coming from spotlight search)
            if ([userActivity.activityType isEqualToString:CSSearchableItemActionType ] == YES) {

                //the identifier you'll use to open specific views and the content in those views.
                NSString * identifierPath = [NSString stringWithFormat:@"%@",[userActivity.userInfo objectForKey:CSSearchableItemActivityIdentifier]];

                if (identifierPath != nil) {

                    // go to YOUR VIEWCONTROLLER
                    // use notifications or whatever you want to do so

                    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
                    MyViewController *myViewController = [storyboard instantiateViewControllerWithIdentifier:@"MyViewController"];

                    // this notification must be registered in MyViewController
                    [[NSNotificationCenter defaultCenter] postNotificationName:@"OpenMyViewController" object: myViewController userInfo:nil];


                    return YES;
                }

            }


            return NO;
        }

Make sure to import in AppDelegate.m :

 #import <MobileCoreServices/MobileCoreServices.h>
 #import <CoreSpotlight/CoreSpotlight.h>

UPDATE for Swift 2.1

func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool {

    if #available(iOS 9.0, *) {
        if userActivity.activityType == CSSearchableItemActionType  {

            //the identifier you'll use to open specific views and the content in those views.
            let dict = userActivity.userInfo! as NSDictionary
            let identifierPath  = dict.objectForKey(CSSearchableItemActivityIdentifier) as! String
            if identifierPath.characters.count > 0 {

                let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
                let mvc: MyViewController = storyboard.instantiateViewControllerWithIdentifier("MyViewController") as! MyViewController

                NSNotificationCenter.defaultCenter().postNotificationName("OpenMyViewController", object: mvc, userInfo: nil)
            }

            return true
        }

    } else {
        // Fallback on earlier versions
            return false

    }

    return false

}

Make sure to import in AppDelegate.swift :

import CoreSpotlight
import MobileCoreServices
8
On
  1. Create a new iOS project and add CoreSpotlight and MobileCoreServices framework to your project. enter image description here

  2. Create the actual CSSearchableItem and associating the uniqueIdentifier, domainIdentifier and the attributeSet. Finally index the CSSearchableItem using [[CSSearchableIndex defaultSearchableIndex]...] as show below. enter image description here

  3. OK!Test the index!
    enter image description here

0
On
  1. Write in your main controller Class

    -(void)storeValueForSpotligtSearch {
    
        NSString *bundleIdentifier                      = [[NSBundle mainBundle] bundleIdentifier];
        // **Your Model Array that Contain Data Like attributes Make, Model, Variant and Year and Images**
    
        for (MyCatalogeModel *myCatalogeModelObj in yourDataContainer) {
            NSMutableArray *arrKeywords                 = [[NSMutableArray alloc] initWithObjects: myCatalogeModelObj.year, myCatalogeModelObj.make, myCatalogeModelObj.model, myCatalogeModelObj.variant, nil];
            NSString *strIdentifier                     = [NSString stringWithFormat:@"%@.%@",bundleIdentifier, myCatalogeModelObj.carId];
            self.userActivity                           = [[NSUserActivity alloc]initWithActivityType:strIdentifier];
            self.userActivity.title                     = myCatalogeModelObj.year;
            self.userActivity.title                     = myCatalogeModelObj.make;
            self.userActivity.title                     = myCatalogeModelObj.model;
            self.userActivity.title                     = myCatalogeModelObj.variant;
            self.userActivity.eligibleForSearch         = YES;
            self.userActivity.eligibleForPublicIndexing = YES;
            self.userActivity.eligibleForHandoff        = YES;
            CSSearchableItemAttributeSet * attributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:(NSString *)kUTTypeJSON];
            attributeSet.title                          = myCatalogeModelObj.make;
            attributeSet.thumbnailData                  = [NSData dataWithContentsOfURL:[NSURL URLWithString:[myCatalogeModelObj.imageArray objectAtIndex:0]]];
            attributeSet.contentDescription             = [NSString stringWithFormat:@"%@ %@ %@ %@", myCatalogeModelObj.year, myCatalogeModelObj.make, myCatalogeModelObj.model, myCatalogeModelObj.variant];
            attributeSet.keywords                       = arrKeywords;
            CSSearchableItem *item                      = [[CSSearchableItem alloc] initWithUniqueIdentifier:strIdentifier domainIdentifier:@"spotlight.CARS24ChannelPartnerapp" attributeSet:attributeSet];
            [[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:@[item] completionHandler: ^(NSError * __nullable error) {
            }];
            self.userActivity.contentAttributeSet       = attributeSet;
            [self.userActivity becomeCurrent];
            [self updateUserActivityState:self.userActivity];
        }
    }
    
  2. Write in App Delegate

    -(BOOL)application:(nonnull UIApplication *) application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray * __nullable))restorationHandler {
    
        @try {
    
            NSString *strIdentifier;
            NSNumber *numScreenId;
            NSNumberFormatter *numFormatter = [[NSNumberFormatter alloc] init];
            NSLog(@"Activity = %@",userActivity.userInfo);
            if (userActivity.userInfo[@"vc"]) {
                numScreenId = userActivity.userInfo[@"vc"];
            }
            else{
                strIdentifier = [userActivity.userInfo objectForKey:@"kCSSearchableItemActivityIdentifier"];
                NSLog(@"strIdentifier : %@",strIdentifier);
                NSArray *arr = [strIdentifier componentsSeparatedByString:@"."];
                NSString *strScreenId = [arr objectAtIndex:3];
                NSLog(@"ID -= %@",strScreenId);
    
                **// On Click in Spotlight search item move your particular view.**
    
                [self moveToParticular:[strScreenId intValue]];
                numScreenId = [numFormatter numberFromString:strScreenId];
            }
        }
        @catch (NSException *exception) {}
    
        return YES;
    }