Context: I'm working on a Pharo/Smalltalk -> Objective-C bridge
Scenario: In the following Objective-C ScriptingBridge snippet:
iTunesApplication *iTunes = [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
iTunesTrack *currentTrack = iTunes.currentTrack; //[1]
// This low level way works too
//iTunesTrack *currentTrack = [iTunes propertyWithCode: 'pTrk']; //[2]
[iTunes playpause]; //[3]
Problem: The bridge uses class_getInstanceMethod
to determine if an object understands a message/selector, but it returns NULL for scripting messages like playpause
Question #1
Why does class_getInstanceMethod
return NULL for scripting messages like playpause
? Same question for class_copyMethodList
? What is special about scripting messages that they do not act like other Obj-C messages (except when they do!)?
Question #2 [SOLVED - see @Matt's answer]
Where, as per the docs, in the "dynamically defined subclass for the iTunes application" does SB put the "application-specific methods that handle the sending of Apple events automatically"? And, given that class_getInstanceMethod
fails to find this behavior (see below), what's a reliable way for the bridge to test for it (i.e. whether such a method/message exists)?
The Objective-C Runtime API reports mixed results. On one hand, the iTunesApplication
class seems not to have any methods (or properties for that matter):
class_copyMethodList([iTunes class]...
returns zero methodsclass_getInstanceMethod
, which the bridge uses to find and execute methods, fails.
On the other, #playpause
can be queried and sent through other parts of the API:
respondsToSelector:
-> TRUEmethodSignatureForSelector:
returns 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.
Question #3 [SOLVED]
How one would simulate/replicate [3]?
Answered by @Willeke in comments: [iTunes sendEvent:'hook' id:'PlPs' parameters:0]