Itunes Music

Has anyone played with reading the iTunes Library?

My question has to due with the “PersistentID” fields (albumPersistentID, genrePersistentID etc.)
The Apple docs indicate that these values “can change”, but it is unclear as to exactly when, and if there is a way to quickly tell if it actually has been.

The reason, is I am attempting to create a SQLite Relational database using those ID as “keys”, and really only want to refresh the database is I need to…
iTunes does use these as its keys, but then IT knows when it changed them :slight_smile:

I’m bumping this. Have an idea for iOS, wondering if anyone had accessed the Music library on iOS devices? I’m guessing declares to get the picker up?

Thanks

I have written an entire iOS app that reads and uses the iTunes music database and playlists… HOWEVER… it is written is Swift

lol. I did write something a few years back in Objective C that read the iTunes database when I was testing. :slight_smile:

never mind - on iOS - :stuck_out_tongue:
Surprised no one has this in iOS lib already

here are some SWIFT snippets that might help someone put together a class or two

// last update date
let iTunesLastUpdated = "\\(MPMediaLibrary.defaultMediaLibrary().lastModifiedDate)"


    let songQuery = MPMediaQuery.songsQuery()
    songQuery.groupingType = .AlbumArtist

    if let result = songQuery.items {


        seqNum=0
        let intCnt=(result.count/10)
        totCnt=intCnt
        let rCnt=Float(result.count)
        for song in result { //
            let dur=song.valueForProperty(MPMediaItemPropertyPlaybackDuration) as! Double
            if (song.cloudItem==false) && (song.mediaType == .Music) && (dur>=30) { // local music only, longer than 30 seconds
                let songName  : String = song.title! 
                // MUST be ios9.2 or above
                if song.protectedAsset==false { // gotta skip any OLD DRM protected songs :(
                    seqNum+=1
                    //
                    let songID    : String = String(song.persistentID,radix:16)
                    let songTrack : Int    = song.albumTrackNumber
                    var albumID   : String = String(song.albumPersistentID,radix:16) //String(format:"%021x",song.albumPersistentID)
                    var genreID   : String = String(song.genrePersistentID,radix:16)
                    var artistID  : String = String(song.artistPersistentID,radix:16)
                    let URL       : String = song.assetURL!.absoluteString
                    //
                    if song.artist?.isEmpty==false {
                        artistName = "\\(song.artist!)"
                    } else {
                        artistID = "??"
                    }
                    //
                    if song.albumTitle?.isEmpty==false {
                        albumName = "\\(song.albumTitle!)"
                    } else {
                        albumID = "??"
                    }
                    //
                    if song.genre?.isEmpty==false {
                        genreName = "\\(song.genre!)"
                    } else {
                        genreID = "??"
                    }
                }
            }
        }
    }

    //
    // Collect PlayLists (and the songs ON them)
    //
    playListID=0
    let pquery = MPMediaQuery.playlistsQuery()
    if let presult = pquery.collections {
        for playlist in presult {
            if playlist.count>0 {
                playListID   += 1
                playListName  = playlist.valueForProperty(MPMediaPlaylistPropertyName) as! String
                playListCount = 0 // count ONLY Music!
                for song in playlist.items {
                    if (song.cloudItem==false) && (song.mediaType == .Music) { // local music only
                        let songID    : String =  String(song.persistentID,radix:16)
                    }
                }
            }
        }
    }

This code is for illustration purposes only, and I have removed all the database interface code that stored the collected information. Note : Itunes does have “relational” tables but I found that only SONGQUERY actually contained all the data elements…

I have some MP classes already written which would allow the replication of Dave’s code but they are currently private. Maybe I’ll polish and publish them if I have some time and there is interest?

1 Like

Thanks all. I’ll do some experimenting later this summer. If others come out of the woodwork and interested, then that would be great, but don’t spend any time just on the account of me :slight_smile:

Are you reading the original database file or the XML backup file? The latter I presume :slight_smile:

if by “you” you meant “me”, then I’m reading the iTunes database directly, but as specified in my above posts, it is using Swift, up to you to figure out how to leverage Xojo to do it.

Ok, so you can also write to the database then? That’s cool. I use it for reading purposes only and for that the xml file is just as useful.

Swift and iTunes are both from Apple, so that connection is an easy one. Accessing iTunes DB from Xojo is not a possibility.

Could I write to it… probably… do I? no.
As to Xojo, I posted that Swift code (years ago) with the intention that someone might make a Xojo interface, which Jason has indicated he might do. I can only assume there wasn’t enough interest for him to pursue it.

My personal opinion (as stated before) is the “Xojo for iOS” is at best a toy, and a very expensive one at that

I agree, I only have the desktop license for Real Studio 2012 at the moment :wink:

I’m considering buying a new Xojo license and I’ve looked at the Web and iOS licenses, but for my purposes I only need the desktop license. Since 64 bit is becoming a “must” on the Mac I need to make a decision soon.

I am in this same boat… I have Xojo2016… but since I’m now on a fixed income, I need to hedge my bets and hope that Xojo2018 becomes stable soon. I have a few programs (Tadpole for one) that needs to be updated to 64bit, but I also want to be able to use the latest SQLite release.