views:

108

answers:

2

I'm having a problem with the Scripting Bridge framework in 10.5. Specifically, I use this code to create a new user playlist in iTunes:

NSDictionary *propertiesDict = [NSDictionary dictionaryWithObject:@"playlistName" forKey:@"name"];
playlistToReturn = (iTunesUserPlaylist*)[[[iTunesApp classForScriptingClass:@"user playlist"] alloc] initWithProperties:propertiesDict];
SBElementArray *sourcesArray = [iTunesApp sources];
iTunesSource *librarySource = [sourcesArray objectAtIndex:0];
SBElementArray *userPlaylistsArray = [librarySource userPlaylists];
[userPlaylistsArray addObject:playlistToReturn];

This code works fine in 10.6. The playlist is created correctly, and I can add songs to it later.

However, on 10.5, an error is generated:

Apple event:'core'\'crel'{
'kocl':'cUsP',
'insh':'insl'{
              'kobj':'obj '{
                            'want':'cUsP',
                            'from':'obj '{
                                          'want':'cSrc',
                                          'from':'null'(),
                                          'form':'ID  ',
                                          'seld':42 },
                            'form':'indx',
                            'seld':'abso'($206C6C61$) },
              'kpos':'end ' },
'prdt':{
              'pnam':'utxt'("playlistName") }
};

Error Domain=SBError Code=-10014 UserInfo=0x152c8cb0 "Operation could not be completed. (SBError error -10014.)"

Why?

A: 

Peter: Thanks for your link, that was enough to get me to start looking for a different solution.

Since 10.5 apparently can't handle creation of objects very well, I've modified the way I create the empty playlist. Instead what I do is create an XML object for the empty playlist, and then use Scripting Bridge's add:to: command which successfully adds the playlist. Then I use Scripting Bridge to search for the newly created playlist. Here's some relevant code:

    NSDictionary *innerDictionary = [NSDictionary dictionaryWithObject:playlistName forKey:@"Name"];
    NSArray *innerArray = [NSArray arrayWithObject:innerDictionary];
    NSDictionary *outerDictionary = [NSDictionary dictionaryWithObject:innerArray forKey:@"Playlists"];

    [outerDictionary writeToFile:pathToWriteXMLFile atomically:YES];
    [iTunesApp add:[NSArray arrayWithObject:[NSURL fileURLWithPath:pathToWriteXMLFile]] to:nil];

This successfully creates the playlist on 10.5. Then, to actually retrieve the iTunesUserPlaylist* object:

    SBElementArray *playlistArray = [[[iTunesApp sources] objectAtIndex:0] userPlaylists];
    NSPredicate *playlistPredicate = [NSPredicate predicateWithFormat:@"name == %@",playlistName];
    NSArray *playlistSearchArray = [playlistArray filteredArrayUsingPredicate:playlistPredicate];

Note that you can be even more rigorous by looping through the playlistSearchArray and checking whether the playlist is empty -- since it's a newly created playlist, that's the one you want.

Simone Manganelli
A: 

I have an application that does this and works on 10.5. The only difference I can see between your code and mine is the last line. I use the following...

[userPlaylistsArray insertObject:playlistToReturn atIndex:0];

Give it a try...

regulus6633
This doesn't seem to work for me. I also got an error when I used insertObject:atIndex:, unless I cast userPlaylistsArray as an NSMutableArray.
Simone Manganelli