【问题标题】:How to Properly Batch Index in Core Spotlight如何在 Core Spotlight 中正确批量索引
【发布时间】:2016-06-23 05:21:40
【问题描述】:

我开始使用 Core Spotlight 来索引我的应用程序中的项目。正如我所想的那样,该应用程序在我的设备上崩溃了,但在模拟器上却没有,因为我有 2000 多个要索引的项目。我注意到当我将大约 427 个项目添加到持有我的项目的 NSMutableArray 时,我开始收到内存警告,并在它达到 540 个项目时完全崩溃。

我知道batch 这些索引的功能,我可以在他们的网站Apple - Index App Content - Using Advanced Features 上看到Apple 提供的代码。但是,我不确定如何实现这一点。

有人可以添加一些代码或指出正确的方向来完成此任务吗?

更新 #1 (2016/06/21)

我要索引的项目大约有 2000 多个姓名,包括我公司的电话号码、电子邮件、职位和部门信息。我有一个内置文件,但我也会定期下载一个文件以获取最新信息。我将数据保存为plist,而不是CoreData。文件下载后,我启动索引,首先删除当前索引的所有内容,然后添加所有项目。从服务器我无法确定数据是否已更改。

我的目标是一次索引大约 200-400 个项目,直到所有项目都被索引。以下是我目前在不进行批处理的情况下进行索引的方式。

