从项目访问今天扩展中保存的文件

时间:2017-02-10 22:55:22

标签: swift audio swift3 save today-extension

我正在尝试访问我从今天的扩展程序中保存的文件。在我今天的extenson中,我这样做是为了保存文件:

func startRecording() {
    let audioFilename = getDocumentsDirectory().appendingPathComponent("recording.m4a")

    let settings = [
        AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
        AVSampleRateKey: 12000,
        AVNumberOfChannelsKey: 1,
        AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
    ]

    do {
        audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings)
        audioRecorder.delegate = self
        audioRecorder.record()

        recordButton.setTitle("Stop", for: .normal)
    } catch {
        finishRecording(success: false)
    }
}

func getDocumentsDirectory() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    let documentsDirectory = paths[0]
    return documentsDirectory
}

然后我尝试使用此代码在项目的主要部分获取AVAudio Player的数据:

let path = Bundle.main.path(forResource: "recording.m4a", ofType:nil)! let url = URL(fileURLWithPath: path)

然而,它给出了错误:在展开Optional值时意外地发现了nil。 谢谢你的帮助。

2 个答案:

答案 0 :(得分:1)

您的扩展程序会将文件保存到其文档目录,而您的应用程序代码正在应用程序包中查找该文件。应用包仅包含随应用分发的资源。您需要深入研究文件系统。

然而,还有另一个问题。扩展和包含应用程序不共享文档目录。它们每个都有自己的容器,用于为自己编写本地数据。如果你想在它们之间共享数据,那就更多了。总结:

  1. 为应用和要分享的扩展程序创建应用组标识符。
  2. 使用FileManager.containerURL(forSecurityApplicationGroupIdentifier:)获取共享容器目录的文件URL。
  3. 从容器URL中添加文件名。
  4. 在扩展程序中,您将照常设置AVAudioRecorder并开始录制。
  5. 在主应用中,您需要使用NSFileCoordinator API来确保一次只有一个进程正在写入文件。希望AVAudioRecorder在内部使用NSFileCoordinator API,但我没有立即找到确认信息。
  6. 有关共享容器的更多详细信息,请参阅此blog post

答案 1 :(得分:0)

我只是尝试了相同的 - 从今日扩展录制音频。代码看起来很熟悉,所以我猜错:你想捕获语音并将文件发送到Google Speech API,对吗?

尽管如此,我认为我们已经达到了扩展限制:通过https://developer.apple.com/library/content/qa/qa1872/_index.html扩展判断无法录制音频。这篇文章一直在为iOS 8撰写,但我不相信苹果公司已经解除了限制。如果我错了,请纠正我,因为我在做自己的OP时会遇到问题。

顺便说一句,检查audioRecorder.record()的结果。它可能是false并表示捕获从未开始(当前是我的错误)。