diff --git a/ios/App/App/plugins/AbsDownloader.swift b/ios/App/App/plugins/AbsDownloader.swift index ea68e482..4f33b51f 100644 --- a/ios/App/App/plugins/AbsDownloader.swift +++ b/ios/App/App/plugins/AbsDownloader.swift @@ -22,61 +22,84 @@ public class AbsDownloader: CAPPlugin { call.resolve() } else { NSLog("Got library item from server \(libraryItem!.id)") - - self.startLibraryItemDownload(libraryItem: libraryItem!) + self.startLibraryItemDownload(item: libraryItem!) call.resolve() } } } - func startLibraryItemDownload(libraryItem: LibraryItem) { - let length = libraryItem.media.tracks?.count ?? 0 + private func startLibraryItemDownload(item: LibraryItem) { + let length = item.media.tracks?.count ?? 0 if length > 0 { - libraryItem.media.tracks?.enumerated().forEach { position, track in - NSLog("TRACK \(track.contentUrl!)") - // filename needs to be encoded otherwise would just use contentUrl - let filename = track.metadata?.filename ?? "" - let filenameEncoded = filename.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed) - let urlstr = "\(Store.serverConfig!.address)/s/item/\(libraryItem.id)/\(filenameEncoded ?? "")?token=\(Store.serverConfig!.token)" - let url = URL(string: urlstr)! - - let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] - let itemDirectory = documentsDirectory.appendingPathComponent("\(libraryItem.id)") - NSLog("ITEM DIR \(itemDirectory)") - - // Create library item directory - do { - try FileManager.default.createDirectory(at: itemDirectory, withIntermediateDirectories: false) - } catch { - NSLog("Failed to CREATE LI DIRECTORY \(error)") - } - - // Output filename - let trackFilename = itemDirectory.appendingPathComponent("\(filename)") - - let downloadTask = URLSession.shared.downloadTask(with: url) { urlOrNil, responseOrNil, errorOrNil in - - guard let fileURL = urlOrNil else { return } - - do { - NSLog("Download TMP file URL \(fileURL)") - let audioData = try Data(contentsOf:fileURL) - try audioData.write(to: trackFilename) - NSLog("Download written to \(trackFilename)") - } catch { - NSLog("FILE ERROR: \(error)") - } - } - downloadTask.resume() + item.media.tracks?.enumerated().forEach { position, track in + startLibraryItemTrackDownload(item: item, position: position, track: track) } } else { NSLog("No audio tracks for the supplied library item") } -// let encoder = JSONEncoder() -// let jsobj = try encoder.encode(Download) -// notifyListeners("onItemDownloadComplete", data: jsobj) + } + + private func startLibraryItemTrackDownload(item: LibraryItem, position: Int, track: AudioTrack) -> URLSessionDownloadTask? { + NSLog("TRACK \(track.contentUrl!)") + + // If we don't name metadata, then we can't proceed + guard let filename = track.metadata?.filename else { + NSLog("No metadata for track, unable to download") + return nil + } + + let serverUrl = urlForTrack(item: item, track: track) + let itemDirectory = createLibraryItemFileDirectory(item: item) + let localUrl = itemDirectory.appendingPathComponent("\(filename)") + + return downloadTrack(serverUrl: serverUrl, localUrl: localUrl) + } + + private func urlForTrack(item: LibraryItem, track: AudioTrack) -> URL { + // filename needs to be encoded otherwise would just use contentUrl + let filenameEncoded = track.metadata?.filename.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed) + let urlstr = "\(Store.serverConfig!.address)/s/item/\(item.id)/\(filenameEncoded ?? "")?token=\(Store.serverConfig!.token)" + return URL(string: urlstr)! + } + + private func createLibraryItemFileDirectory(item: LibraryItem) -> URL { + let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] + let itemDirectory = documentsDirectory.appendingPathComponent("\(item.id)") + + NSLog("ITEM DIR \(itemDirectory)") + + // Create library item directory + do { + try FileManager.default.createDirectory(at: itemDirectory, withIntermediateDirectories: false) + } catch { + NSLog("Failed to CREATE LI DIRECTORY \(error)") + } + + return itemDirectory + } + + private func downloadTrack(serverUrl: URL, localUrl: URL) -> URLSessionDownloadTask { + let downloadTask = URLSession.shared.downloadTask(with: serverUrl) { urlOrNil, responseOrNil, errorOrNil in + + guard let fileURL = urlOrNil else { return } + + do { + NSLog("Download TMP file URL \(fileURL)") + let audioData = try Data(contentsOf:fileURL) + try audioData.write(to: localUrl) + NSLog("Download written to \(localUrl)") + } catch { + NSLog("FILE ERROR: \(error)") + } + } + + // Start the download + downloadTask.resume() + + return downloadTask } } + struct DownloadItem: Codable { var isDownloading = false var progress: Float = 0