- (void)setupCoreSpotlightSearchFor:(NSString *)fileName {
        if ([fileName isEqual:kPlistFileNameEmployee]) {
            NSFileManager *fileManager = [NSFileManager defaultManager];
            NSURL *downloadFileUrl = kDirectoryEmployeeListDownload;

            if ([fileManager fileExistsAtPath:[downloadFileUrl path]]) {
                NSArray *dataArray = nil;
                NSError *error = nil;
                dataArray = [NSArray arrayPropertyListWithURL:downloadFileUrl error:&error];
                if (!error && dataArray) {
                    NSMutableArray *items = nil;
                    int counter = 0;
                    for (NSDictionary *person in dataArray) {
                        NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
                        f.numberStyle = NSNumberFormatterDecimalStyle;
                        NSNumber *idNum = [f numberFromString:[[person objectForKey:@"Id"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
                        NSString *firstName = [[person objectForKey:@"FirstName"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
                        NSString *lastName = [[person objectForKey:@"LastName"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
                        NSString *email = [[person objectForKey:@"Email"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
                        NSString *phone = [[person objectForKey:@"Extension"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
                        NSString *title = [[person objectForKey:@"Title"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
                        NSString *organization = [[person objectForKey:@"Organization"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
                        NSString *department = [[person objectForKey:@"Department"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

                        CSSearchableItemAttributeSet *attributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:(NSString *)kCIAttributeTypeImage];

                        Person *person = [Person createPersonWithId:idNum
                                                          FirstName:[NSString stringOrNil:firstName]
                                                           LastName:[NSString stringOrNil:lastName]
                                                              Email:[NSString stringOrNil:email]
                                                        PhoneNumber:[NSString stringOrNil:phone]
                                                              Title:[NSString stringOrNil:title]
                                                       Organization:[NSString stringOrNil:organization]
                                                         Department:[NSString stringOrNil:department]
                                          ];

                        if ([NSString stringOrNil:[person fullName]] != nil) {
                            [attributeSet setTitle:[person fullName]];
                            [attributeSet setContentDescription:[person title]];

                            NSMutableArray *keywords = [[NSMutableArray alloc] init];

                            if ([NSString stringOrNil:[person firstName]] != nil) {
                                [keywords addObject:[person firstName]];
                            }
                            if ([NSString stringOrNil:[person lastName]] != nil) {
                                [keywords addObject:[person lastName]];
                            }
                            if ([NSString stringOrNil:[person title]] != nil) {
                                [keywords addObject:[person title]];
                            }
                            if ([NSString stringOrNil:[person department]] != nil) {
                                [keywords addObject:[person department]];
                            }
                            if ([NSString stringOrNil:[person phoneNumber]] != nil) {
                                [keywords addObject:[person phoneNumber]];
                            }
                            if ([NSString stringOrNil:[person email]] != nil) {
                                [keywords addObject:[person email]];
                            }

                            [attributeSet setKeywords:keywords];

                            UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 180, 180)];
                            [imageView setImageWithString:[person initialsWithCapitalization:InitialsCapitalizationTypeBoth andLastNameFirst:NO] color:[UIColor colorWithRed:0.77 green:0.07 blue:0.19 alpha:1.0] circular:YES];
                            [attributeSet setThumbnailData:UIImagePNGRepresentation([imageView image])];

                            if ([NSString stringOrNil:[person phoneNumber]] != nil) {
                                [attributeSet setSupportsPhoneCall:[NSNumber numberWithInt:1]];
                                [attributeSet setPhoneNumbers:@[[person phoneNumber]]];
                            }
                            if ([NSString stringOrNil:[person email]] != nil) {
                                [attributeSet setEmailAddresses:@[[person email]]];
                            }

                            CSSearchableItem *item = [[CSSearchableItem alloc] initWithUniqueIdentifier:[NSString stringWithFormat:@"%@", [person id]] domainIdentifier:@"com.myapp.index.employee" attributeSet:attributeSet];

                            if (item) {
                                if (!items) {
                                    items = [[NSMutableArray alloc] init];
                                }
                                [items addObject:item];
                                counter++;
                            }
                        }
                    }

                    if (items) {
                        // delete current items
                        [[CSSearchableIndex defaultSearchableIndex] deleteAllSearchableItemsWithCompletionHandler:^(NSError * _Nullable error) {
                            if (error) {
                                DLog(@"%@",error);
                            } else {
                                DLog(@"Deleted Index!");

                                // add new items
                                [[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:items completionHandler:^(NSError * _Nullable error) {
                                    if (error) {
                                        DLog(@"%@",error);
                                    } else {
                                        DLog(@"Added Index!");
                                    }
                                }];
                            }
                        }];
                    }
                }
            }
        }
    }

谢谢!

【问题讨论】:

  • 我不知道你在问什么......你想给你的索引洗澡,你可以看到苹果实现的代码,但你还是一头雾水?这是一个链接开始我猜toptal.com/ios/ios-9-spotlight-search-for-developers
  • @KFDoom,不,我搞定了。我正在尝试Batch他们,如我提供的链接中所述。
  • 所以您想在应用未运行时批量更新?这就是您链接到的 Apple 文档中的“高级”部分主要讨论的内容。
  • 我不同意你的观点。高级部分讨论了两个不同的功能:1)批量更新和 2)不运行时的索引。这两个是不同的功能。清单 4-6 可以在应用程序运行时完成,我正在尝试获取人们如何完成它的示例。
  • 啊,我明白了!事实上,我们一点也不反对。我只是想弄清楚你在问什么。不,我们可以做饭..

标签: ios objective-c corespotlight


【解决方案1】:

因此,您的内存问题实际上与核心聚光灯无关,因为您的代码甚至在您到达那里之前就崩溃了。您应该配置文件以准确检查占用所有内存的内容,我猜您生成的图像占了很大一部分,特别是因为您使用的是 PNG 数据而不是 JPEG(考虑到图像的简单性质,压缩效果显着) .当您真正想要的是图像时,创建图像视图似乎也非常浪费,并且在循环的每次迭代中创建一个新的图像视图也是双重浪费......

因此,您不应该对核心聚光灯处理进行批处理,而应该对文件处理进行批处理。有很多方法可以做到这一点,但重点是你将文件中的 100 个项目处理成一个数组,然后将其传递给核心聚光灯并等待它完成。然后开始文件中接下来的 100 个项目。

您可以使用异步 NSOperation 来做到这一点。您可以使用递归块和 GCD 来做到这一点。

【讨论】:

  • 知道了。有趣的。我没用过NSOperation。我得查一下。你介意给我一些代码吗?
  • 很抱歉正在度假。我现在会调查一下。但是,我确实要求提供工作代码/示例来获得 50 赏金。如果可以的话,谢谢!顺便说一句:它在 OBJ-C 中
猜你喜欢
  • 2016-06-22
  • 1970-01-01
  • 2016-03-13
  • 2016-10-14
  • 2020-02-10
  • 2014-01-10
  • 2023-04-01
  • 2019-07-19
  • 2018-04-19
相关资源
最近更新 更多