tingraldi/SwiftScripting

Create an iTunes Playlist?

bvanderw opened this issue · 2 comments

Hi,

Thanks for this code - very helpful! I updated the code to use Swift 3 and all is well, except that I can't seem to figure out how to create an iTunes playlist. I had this obj-c code:

-(iTunesUserPlaylist*)createPlaylist:(NSString*)playlistName
{
  iTunesUserPlaylist* playlist = [librarySource.playlists objectWithName:playlistName];
  if (playlist.exists)
    [playlist delete];
  playlist = (iTunesUserPlaylist*)[[[iTunesApp classForScriptingClass:@"playlist"] alloc] init];
  [librarySource.playlists addObject:playlist];
  playlist.name = playlistName;
  return playlist;
}

I've tried this:

func createPlaylist(_ playlistName: String) -> iTunesUserPlaylist
{
  let playlist = objectWithApplication(iTunesApp, scriptingClass: "playlist") as iTunesUserPlaylist
  var playlists = librarySource.playlists!().get()!
  playlists.append(playlist)
  playlist.setName!(playlistName)
  return playlist
}

It crashes on the call to setName. What am I doing wrong?

You were very close to a working solution. There are two issues. As written, the playlists variable will end up being a Swift._SwiftDeferredNSArray, which is apparently immutable. This is in spite of the fact that it is actually an SBElementArray which is a subclass of NSMutableArray. Second, the call to append should be a call to add instead. I was surprised to see no error thrown on the call to append, but I didn't run that down to find the reason.

To work around the array class issue, you can chain together the playlists()! and the add() operations. Here's a working example:

#!/usr/bin/xcrun swift -F /Library/Frameworks

import iTunesScripting
import ScriptingUtilities 

let iTunesApp = application(name: "iTunes") as! iTunesApplication
let sources = iTunesApp.sources!() as! [iTunesSource]
let librarySource = sources.first!

func createPlaylist(_ playlistName: String) -> iTunesUserPlaylist {
  let playlist = objectWithApplication(iTunesApp, scriptingClass: iTunesScripting.playlist) as iTunesUserPlaylist
  librarySource.playlists!().add(playlist)

  playlist.setName!(playlistName)
  return playlist
}

let playlist = createPlaylist("Scripting Test")
playlist.reveal!()
iTunesApp.activate()