I'm trying to use scripting bridge with iTunes, but I'm getting an error - itunes

I'm trying to use scripting bridge to access album artwork with iTunes, but when I use the method
[iTunesApplication currentTrack];
I get an error saying that there is no know class method current track
It seems to work in other people's code, so what am I doing wrong? I don't think I'm trying to call it as a class method.

iTunesApplication *iTunes = [SBApplication applicationWithBundleIdentifier:#"com.apple.iTunes"];
[iTunes currentTrack];
should work.

Related

PlayAtTime Issue playing multiple audio files

All
I have two audio files (caf) which I want to my audioplayer play one after the other. Below is the code I am using
AVAudioPlayer *lSoundPlayer;
AVAudioPlayer *lSoundPlayer1;
NSTimeInterval timedelay = 2;
[lSoundPlayer play];
[lSoundPlayer1 playAtTime:timedelay];
When I compile I am getting a warning that the AVaudio player might not respond. When I try to execute I am getting exception. Can someone please help
You are sending a message to an object which is neither allocated nor it is initialized.
I suggest you have a look at the class reference and ask again if you have any further questions: http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVAudioPlayerClassReference/Reference/Reference.html

Opening a file using ScriptingBridge

I have an AppleScript that I am trying to convert to ScriptingBridge. Since my application is a C++/Obj-C application, ScriptingBridge is much easier to use and quite a bit faster (not to mention I hate dynamically building AppleScripts).
The AppleScript sends a message to Photoshop to open a file. The file parameter is sent as an alias, but ScriptingBridge imports the parameter as an id. I don't know what Obj-C object I should pass in?
I've tried passing an NSURL and an NSString (probably incorrectly :-P), but to no avail. Any suggestions on what I should be passing for the file alias?
The short answer is that you can't open documents in Photoshop with Scripting Bridge.
Apple's docs really spell it out like it is. All classes must have a container, which is a mutable array, that they need to be added to before they can be acted upon, as shown in the generated header...
#interface photoshopCS4Application : SBApplication
- (SBElementArray *) documents;
- (SBElementArray *) fonts;
- (SBElementArray *) notifiers;
... and that is the complete list of top-level containers available to us. The open command requires a photoshopCS4OpenOptions to be generated and populated. Because the API doesn't expose the array to store the newly created photoshopCS4OpenOptions object, we can't use a newly created photoshopCS4OpenOptions object. Therefore we can't make a target document and by extensions can't use the open command in Scripting Bridge. The same can be said of all the commands that require some kind of options object.
The only workaround that I have sorted out is to either open a document with native Applescript called from Cocoa or objc-appscript, and then parse the documents array looking for the one just opened. It's not ideal, but then neither is Scripting Bridge because it requires application developers write their scripting APIs in a very specific way that is not native to the OSA framework.
If your program is such that opening a Photoshop document can be executed outside your AppleScript script/Scripting Bridge code, Cocoa provides a method to open files with a specific application:
[[NSWorkspace sharedWorkspace] openFile:#"/Users/bavarious/Desktop/test.psd" withApplication:#"Adobe Photoshop CS4"];
or, if you want to use the default application that handles that file type, you can drop the application name altogether:
[[NSWorkspace sharedWorkspace] openFile:#"/Users/bavarious/Desktop/test.psd"];
Consider Appscript. http://appscript.sourceforge.net/
Here's the code using that:
APApplication *adobePhotoshopCs4 = [APApplication applicationWithName: #"Adobe Photoshop CS4"];
id result = [[adobePhotoshopCs4 open_] send];
(Note, I'm not a Cocoa programmer - I mainly use Appscript with Python but Appscript comes with ASTranslate which translates Applescript into Python, Ruby or Obj-C and that's the output - but I've found there are subtle mistakes in the past sometimes with the translator)

Xcode can't find headers in given framework

Messing round a little in Xcode, and I was trying to get my app to look at the users music library with the use of MPMediaPickerController.
Following Apples documentation, I added the MediaPlayer.framework to the project, and in my header I've imported , giving me something like this:
#import <GameKit/GameKit.h>
#import <MediaPlayer/MediaPlayer.h>
#interface HelloMusic : UIViewController
{
}
So far so simple. Now, as far as I'm aware I should be able to do
MPMediaPickerController *mp = [[MPMediaPickerController alloc] init];
in my main file and set about launching my picker. Unfortunately XCode stubbronly refuses to admit that there is such a thing as an MPMediaPickerController - if I type MP and hit escape to get code complations I am without any of the MPMedia family. Annoyingly Xcode does recognise any MPMovie... class (from the same framework!). If I try and run the app it compiles fine so it must at least recognise the header from the framework, then chunters along until I get to the assignment of MPMediaPickerController, at which point I get an EXC_BAD_ACCESS, with a console output of
Detected an attempt to call a symbol in system libraries that is not present on the iPhone:
pthread_mutexattr_destroy$UNIX2003 called from function _ZN4llvm3sys5MutexC2Eb in image
libLLVMContainer.dylib.
I'm... certain I'm doing something beyond stupid, but I'm stuck nevertheless.
As the class reference states, it's declared in MPMediaPickerController.h. As such, simply adding...
#import <MediaPlayer/MPMediaPickerController.h>
...should solve your problems. :-)

Add movie to iTunes using Scripting Bridge

I want to use Scripting Bridge to add a movie to iTunes. And preferably letting me choose between a 'music video' and a 'movie'. I know both Objective-C and AppleScript so I thought it wouldn't be that hard but I can't figure it out. I know how I would use NSAppleScript for it but I'm targeting 10.5 or later and read that Scripting Bridge obsoletes NSAppleScript. Is that right?
All I got is
iTunesApplication *iTunes = [SBApplication applicationWithBundleIdentifier: #"com.apple.iTunes"];
Which is, as you can see, not much at all.
Step 1. Generate iTunes.h header file:
sdef /Applications/iTunes.app | sdp -fh --basename "iTunes"
Step 2. The code to add a media file looks like the following:
NSString* sourceMediaFile = ...;
iTunesApplication *iTunes = [SBApplication applicationWithBundleIdentifier:#"com.apple.iTunes"];
iTunesTrack * track = [iTunes add:[NSArray arrayWithObject:[NSURL fileURLWithPath:sourceMediaFile]] to:nil];
NSLog(#"Added %# to track: %#",sourceMediaFile,track);
You should use the "scripting definition processor" (sdp) program to generate a header file from iTunes' scripting definition (.sdef) file (which you can get using the sdef program):
sdef /Applications/iTunes.app | sdp -fh --basename "iTunes"
This'll give you a file called iTunes.h. Then you include that header into your project and read through it to see what the iTunes scripting bridge interface offers.
If it seems like you won't be able to do this with the scripting bridge (it's possible -- not everything that can be done via an app's AppleScript interface can also be done via the scripting bridge), just go ahead and write an AppleScript to do it instead, and then execute that in your program with NSAppleScript.
For the second parameter, it takes a playlist object (or nil as previously mentioned). Once you have fetched an instance of a iTunesPlaylist* object through some means (there are several depending on your needs), you can pass it as the second parameter.

Make new chat in Adium using Cocoa ScriptingBridge

The following AppleScript code works fine:
tell application "Adium" to tell first account to make new chat with contacts {first contact} with new chat window
But how can I do the same using Cocoa's ScriptingBridge?
Generally, you ought to be able to do it following Apple's Scripting Bridge Programming Guide for Cocoa. To start, I created a header file for Adium by running sdef /Applications/Adium.app | sdp -fh --basename Adium in Terminal (creates Adium.h in the current directory). The header file produced gives clues about making the AppleScript calls via the Scripting Bridge.
The problem that I ran into is that I cannot see a way, based on the generated header file, to do make new chat with contacts {...} with new chat window (I can make a new chat and maybe even hook it into a new window, but I could not find a way to make that chat take the contact).
The next best thing might be to use NSAppleScript to execute your valid AppleScript code:
NSAppleScript *appleScript = [[NSAppleScript alloc] initWithSource:#"tell application \"Adium\" to tell first account to make new chat with contacts {first contact} with new chat window"];
NSDictionary *errorDictionary;
NSAppleEventDescriptor *eventDescriptor = [appleScript executeAndReturnError:&errorDictionary];
Short of using raw Apple event codes, you can't. Should work with objc-appscript though. Running your AppleScript command through appscript's ASTranslate tool produces the following:
#import "ADGlue/ADGlue.h"
ADApplication *adium = [ADApplication applicationWithName: #"Adium"];
ADReference *ref = [[adium accounts] at: 1];
ADMakeCommand *cmd = [[[[ref make] newChatWindow: ASTrue] withContacts: [NSArray arrayWithObject: [[[[adium accounts] at: 1] contacts] at: 1]]] new_: [ADConstant chat]];
id result = [cmd send];