There are a lot of topics on core data tree structures but I'm left with some questions.
What I'm trying to create is a simple directory structure. (Folders with subfolders with subfolders, ... and later on also files.)
I now have this Folder entity:
And I'm adding folders like this: [Obviously this is dummy data and this will be dynamicly inserted later]
// root 1
Folder *root1 = [NSEntityDescription insertNewObjectForEntityForName:@"Folder" inManagedObjectContext:context];
root1.name = @"Root 1";
root1.parent = nil;
// folder 1 in root 1
Folder *subFolder1 = [NSEntityDescription insertNewObjectForEntityForName:@"Folder" inManagedObjectContext:context];
subFolder1.name = @"Folder 1 in root 1";
subFolder1.parent = root1;
root1.children = [NSSet setWithObjects: subFolder1, nil];
Now I want to make a ViewController for every folder and then open a new ViewController for every subfolder. (Or an infinite UITabelView)
When I loop in the Folder entity with this code:
NSArray *folders = [context executeFetchRequest:fetchRequest error:&error];
for(Folder *folder in folders){
NSLog(@"Profile: %@", folder.name);
}
I get all the folders at once.
So the question is: How can I log this out in a tree structure? So I can create a ViewController for all the root folders first, and then for every subfolder another ViewController etc. etc... (In other words: How can I read this entity as I would put it in a UITabelView)
A directory structure/system/tree is simply a layout of directories on your computer. Taking a big step back, the early computer designers realized that lumping together every single file on your computer would create a massive jumble and make it impossible to find anything. So they wisely created the directory.
To display the folder hierarchy, open Windows Explorer, navigate to the folder you wish to start at, hold down the Shift key, right-click on the folder name and choose Open command window here. Type tree |clip and press Enter. Open your word processor program (or Notepad) and paste (Ctrl+V) the list to it.
You need to use command called tree. It will list contents of directories in a tree-like format. It is a recursive directory listing program that produces a depth indented listing of files. When directory arguments are given, tree lists all the files and/or directories found in the given directories each in turn.
A tree data structure is an algorithm for placing and locating files (called records or keys) in a database. The algorithm finds data by repeatedly making choices at decision points called nodes. A node can have as few as two branches (also called children) or as many as several dozen.
You don't detail how your fetch request is constructed, but the key is to use an NSPredicate
to filter the results only to include the Folder
objects of interest at any given time. To do this, you'll need to store a reference to the current parent folder in the view controller:
@property (readwrite, strong) Folder *parentFolder;
If you're at the root of the tree, this will be nil
, otherwise it will have a reference to the current folder whose contents you're displaying.
Then use this property in a predicate:
NSFetchRequest *fetchRequest = ...
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"parent = %@", self.parentFolder];
[fetchRequest setPredicate:predicate];
When you're at the root, this will select only instances of Folder
where parent
is nil
(i.e. only root level objects). At every other level, it selects only Folders
where parent
is whatever the current parent folder is.
As a side note, in your sample code, it's not necessary to set subFolder1.parent
and root1.children
. Core Data inverse relationship management means that you only need to do this on one side of the relationship. It doesn't hurt anything to do both (aside from a very minor performance hit), but it also serves no purpose.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With