iOS9搜索三剑客之CoreSpotlight

7 篇文章 0 订阅
6 篇文章 0 订阅

       iOS9之前普通的App应用只能够搜索应用名称,通过搜索到的应用来打开对应的应用。而其他的内容搜索功能只能够由苹果提供的系统应用使用,如邮件、短信等。iOS9提供的搜索三剑客为:

  • NSUserActivity,从iOS8开始提供用于记录App状态,在iOS9及之后,不设计隐私内容,默认是可以被手机本地搜索
  • CoreSpotlight,第三方app可以通过CSSearchableItem对象将待索引的用户内容持久化到本地,供本地搜索
  • web markup,允许应用在其网站上做一些markup的标记,在spotlight中进行检索

        本文着重介绍CoreSpotlight的使用,另外两个使用起来相对复杂一点,在后续blog里面会再介绍。特别强调,CoreSpotlight必须是在Xcode7,iOS9上使用,若使用的不是Xcode7请自行更新Xcode,:)

        1、导入framework

              工程 -> Build Phases -> Link Binary With Libraries,搜索CoreSpotlight

              

        2、引用CoreSpotlight包

              在需要使用的类文件中加入

              Swift写法:

       import CoreSpotlight
             Object-C写法:

       #import <CoreSpotlight/CoreSpotlight.h>

        3、将待索引的数据保存至CoreSpotlight

              Swift写法:

              

    @available(iOS 9, *)   //标明该方法只适用于iOS9及以后的系统
    func saveCoreSpotlightItems() {
        let domain: String = "com.xxx.searchAPIs"
        CSSearchableIndex.defaultSearchableIndex().deleteSearchableItemsWithDomainIdentifiers([domain]) { (error) -> Void in
        }   //删除已有索引,便于增加新的索引,如果此处的索引是永久不变的,可以将此处改为是否已经添加过,避免重复添加
        
        if let filepath: String = NSBundle.mainBundle().pathForResource("Spotlight", ofType: "plist") {//此例子是从plist文件读取信息
            let items: NSArray? = NSArray(contentsOfFile: filepath)
            if items != nil && items!.count > 0 {
                var searchableItems: Array<CSSearchableItem> = Array()
                for var i: Int = 0; i < items!.count; i++ {
                    let item: NSDictionary = items![i] as! NSDictionary
                    let title: String? = item.objectForKey("title") as? String
                    let content: String? = item.objectForKey("content") as? String
                    
                    let attributeSet: CSSearchableItemAttributeSet = CSSearchableItemAttributeSet(itemContentType: "search")
                    attributeSet.title = title
                    attributeSet.contentDescription = content
                    attributeSet.thumbnailData = UIImagePNGRepresentation(UIImage(named: "spot")!)
                    
                    let searchItem: CSSearchableItem = CSSearchableItem(uniqueIdentifier: "healthtool", domainIdentifier: domain, attributeSet: attributeSet)
                    searchableItems.append(searchItem)
                }
                
                CSSearchableIndex.defaultSearchableIndex().indexSearchableItems(searchableItems, completionHandler: { (error) -> Void in
                })
            }
        }
    }
           Object-C写法:         

     - (void)saveCoreSpotlightItems {
     <span style="white-space:pre">	</span>#if __IPHONE_OS_VERSION_MAX_ALLOWED >= _IPHONE90_
    <span style="white-space:pre">		</span>NSString *domain = @"com.tijianzhuanjia.kangjian.SearchAPIs";
    <span style="white-space:pre">		</span>[[CSSearchableIndex defaultSearchableIndex] deleteSearchableItemsWithDomainIdentifiers:[NSArray arrayWithObject:domain] completionHandler:^(NSError * _Nullable error) {
    }];
    
<span style="white-space:pre">	</span>    <span style="white-space:pre">	</span>NSString *filepath = [[NSBundle mainBundle] pathForResource:@"Spotlight" ofType:@"plist"];
    <span style="white-space:pre">		</span>if (filepath != nil && filepath.length > 0) {
<span style="white-space:pre">	</span>        <span style="white-space:pre">	</span>NSMutableArray *searchableItems = [NSMutableArray array];
<span style="white-space:pre">		</span>        NSArray *items = [NSArray arrayWithContentsOfFile:filepath];
<span style="white-space:pre">		</span>        for (NSDictionary *item in items) {
<span style="white-space:pre">		</span>            NSString *title = [item objectForKey:@"title"];
<span style="white-space:pre">		</span>            NSString *content = [item objectForKey:@"content"];
            
<span style="white-space:pre">		</span>            CSSearchableItemAttributeSet *attributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:@"search"];
<span style="white-space:pre">		</span>            attributeSet.title = title;
<span style="white-space:pre">		</span>            attributeSet.contentDescription = content;
<span style="white-space:pre">		</span>            attributeSet.thumbnailData = UIImagePNGRepresentation([UIImage imageNamed:@"spot"]);
            
<span style="white-space:pre">		</span>            CSSearchableItem *searchItem = [[CSSearchableItem alloc] initWithUniqueIdentifier:@"kangjian" domainIdentifier:domain attributeSet:attributeSet];
            
<span style="white-space:pre">		</span>            [searchableItems addObject:searchItem];
<span style="white-space:pre">	</span>        }
        
        <span style="white-space:pre">	</span>if (searchableItems.count != 0) {
<span style="white-space:pre">	</span>            [[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:searchableItems completionHandler:^(NSError * _Nullable error) {
            }];
        <span style="white-space:pre">	</span>}
    <span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>#endif
<span style="white-space:pre">	</span>}

                title,contentDescription和thumbnilData字段说明,参见下图

                

               title和contentDescription已经写在图中了,thumbnilData就是图中红色圈中的图片文件内容

   

               4、使用saveCoreSpotlightItems方法注册

                   我一般喜欢把这种东西放在didFinishLaunching的方法里面,你也可以放在任何可以执行到的地方,且放在线程中执行,最小化影响主线程

                   Swift写法:

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { () -> Void in
            if #available(iOS 9, *) {
                weakSelf?.saveCoreSpotlightItems()
            }
        }
                  Object-C写法:

        [NSThread detachNewThreadSelector:@selector(saveCoreSpotlightItems) toTarget:self withObject:nil];  //也可以使用GCD的写法,偷懒没有写

               5、利用Spotlight直接跳转至对应的界面

                     至上面第四步,我们也只能像之前Spotlight搜索功能一样,只能跳转至App的首页即rootViewController,要想利用Spotlight搜索出来的项,点击直接进入指定的界面,我们还需要做额外的工作。那就是实现AppDelegate中iOS8及以后才出现的方法continueUserActivity

              此处作为测试,仅直接跳转至登录界面,各位完全可以按照自己的想法,跳转至任何controller

@available(iOS 8, *)
    func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool {
        let identifier: String? = userActivity.userInfo?["kCSSearchableItemActivityIdentifier"] as? String
        if identifier == "healthtool" {
            let currentController: UIViewController = self.getCurrentViewController()
            let controller: LoginViewController = LoginViewController(nibName: "LoginViewController", bundle: nil)
            currentController.navigationController?.pushViewController(controller, animated: true)
        }
        
        return true
    }

                    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值