Sobes.tech
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))