Autosave of extended NSOutlineView items does not work

I am trying to use the Auto Save Advanced Elements feature. When I expand the group with my children and restart the application, all the children crash again, and I don’t know why they will not stay extended. I use basic data to store the elements of the original list.

This is what I have done / installed so far:

  • Checked "Autosave of Extended Elements" in NSOutlineView (list of sources)
  • Set a name for "Autosave"
  • dataSource and delegates assigned to my controller

This is my implementation for outlineView: persistentObjectForItem and outlineView: itemForPersistentObject.

- (id)outlineView:(NSOutlineView *)anOutlineView itemForPersistentObject:(id)object { NSURL *objectURI = [[NSURL alloc] initWithString:(NSString *)object]; NSManagedObjectID *mObjectID = [_persistentStoreCoordinator managedObjectIDForURIRepresentation:objectURI]; NSManagedObject *item = [_managedObjectContext existingObjectWithID:mObjectID error:nil]; return item; } - (id)outlineView:(NSOutlineView *)anOutlineView persistentObjectForItem:(id)item { NSManagedObject *object = [item representedObject]; NSManagedObjectID *objectID = [object objectID]; return [[objectID URIRepresentation] absoluteString]; } 

Any ideas? Thanks.

EDIT: I have a key! The problem, perhaps, is that the tree controller did not prepare its content on time. ApplicationDidFinishLaunching, outlineView: persistentObjectForItem methods, etc. Run before data is loaded, or rather, NSOutlineView has not yet completed initialization. Any ideas how to solve this?

+5
source share
4 answers

I had a problem that my implementation of -outlineView: itemForPersistentObject: was not called at all. It turns out that this method is called when either "autosaveExpandedItems" or "autosaveName" are set. My solution was to set both properties in Code and NOT in InterfaceBuilder. When I set the properties after assigning a delegate, the method is called.

+2
source

I never got this job.

This is my current way of doing this:

First, I added the "isExpanded" attribute and saved the status for each node in the database.

enter image description here

Secondly, I expand nodes when my treeController prepared its contents.

 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { [treeSectionController addObserver:self forKeyPath:@"content" options:0 context:nil]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (object == treeSectionController) { NSArray *sectionArray = [[treeSectionController arrangedObjects] childNodes]; for (NSTreeNode *node in sectionArray) { if([[node representedObject] isExpandedValue]) { [outlinePilesView expandItem:node]; } } [treeSectionController removeObserver:self forKeyPath:@"content"]; } } 
0
source

I got this to work - you need to return the corresponding node tree instead of the "just" of its represented object.

In itemForPersistentObject: instead of return item; you need return [self itemForObject:item inNodes:[_treeController.arrangedObjects childNodes]];

from

 - (id)itemForObject:(id)object inNodes:(NSArray *)nodes { for (NSTreeNode *node in nodes) { if ([node representedObject] == object) return node; id item = [self itemForObject:object inNodes:node.childNodes]; if (item) return item; } return nil; } 

where _treeController is an instance of NSTreeController , which is used to populate the outline view.

0
source

Deployment as decided by Karsten:

The -outlineView:itemForPersistentObject: called after doing what Karsten offers, but ONLY if you also set the data source before setting the delegate.

So, if Karsten's answer does not seem to work, check where your data source is installed and adjust it accordingly.

(I wanted to write this as a comment, but I'm not allowed because of the status of my newbie ...)

-1
source

Source: https://habr.com/ru/post/1202346/


All Articles