Compare commits

...

3 Commits

Author SHA1 Message Date
tanhakabir d78536033a Release 7.5.0 2021-09-27 17:34:13 -07:00
tanhakabir 73bc016d9d Shorten timeout to 30 seconds 2021-09-27 17:28:17 -07:00
tanhakabir 911f47e1e2 Push up error messages from download layer 2021-09-27 17:03:16 -07:00
6 changed files with 27 additions and 12 deletions
+4
View File
@@ -1,5 +1,9 @@
# Changelog
## 7.5.0
- Propagate up any errors from downloading audio. This will cause breaking changes to `SAPlayer.Downloader.downloadAudio(...)`
## 7.3.0
- Take in PR from @cntrump to use the non-deprecated subscription pattern in loop feature
@@ -280,8 +280,15 @@ class ViewController: UIViewController {
} else {
downloadButton.setTitle("Cancel 0%", for: .normal)
isDownloading = true
SAPlayer.Downloader.downloadAudio(withRemoteUrl: selectedAudio.url, completion: { [weak self] url in
SAPlayer.Downloader.downloadAudio(withRemoteUrl: selectedAudio.url, completion: { [weak self] (url, error) in
guard let self = self else { return }
guard error == nil else {
DispatchQueue.main.async {
self.currentUrlLocationLabel.text = "ERROR! \(error!.localizedDescription)"
}
return
}
DispatchQueue.main.async {
self.currentUrlLocationLabel.text = "saved to: \(url.lastPathComponent)"
self.selectedAudio.addSavedUrl(url)
+3 -3
View File
@@ -49,7 +49,7 @@ protocol AudioDataManagable {
func deleteStream(withRemoteURL url: AudioURL)
func getPersistedUrl(withRemoteURL url: AudioURL) -> URL?
func startDownload(withRemoteURL url: AudioURL, completion: @escaping (URL) -> ())
func startDownload(withRemoteURL url: AudioURL, completion: @escaping (URL, Error?) -> ())
func cancelDownload(withRemoteURL url: AudioURL)
func deleteDownload(withLocalURL url: URL)
}
@@ -171,12 +171,12 @@ extension AudioDataManager {
return FileStorage.Audio.locate(url.key)
}
func startDownload(withRemoteURL url: AudioURL, completion: @escaping (URL) -> ()) {
func startDownload(withRemoteURL url: AudioURL, completion: @escaping (URL, Error?) -> ()) {
let key = url.key
if let savedUrl = FileStorage.Audio.locate(key), FileStorage.Audio.isStored(key) {
globalDownloadProgressCallback(key, 1.0)
completion(savedUrl)
completion(savedUrl, nil)
return
}
@@ -35,7 +35,7 @@ protocol AudioDataDownloadable: AnyObject {
func getProgressOfDownload(withID id: ID) -> Double?
func start(withID id: ID, withRemoteUrl remoteUrl: URL, completion: @escaping (URL) -> ())
func start(withID id: ID, withRemoteUrl remoteUrl: URL, completion: @escaping (URL, Error?) -> ())
func stop(withID id: ID, callback: ((_ dataSoFar: Data?, _ totalBytesExpected: Int64?) -> ())?)
func pauseAllActive() //Because of streaming
func resumeAllActive() //Because of streaming
@@ -56,6 +56,7 @@ class AudioDownloadWorker: NSObject, AudioDataDownloadable {
config.isDiscretionary = !allowsCellularDownload
config.sessionSendsLaunchEvents = true
config.allowsCellularAccess = allowsCellularDownload
config.timeoutIntervalForRequest = 30
return URLSession(configuration: config, delegate: self, delegateQueue: nil)
}()
@@ -89,7 +90,7 @@ class AudioDownloadWorker: NSObject, AudioDataDownloadable {
return activeDownloads.filter { $0.info.id == id }.first?.progress
}
func start(withID id: ID, withRemoteUrl remoteUrl: URL, completion: @escaping (URL) -> ()) {
func start(withID id: ID, withRemoteUrl remoteUrl: URL, completion: @escaping (URL, Error?) -> ()) {
Log.info("startExternal paramID: \(id) activeDownloadIDs: \((activeDownloads.map { $0.info.id } ).toLog)")
let temp = activeDownloads.filter { $0.info.id == id }.count
guard temp == 0 else {
@@ -204,7 +205,7 @@ extension AudioDownloadWorker: URLSessionDownloadDelegate {
completionHandler(task.info.id, nil)
for handler in task.info.completionHandlers {
handler(destinationUrl)
handler(destinationUrl, nil)
}
activeDownloads = activeDownloads.filter { $0 != task }
@@ -238,6 +239,9 @@ extension AudioDownloadWorker: URLSessionDownloadDelegate {
for download in activeDownloads {
if download.task == task {
for handler in download.info.completionHandlers {
handler(download.info.remoteUrl, e)
}
completionHandler(download.info.id, e)
activeDownloads = activeDownloads.filter { $0.task != task }
}
@@ -281,7 +285,7 @@ extension AudioDownloadWorker {
let id: ID
let remoteUrl: URL
let rank: Int
var completionHandlers: [(URL) -> ()]
var completionHandlers: [(URL, Error?) -> ()]
func hash(into hasher: inout Hasher) {
hasher.combine(id)
@@ -328,11 +332,11 @@ extension Set where Element == AudioDownloadWorker.DownloadInfo {
return ret
}
mutating func updatePreservingOldCompletionHandlers(withID id: ID, withRemoteUrl remoteUrl: URL, completion: ((URL) -> ())? = nil) -> AudioDownloadWorker.DownloadInfo {
mutating func updatePreservingOldCompletionHandlers(withID id: ID, withRemoteUrl remoteUrl: URL, completion: ((URL, Error?) -> ())? = nil) -> AudioDownloadWorker.DownloadInfo {
let rank = Date.getUTC()
let tempHandlers: [(URL) -> ()] = completion != nil ? [completion!] : []
let tempHandlers: [(URL, Error?) -> ()] = completion != nil ? [completion!] : []
var newInfo = AudioDownloadWorker.DownloadInfo.init(id: id, remoteUrl: remoteUrl, rank: rank, completionHandlers: tempHandlers)
+1 -1
View File
@@ -47,7 +47,7 @@ extension SAPlayer {
- Parameter completion: Completion handler that will return once the download is successful and complete.
- Parameter savedUrl: The url of where the audio was saved locally on the device. Will receive once download has completed.
*/
public static func downloadAudio(withRemoteUrl url: URL, completion: @escaping (_ savedUrl: URL) -> ()) {
public static func downloadAudio(withRemoteUrl url: URL, completion: @escaping (_ savedUrl: URL, _ error: Error?) -> ()) {
SAPlayer.shared.addUrlToMapping(url: url)
AudioDataManager.shared.startDownload(withRemoteURL: url, completion: completion)
}
+1 -1
View File
@@ -8,7 +8,7 @@
Pod::Spec.new do |s|
s.name = 'SwiftAudioPlayer'
s.version = '7.4.0'
s.version = '7.5.0'
s.summary = 'SwiftAudioPlayer is a Swift based audio player that can handle streaming from a remote location and audio manipulation.'
# This description is used to generate tags and improve search results.