I'm creating a music player. It plays tracks from device memory (from Documents folder).
I ran into a problem that when there are many tracks (200 or more), then at the moment of loading the list of tracks, my interface freezes. I searched for the source of the problem for a long time, tried different options and I found it - this is the function createPlayerQueue
in which I create the playerQueue.
I want to understand: is this really taking so much resources from the device or is my code not very good? How can I solve this problem?
func createPlayerQueue(from content: [URL]) -> [AVPlayerItem] {
var playerQueue: [AVPlayerItem] = []
let items = content.map { AVURLAsset(url: $0) }.map { AVPlayerItem(asset: $0) } //at this point the interface freezes
playerQueue = items
return playerQueue
}
I use function result to create my models:
private var playerQueue: [AVPlayerItem] = []
func setupTrackModels(content: [URL]) -> [TrackModelProtocol] {
playerQueue = audioPlayer.createPlayerQueue(from: content)
var tracks: [TrackModelProtocol] = []
for index in 0..<playerQueue.count {
var artwork: UIImage?
let playerItem = playerQueue[index]
let metadataList = playerItem.asset.metadata
for item in metadataList {
guard let key = item.commonKey?.rawValue, let value = item.value else {
continue
}
switch key {
case "artwork" where value is Data:
artwork = UIImage(data: value as! Data)
default:
continue
}
}
let track = TrackFromDeviceMemory(
fileName: content[index].lastPathComponent,
duration: playerQueue[index].asset.duration.seconds,
artwork: artwork,
url: content[index].absoluteURL)
tracks.append(track)
}
return tracks
}
I call this function in the viewWillAppear
function so that I can get the actual list of files every time I return to this view.