You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The problem is the last line. What we'd like to write is:
iTunes currentTrack name.
However, the bridge uses class_getInstanceMethod to determine if an object understands a message/selector, and it returns NULL for scripting messages like currentTrack and playpause.
I've asked on SO for more information about how SB works its magic. Here are some parts of the Objective-C API that do see these scripting methods:
respondsToSelector: -> TRUE
methodSignatureForSelector: - does return a signature
and performSelector: actually sends the message
Strangely, methodForSelector:@"playpause" successfully returns an IMP in Obj-C, but crashes if sent from the other side of the bridge.
This lower level alternative works, but completely misses much of the convenience of SB:
currentTrack := iTunes propertyWithCode:'pTrk' asObjCFourCharCode.
"Current track can also be retrieved this way, but there doesn't seem to be an advantage...trackClass := iTunes classForScriptingClass: 'track' asNSString autorelease.track := iTunes propertyWithClass: trackClass code: 'pTrk' asObjCFourCharCode."
trackName := currentTrack propertyWithCode:'pnam' asObjCFourCharCode.
trackName get cString
For a command (as opposed to a property as above), a similar approach from SO would be:
Here is a sample acceptance test usage in Python (see reference):
The first three lines are no problem. Foundation is already loaded and then in Pharo, we can do:
The problem is the last line. What we'd like to write is:
However, the bridge uses
class_getInstanceMethod
to determine if an object understands a message/selector, and it returns NULL for scripting messages likecurrentTrack
andplaypause
.I've asked on SO for more information about how SB works its magic. Here are some parts of the Objective-C API that do see these scripting methods:
respondsToSelector:
-> TRUEmethodSignatureForSelector:
- does return a signatureperformSelector:
actually sends the messageStrangely,
methodForSelector:@"playpause"
successfully returns anIMP
in Obj-C, but crashes if sent from the other side of the bridge.Possible Solutions
Perform Selector
This works, but requires inheritance from NSObject and the docs suggest this approach may lead to memory leaks and a SO threads here and here say that NSInvokation might be better
Bypass SB Dynamically-Generated Methods
This lower level alternative works, but completely misses much of the convenience of SB:
For a command (as opposed to a property as above), a similar approach from SO would be:
Directions for further research
Notes
To create application specific scripting definition:
sdef /path/to/application.app
The text was updated successfully, but these errors were encountered: