How to properly index the package in the main spotlight

I'm starting to use Core Spotlight to index items in my application. As I thought, the application will crash on my device, but not in the simulator, because I have 2000+ elements for indexing. I noticed that by the time NSMutableArray containing my elements, I get a warning about saving memory when I add about 427 elements, and completely drops to the moment when it reaches 540 elements.

I am aware of the batch capabilities of these indices, and I can see the code submitted by Apple on their Apple website - application content for the application - using additional features . However, I am not sure how to implement this.

Can someone add code or point me in the right direction to accomplish this?

Update No. 1 (2016/06/21)

The items I'm trying to index are over 2000+ names with phone numbers, email, headline and department information for my company. I have a file, but I also periodically upload the file to get the latest information. I save data as plist , not in CoreData . After downloading the files, I run the index, first deleting all the indexed ones, and then adding all the elements. From the server I can’t determine if the data has changed.

My goal is to index about 200-400 items at a time, until all items have been indexed. The following is how I index now without batch processing.

 - (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!"); } }]; } }]; } } } } } 

Thanks!

+5
source share
1 answer

So the problem with your memory is not really related to the main spotlight, because your code breaks before you get there. You need a profile to accurately verify that taking all the memory, I think that the images you generate make up a significant part, especially because you use PNG data instead of JPEG (with significant compression, given the simple nature of the images). it seems very wasteful to create an image view when what you really want is an image, and it is doubly wasteful to create a new image view at each iteration of the loop ...

Thus, you should not perform batch processing of the main spotlight, you should perform batch processing of files. There are several ways to do this, but the main thing is that you process 100 elements from a file into an array, and then transfer it to the main spotlight and wait for it to complete. Then you start the next 100 elements in the file.

You can do this using asynchronous NSOperation . You can do this with a recursive block and a GCD.

0
source

All Articles