Skip to content

Instantly share code, notes, and snippets.

@risacher
Last active November 13, 2018 16:50
Show Gist options
  • Save risacher/7739854 to your computer and use it in GitHub Desktop.
Save risacher/7739854 to your computer and use it in GitHub Desktop.
NodObjC, iTunes, Scripting Bridge example
var util = require('util');
require('NodObjC/global');
framework('ScriptingBridge');
var iTunes = SBApplication('applicationWithBundleIdentifier',
NSString('stringWithUTF8String', 'com.apple.iTunes'));
if (!iTunes('isRunning')) {
console.log('iTunes is not running');
iTunes('run')
}
console.log(0, iTunes('name'), iTunes('name').toString());
var sel = iTunes('selection');
console.log('sel.getClassName', sel.getClassName());
console.log('sel.getClassName', sel.methods());
sel = sel('get');
console.log('sel.getClassName(post-get)', sel.getClassName());
console.log('sel.methods(post-get)', sel.methods());
console.log('iTunes.methods', iTunes.methods());
console.log('iTunes(sources).methods', iTunes('sources').methods());
console.log('iTunes(sources)(count)', iTunes('sources')('count'));
// My technique for figuring out how to work objects with ScriptingBridge
// is to print the object, which tells me the type of the object.
// Then, call methods(n) to learn what methods it supports. The other
// non-obvious issue is when to call the ('get') method, which forces
// evaluation of the object
// Also useful to start AppleScript Editor, and do "File->Open
// Dictionary" for the application that you are trying to script.
console.log('iTunes(sources)(objectAtLocation,0)', iTunes('sources')('objectAtIndex',0));
// The parameter 3 for the methods(3) call says how many parent
// classes to recurse through when compiling the list of methods
console.log('iTunes(sources)(objectAtLocation,0).methods', iTunes('sources')('objectAtIndex',0).methods(3));
console.log('iTunes(sources)(objectAtLocation,0)(name)', iTunes('sources')('objectAtIndex',0)('name'));
var playlist_sbarray = iTunes('sources')('objectAtIndex',0)('playlists');
// I'd like to use initWithProperties instead, but don't know how yet
//var new_pl = iTunes('classForScriptingClass',$('playlist'))('alloc')('initWithProperties',
// { name: $('s-TESTPLAYLIST') });
var new_pl = iTunes('classForScriptingClass',$('playlist'))('alloc')('init');
console.log('new_pl', new_pl);
console.log('playlist_sbarray', playlist_sbarray);
// the setName call MUST be after the insertObject call because until it's inserted somewhere, it doesn't really exist
playlist_sbarray('insertObject', new_pl, 'atIndex', 0);
new_pl('setName',$('s-TESTPLAYLIST'));
console.log('playlist_sbarray(count)', playlist_sbarray('count'));
for (var i = playlist_sbarray('count')-1; i>=0; i--) {
var pl = playlist_sbarray('objectAtIndex',i);
console.log(pl('name'));
if (pl('name').toString() === 's-Temp') {
console.log(pl.methods(2));
pl('delete');
}
if (pl('name').toString() === 's-Sublime') {
console.log(pl('tracks'));
var tracks_sbary = pl('tracks');
for (var trackidx = 0; trackidx < tracks_sbary('count'); trackidx++) {
var track_sb = tracks_sbary('objectAtIndex', trackidx);
console.log(track_sb);
if (trackidx === 0) {
console.log(track_sb.methods(5));
// the ('get') method below converts from an ITunesTrack to an ITunesFileTrack
// necessary to fetch the 'location'
console.log(track_sb('get')('location')('path'));
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment