Hi,
I'm looking for a way to get all the iTunes artists and their albums in a tree (like the playlists in iTunes which I get like it).
I tried an algo where I get all the media items filtered by mediaKind == .kindSong sorted by artist and after that, I "while" loop in all the media items count (about 36 000 for me (iTunes user for 15 years 😝)) to filter them by artist name and after that by album title so each time, I increase the i + the count of the results to go to the next artist and then next album for each artist.
It is working but it is very slow. I think it is because of the array filter function of the media items list which loop into all the array (right ?) to find the criteria. But as I sorted it just before to start the loop, it could be faster to stop it as soon as the artist name is not the same than the previous (or something like that...).
Here is the 2 main func I use :
static func getArtistsTree(theITTracks: [ITLibMediaItem], theLenght: Int) -> [Artist] {
var theArtists: [Artist] = [Artist]() // just a custon obj to record the artists
let theArtistNames = getAllArtistNames(theITTracks: theITTracks).sorted()
for theArtistName in theArtistNames {
let theArtistResults = theITTracks.filter({$0.artist?.name?.lowercased() == theArtistName.lowercased()}).sorted(by: {self.sortITTrack(ITTrack1: $0, ITTrack2: $1, kind: ITSortKind.album)})
print("V&G_Project___theArtistResult.count : ", theArtistResults.count)
var i: Int = 0
while i < theArtistResults.count {
let theArtistTrack = theArtistResults[i]
if let theAlbumTitle = theArtistTrack.album.title {
let theAlbumResults = theArtistResults.filter({$0.album.title?.lowercased() == theAlbumTitle.lowercased()})
print("V&G_Project___name : ", theArtistTrack.artist?.name, " - ", theAlbumTitle, "theAlbumResults.count : " + String(theAlbumResults.count))
var j: Int = 0
while j < theAlbumResults.count {
let theAlbum = theAlbumResults[j]
let theTracksResults = theAlbumResults.filter({$0.album.title?.lowercased() == theAlbumTitle.lowercased()})
j += 1
}
i += theAlbumResults.count
} else {
i += 1
}
}
print("V&G_Project___--------------- : ")
}
return theArtists
}
static func getAllArtistNames(theITTracks: [ITLibMediaItem]) -> [String] {
var theArtistsList: [String] = [String]()
for theITTrack in theITTracks {
let theArtistName = theITTrack.artist?.name
var theToto: String = "unknown"
if let theArtistName = theArtistName {
theToto = theArtistName
}
let theIndex = theArtistsList.index(of: theToto)
print("V&G_Project___getAllArtistNames : ", theIndex)
if theIndex == nil {
theArtistsList.append(theToto)
}
}
return theArtistsList
}
do {
let lib = try ITLibrary(apiVersion: "1.0")
let theITTracks = lib.allMediaItems.filter({$0.mediaKind == .kindSong})
let theArtistsTree = iTunesModel.getArtistsTree(theITTracks: theITTracks, theLenght: theITTracks.count)
} catch let error {
print("V&G_Project___<#name#> : ", error)
}
I can use only one func to save one loop but even with one, everything works fine but the algorythm is very slooooww and I need to improve it.
Any idea ?
Thx.