Im using swift and I show a NSOpenPanel. In the delegate I need to look at the sender's prompt to distinguish which action to take:
eg
func show() {
...
panel.delegate = self
panel.prompt = "xy"
panel.run ....
}
func show2() {
...
panel.delegate = self
panel.prompt = "abc"
panel.run ....
}
//delegate
func panel(sender: AnyObject, shouldEnableURL url: NSURL) -> Bool {
let panelPrompt = (sender as! NSOpenPanel).prompt ...
}
without sandbox = WORKS fine
with sandbox = Cast fails, crash
So the question is how do I do use this in swift without crashing?
Is there a nice way or is it just a bug/ugly idk behavior
Do I have to revert to use performSelector?
===
Addition: extensions to NSOpenPanel don't work either!
Instead of casting the sender to NSOpenPanel
(which fails because the sender is an instance of the private NSVBOpenPanel
class), or some performSelector
magic, you can use the fact that arbitrary methods and properties can be accessed on AnyObject
without casting , and the call behaves like an implicitly unwrapped optional:
func panel(sender: AnyObject, shouldEnableURL url: NSURL) -> Bool {
let panelPrompt = sender.prompt ?? ""
// ...
return true
}
This gives the prompt for any sender
object which has a prompt
property, and the empty string as a fallback. In my test it worked well in a sandboxed environment.
See The strange behaviour of Swift's AnyObject for more details, examples, and references to the documentation.
This is how it would work with performSelector. It is quite ugly though:
let panelPromptUnmanaged = (sender as! NSObject).performSelector(NSSelectorFromString("prompt"))
let panelPrompt = panelPromptUnmanaged != nil ? panelPromptUnmanaged.takeRetainedValue() as! String : ""
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.