打开现有的Search Kit Framework搜索索引,而不知道其名称

时间:2012-06-16 21:50:24

标签: objective-c macos cocoa search

OS X的Search Kit Framework允许创建和访问搜索索引。但是,当该索引的名称未知时,无法访问现有搜索索引。可用于访问现有搜索索引(SKIndexOpenWithData,SKIndexOpenWithMutableData,SKIndexOpenWithURL)的框架的所有功能都要求索引名称。这与存储搜索索引数据的文件的文件名不同。

当我尝试通过在不知道索引名称的情况下调用SKIndexOpenWithURL来访问现有搜索索引文件时,该函数不会返回有效的SKIndexRef。传递NULL作为索引名称(由框架文档建议)不起作用,因为Search Kit Framework只尝试使用索引名称'IADefaultIndex'。

例如,如果我创建一个索引名称如下的索引文件:

    NSString *path = @"/Users/Tim/Desktop/searchindex.skindex";
    NSURL *url = [NSURL fileURLWithPath: path];  
    NSString *name = @"myIndex";          
    SKIndexType type = kSKIndexInverted;                    
    SKIndexRef skIndex;
    skIndex = SKIndexCreateWithURL ((__bridge CFURLRef)url, (__bridge CFStringRef)name, (SKIndexType)type, (CFDictionaryRef)NULL);
    // ..

如果我知道索引名称“myIndex”,我以后只能打开文件并访问存储的索引。如果我尝试在没有(或知道)索引名称的情况下打开文件,则以下代码示例将失败:

    NSURL *skURL = [NSURL fileURLWithPath:@"/Users/Tim/Desktop/searchindex.skindex"];
    SKIndexRef skIndex;
    skIndex = SKIndexOpenWithURL((__bridge CFURLRef)skURL, NULL, true);
    if (!skIndex) NSLog (@"couldn't open index!");

但是,搜索索引的名称肯定在索引文件中。有没有人知道在不知道搜索索引名称的情况下检索该名称或以其他方式访问搜索索引文件的方法?我知道根据框架文档,不可能使用框架来获取索引名称,但它应该是可能的。

2 个答案:

答案 0 :(得分:2)

好的,经过一些研究后,我想出了如何从搜索索引文件中提取索引名称:

-(NSString*)getIndexNameOfSKFile:(NSString*)filePath
{
    if (!filePath) return nil;

    // open the search index file
    NSData *data = [NSData dataWithContentsOfFile:filePath];
    if (!data) return nil;
    NSUInteger dataLength = [data length];

    // calculate the offset where the index name is stored
    int32_t offset1, offset2;
    if (dataLength<11) return nil;
    [data getBytes:&offset1 range:NSMakeRange(4,4)];
    [data getBytes:&offset2 range:NSMakeRange(8,4)];
    int32_t offset = CFSwapInt32HostToBig(offset1)+(CFSwapInt32HostToBig(offset2)/2)+14;

    // Get index name string (stored as zero-terminated string)
    unichar c;
    NSMutableString *indexName = [NSMutableString stringWithCapacity:0];
    do {
        if (dataLength<(offset+1)) return nil;
        [data getBytes:&c range:NSMakeRange(offset, 2)];
        if (c!=0) [indexName appendString:[NSString stringWithCharacters:&c length:1]];
        offset+=2;
    } while (c!=0);
    return indexName;
}

这可能不适用于每个OS X版本,但它适用于10.7。

答案 1 :(得分:1)

您确定缺少导致问题的索引名称而不是代码的其他部分,例如有效的网址?正如您所注意到的,文档说它应该在不知道索引名称的情况下工作。我与Search Kit进行了广泛的合作,从不需要它,这就是为什么我怀疑问题可能是其他原因。

你可以张贴一些代码吗?

要回答关于是否可以从索引获取名称的问题,方法SKIndexCreateWithURL的文档说不:

  

inIndexName索引的名称。如果你用这个函数调用   inIndexName设置为NULL,Search Kit将索引指定为默认值   索引名称IADefaultIndex。如果您然后尝试创建第二个   不分配名称的同一文件中的索引,没有第二个索引   created,此函数返回NULL。 目前没有搜索工具包   支持从索引中检索索引名称

如果您在Cocoa工作,我想邀请您使用我的开源搜索工具包。你会在Github上找到代码:

https://github.com/phildow/SPSearchStore

如果您可以发布一些代码,我很乐意看一下。