1

I test a little OSX app based on this example which use a bridge to AppleScript to get simple infos from iTunes.

Like I said in the ComboDrums's comment (it's me), I have a script to get all my iTunes playlists in a tree but as soon as the return is more complex than a simple string, it fails.

So I'm looking for the way to convert the AppleScript's list returned to a Swift friendly object.

Any idea ?

Thx.

Script:

to getStaticPlaylistsTree()
    tell application "iTunes"
        set theList to {{theName:"Bibliothèque", theID:"66270731FDBE2C50", isFolder:false, theClass:library playlist, isSmart:false, theCount:37581}, {theName:"Clips vidéo", theID:"07D5032B96891D67", isFolder:false, theClass:user playlist, isSmart:true, theCount:283}}
    end tell
    return theList
end getStaticPlaylistsTree
Willeke
  • 14,578
  • 4
  • 19
  • 47
user10177193
  • 35
  • 1
  • 6
  • Post your code please. – Willeke Jan 20 '19 at 15:10
  • The code is in the project example (https://github.com/hhas/Swift-AppleScriptObjC). I just added a method to get a static tree of some playlists like : to getStaticPlaylistsTree() tell application "iTunes" set theList to {{theName:"Bibliothèque", theID:"66270731FDBE2C50", isFolder:false, theClass:library playlist, isSmart:false, theCount:37581}, {theName:"Clips vidéo", theID:"07D5032B96891D67", isFolder:false, theClass:user playlist, isSmart:true, theCount:283}} end tell return theList. Thx. – user10177193 Jan 20 '19 at 15:16
  • Please post the formatted code in the question. – Willeke Jan 20 '19 at 16:20
  • I can't format the code because I can't post answer with my account... So sorry but I can't. Can you copy/paste the code in a simple AppleScript script? It is the same... to getStaticPlaylistsTree() tell application "iTunes" set theList to {{theName:"Bibliothèque", theID:"66270731FDBE2C50", isFolder:false, theClass:library playlist, isSmart:false, theCount:37581}, {theName:"Clips vidéo", theID:"07D5032B96891D67", isFolder:false, theClass:user playlist, isSmart:true, theCount:283}} end tell return theList end getStaticPlaylistsTree – user10177193 Jan 21 '19 at 14:14

1 Answers1

1

Firstly, Create the swift class or struct with a constructor having NSDictionary as parameter

struct SwiftModel {

    // Declare attributes

    init(dictionary: NSDictionary) {
        self.isFolder = dictionary.value(forKey: "isFolder") as! Bool
        self.isSmart = dictionary.value(forKey: "isSmart") as! Bool
        self.theCount = dictionary.value(forKey: "theCount") as? Int
        self.theID = dictionary.value(forKey: "theID") as? String
        self.theName = dictionary.value(forKey: "theName") as? String
        self.theClass = (dictionary.value(forKey: "theClass") as? NSAppleEventDescriptor)
    }
}

Then, Using flatMap or compactMap convert apple script list to Swift Array.

let listFromAppleScript = // List returned from apple script i.e self.iTunesBridge.getStaticPlaylistsTree
let staticPlayListTree = listFromAppleScript?.compactMap({SwiftModel(dictionary: $0 as! NSDictionary)})
print(staticPlayListTree![0].theName)

Output: Optional("Bibliothèque")

Bharat Gadde
  • 173
  • 1
  • 10
  • Ok thank you. CompactMap return a tree of the AppleScript list and flatMap an flat array of the list, right ? – user10177193 Jan 22 '19 at 15:36
  • And also, the getStaticPlaylistsTree to declare in the iTunesBridge.swift protocol needs to return a [NSString:AnyObject]? like in the trackInfo ? Thx. – user10177193 Jan 22 '19 at 15:53
  • getStaticPlaylists can be of type [NSDictionary] or [[String:Any]] – Bharat Gadde Jan 22 '19 at 16:48
  • in this scenario you can use either compactMap or flatMap but for more clarification you can refer https://stackoverflow.com/questions/49291057/difference-between-flatmap-and-compactmap-in-swift – Bharat Gadde Jan 22 '19 at 16:53
  • Ok thank you. But how the map do to get the children’s tree ? In my example there is no children but in the final tree there are a lot in the theChildren property. – user10177193 Jan 22 '19 at 16:55
  • For the moment I can get the children but I’m not able to loop in it like I do with the first level of items. I cast them as Dictionary in the struct but for recursives items, it is not enough and I need to call a recursive function instead, right ? Thx. – user10177193 Jan 23 '19 at 03:30
  • Yes. As in question the return type of getStaticPlaylists is list of dictionary so the code works. But if getStaticPlaylists is returning some different type then it's better to change accordingly. – Bharat Gadde Jan 23 '19 at 04:59
  • Ok, almost done ! I have one more problem : I try to show the data in a Source List (NSOutlineView with only one column). I followed this tuto https://www.youtube.com/watch?v=_SvZiUF-ShM but if I try to use the staticPlayListTree directly in the dict.setObject(staticPlayListTree!, forKey: "theChildren" as NSCopying), it fails and I have to rebuild a tree with fresh new object with @objc dynamic var properties. I think it is because the NSOutlineView works like that and is waiting for dynamic var, right ? Or how can I do ? Thx a lot. – user10177193 Jan 23 '19 at 20:58