Here is my saving and retrieving code:
func retrieveSong(songId: String) -> URL? {
guard let pathComponent = cache[songId] else {
return nil
}
if let documentsUrl = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: .documentsDirectory, create: false) {
let fileUrl = documentsUrl.appendingPathComponent(pathComponent)
if FileManager.default.fileExists(atPath: fileUrl.path()) {
print("File Exists!\n\(fileUrl.absoluteString)")
} else {
print("File does not Exist!\n\(fileUrl.absoluteString)")
}
return fileUrl
}
return nil
}
func cacheSong(song: Song, callback: @escaping () -> Void) {
if self.cache[song.id] == nil {
let url = SubsonicClient.shared.stream(id: song.id)
Task {
do {
let path = try await SubsonicClient.shared.downloadSong(url: url)
DispatchQueue.main.async {
self.cache[song.id] = path
}
print("Song cached: \(song.title)")
callback()
} catch {
print("Song caching error: \(error)")
}
}
}
}
func downloadSong(url: URL) async throws -> String {
let urlRequest = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData)
let (data, response) = try await session.data(for: urlRequest)
if let code = (response as? HTTPURLResponse)?.statusCode, code != 200 {
printJSONData(data)
throw HalpoError.badResponse(code: code)
}
let documentsURL = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: .documentsDirectory, create: false)
let savedMusicPath = documentsURL.appendingPathComponent("saved", conformingTo: .directory)
var isDirectory: ObjCBool = true
if !FileManager.default.fileExists(atPath: savedMusicPath.path(), isDirectory: &isDirectory) {
try FileManager.default.createDirectory(at: savedMusicPath, withIntermediateDirectories: false)
}
let pathComponent = "saved/\(UUID()).mp3"
let filePath = documentsURL.appendingPathComponent(pathComponent)
FileManager.default.createFile(atPath: filePath.path(), contents: nil)
try data.write(to: filePath)
return pathComponent
}
and when I try to access this file via my retrieveSong function I get an error. logs:
Song cached: Funky Fanfare
["696b94e70f08c3023ed3c52ba0ff63f1": "saved/95381166-F33E-48AB-BA51-2CF931179BA2.mp3"]
File Exists!
file:///var/mobile/Containers/Data/Application/F04D1E83-7DAD-4690-8DA8-11FE3E2DEED3/Documents/saved/95381166-F33E-48AB-BA51-2CF931179BA2.mp3
AUDIO PLAYER ERROR: The file “95381166-F33E-48AB-BA51-2CF931179BA2.mp3” couldn’t be opened because you don’t have permission to view it.
I don't have anywhere I can really use url.startAccessingSecurityScopedResource()
as the audio player is a library that does it all internally.
Also I don't believe I need to as I am working within the sandbox and the app has loaded files previously, I'm just not sure what has changed
Could the audio player, being in a swift package (SwiftAudioEX), not have permissions to view the documents directory?
After a while of messing about, I realised when loading my audio player item, I was using URL.absoluteString
instead of URL.path()