I get an Ambiguous use of 'children'
error in XCode 8.0/Swift 3.0 when trying to send a message to the opaque NSTreeController.arrangedObjects
object.
Here is a bare playground showing the use case :
import AppKit
extension NSTreeController {
func whatever () {
let k = (self.arrangedObjects as AnyObject).children // error here
}
}
I try to use AnyObject
as a bridge to the underlying ObjC object, which is supposed to be able to get through any method call, I guess.
Xcode signals that it found two candidates that could respond to a "children" message: Foundation.XMLNode
and AppKit.NSTreeNode
.
Of course the obvious solution (casting to NSTreeNode
) is not working because arrangedObjects
returns an opaque, proxy object not a real NSTreeNode
Any suggestion on how we're supposed to use NSTreeController.arrangedObjects.children
in Swift 3 ?
The two candidates for the children
property differ by their type:
Foundation.XMLNode:137:14: note: found this candidate
open var children: [XMLNode]? { get }
^
AppKit.NSTreeNode:12:14: note: found this candidate
open var children: [NSTreeNode]? { get }
^
You can resolve the ambiguity by casting the value of the property
to the expected type. In your case:
let k = (self.arrangedObjects as AnyObject).children as [NSTreeNode]?
Another solution: Adding an Obj-C category to NSTreeController
.h
#import <Cocoa/Cocoa.h>
@interface NSTreeController (RootNodes_m)
- (NSArray *) rootNodes;
@end
.m
#import "NSTreeController+RootNodes_m.h"
@implementation NSTreeController (RootNodes_m)
- (NSArray *) rootNodes {
NSObject * arranged = self.arrangedObjects;
if ([arranged respondsToSelector: @selector(childNodes)]) {
return [arranged performSelector:@selector(childNodes)];
}
return nil;
}
@end
Now in your code you can use it like this:
return treeController.rootNodes() as? [NSTreeNode]
I had problem with the above answer: The compiler refused to compile when "whole module optimization" was turned on. A swift extension didn't help. I'm using Xcode 8.2.1.