Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
166 views
in Technique[技术] by (71.8m points)

ios - FileManager cannot find audio file

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("

recording url :(audioFileUrl.absoluteString)

")

    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? ????

Many thanks!

EDIT: Before storing the url as a property, I was doing the following, recalculating the documentsDirectory in VC#2 however was also not succesfull:

let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let results = try? FileManager.default.contentsOfDirectory(atPath: documentsDirectory.absoluteString)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...