Junior — Senior
Create a manager to merge tracks from multiple albums
livecode
Task condition
It is necessary to implement a manager that collects track lists from different albums and outputs a combined result.
struct Song: CustomStringConvertible {
let title: String
var description: String { title }
}
protocol AlbumProvider {
func loadSongs(albumId: String, completion: @escaping ([Song]) -> Void)
}
final class AlbumService: AlbumProvider {
func loadSongs(albumId: String, completion: @escaping ([Song]) -> Void) {
DispatchQueue.global().async {
let songs: [Song]
switch albumId {
case "1":
songs = [
Song(title: "One, 1"),
Song(title: "Two, 1"),
Song(title: "Three, 1"),
Song(title: "Four, 1")
]
case "2":
songs = [
Song(title: "One, 2"),
Song(title: "Two, 2"),
Song(title: "Three, 2")
]
case "3":
songs = [
Song(title: "One, 3"),
Song(title: "Two, 3")
]
default:
songs = []
}
DispatchQueue.main.asyncAfter(deadline: .now() + Double.random(in: 0.1...0.4)) {
completion(songs)
}
}
}
}
final class SongsManager {
let albumService = AlbumService()
func loadSongs(albumIds: [String], completion: @escaping ([Song]) -> Void) {
// Implement loading tracks from all given albums and return a single array
var allSongs: [Song] = []
let group = DispatchGroup()
for albumId in albumIds {
group.enter()
albumService.loadSongs(albumId: albumId) { songs in
allSongs.append(contentsOf: songs)
group.leave()
}
}
group.notify(queue: .main) {
completion(allSongs)
}
}
}
let manager = SongsManager()
let albumIds: [String] = ["1", "2", "3"]
manager.loadSongs(albumIds: albumIds) { songs in
// Output the combined list of tracks
print(songs)
}
RunLoop.main.run(until: Date(timeIntervalSinceNow: 3))