FileManager cannot find audio file

2019-03-01 10:04发布

Helloo! My ultimate goal is to create a UITableViewController with recordings made in-app, using FileManager to traverse the /Documents/ directory and list all the recordings found there.

The recording and playback are functioning just fine with one recording, with the following setup:

// In VC#1

 func setupRecorder(){
    let audioSession:AVAudioSession = AVAudioSession.sharedInstance()
    do {
        try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord)
    } catch {
        print("Audio Setup Error: \(error)")
    }
    do {
        try audioSession.setActive(true)
    } catch {
        print("Audio Setup Error: \(error)")
    }

    let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]

    audioFileName = "test.caf"
    audioFileUrl = documentsDirectory.appendingPathComponent(audioFileName)

    print("\n\nrecording url :\(audioFileUrl.absoluteString)\n\n")

    let recordSettings = [
        AVFormatIDKey: Int(kAudioFormatAppleLossless),
        AVEncoderAudioQualityKey : AVAudioQuality.max.rawValue,
        AVEncoderBitRateKey : 320000,
        AVNumberOfChannelsKey: 2,
        AVSampleRateKey : 44100.0
        ] as [String : Any]

    do {
        audioRecorder = try AVAudioRecorder(url: audioFileUrl, settings: recordSettings)
    } catch let error as NSError{
        print("Audio Setup Error: \(error)")
        audioRecorder = nil
    }
    audioRecorder.delegate = self
    audioRecorder.isMeteringEnabled = true
    audioRecorder.prepareToRecord()
}

...



 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == GraphViewController.getEntrySegue() {
        let navController = segue.destination as! UINavigationController
        let destination = navController.topViewController as! GraphViewController
        destination.audioFileName = audioFileName
        destination.audioFileUrl = audioFileUrl
    }

// In VC#2
func setupAudioPlayer() {
    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
    } catch {
        print(error)
    }
    do {
        try AVAudioSession.sharedInstance().setActive(true)
    } catch {
        print(error)
    }
    do {
        audioPlayer = try AVAudioPlayer(contentsOf: audioFileUrl)
    } catch {
        print("Audio Player Setup Error: \(error)")
    }
    audioPlayer.prepareToPlay()
}

This is working all fine and dandy; it plays the recorded audio file with no problems whatsoever. However, when I try to find the file via FileManager, FileManager cannot find it. Listed below are my attempts to find this file.

        print("\(FileManager.default.fileExists(atPath: audioFileUrl.absoluteString))") // -> False

        print("\(FileManager.default.contents(atPath: audioFileUrl.absoluteString))") // -> nil

Clearly I must be missing something... especially given AVAudioPlayer is successfully reading the audio file with the exact same url. The path prints as:

file:///var/mobile/Containers/Data/Application/1DA6BD0F-5A23-4228-92A9-A083E55ACE21/Documents/test.caf

Any ideas?

1条回答
看我几分像从前
2楼-- · 2019-03-01 10:42

You cannot save a sandboxed file URL or path string for later use, because the sandbox can move. You need to do what you were doing before, successfully: calculate the documents directory URL and then examine it. You should work entirely with URLs and never call absoluteString at all; it is the wrong call entirely and is letting you down here.

In this example, I check the documents directory for any files whatever:

let documentsDirectory = 
    FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let results = 
    try? FileManager.default.contentsOfDirectory(at: documentsDirectory, 
                                                 includingPropertiesForKeys: nil)
查看更多
登录 后发表回答