itZme
itZme

Reputation: 1439

Predicate to fetch child files and folders inside a parent folder with coredata

I have a situation where my apps core-data entities looks like this enter image description here

Application is basically intends to works like a directory, where user can add their own files and folders.

I need to provide search feature inside folders, where user can search for files or folders with specific values (need to iterate through child files and sub folders in all sub levels).

Can we use NSPredicate and NSFetchrequest to do this?

Please advice.

Upvotes: 0

Views: 351

Answers (2)

Dan Shelly
Dan Shelly

Reputation: 6011

If your File and Folder have many things in common ...
I would change my model a bit:

  1. make a Node abstract base class having properties:
    identifier
    title
    relationships:
    parent - to-one -> Node
  2. inherit Folder from Node and add the relationship:
    children - to-many ->> Node
  3. inherit File from Node and add the properties:
    mimeType
    owner

Take into account that this will create (under current CoreData implementation) a single table containing all these properties and relationships.

You would now be able to search your model for nodes (Files and Folders) with title matching a given string. Use the predicate:

[NSPredicate predicateWithFormat:@"title CONTAINS[cd] %@",searchText]

However ... This is not a complete solution as you can not limit your search to a given parent Node.

If you need to limit the search, you could keep a parent list for each Node by adding another to-many relationship to a Node entity called parents. this parents set will be set upon Node parent relationship setting, by taking the new node parent parents set, coping it and adding the parent to it, then setting it to the new node.

This will allow a more refined search by using the predicate:

[NSPredicate predicateWithFormat:@"ANY parents = %@ AND title CONTAINS[cd] %@",baseNode,searchText]

This could be optimised so that a node may point only to a specific parents set without coping it over and over again, but this is a bit more complex.

You could also use a nested sets or nested intervals implementation ... but I guess it will require a lot of work on your part.

All requests here are done on the Node entity

Upvotes: 1

shtefane
shtefane

Reputation: 454

You must to do two requests: one for folders and one for files like this

 - (NSArray*) getFilesOrFoldersWithName:(NSString*) name {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Folder"
                                          inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setResultType:NSDictionaryResultType];

NSPredicate *predicate=[NSPredicate predicateWithFormat:@"title CONTAINS[cd] %@ ", name];
[fetchRequest setPredicate:predicate];

NSError* error;
NSArray *fetchedRecords = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];

if (error) {
    NSLog(@"Error %@",error);
}

return fetchedRecords;
}

Upvotes: 0

Related Questions