如何在 CloudKit 中存储和检索音频文件?

Posted

技术标签:

【中文标题】如何在 CloudKit 中存储和检索音频文件?【英文标题】:How can I store and retrieve audio files to and from CloudKit? 【发布时间】:2020-05-19 20:23:54 【问题描述】:

我正在尝试录制语音消息并将它们作为 CKAsset 存储在 CloudKit 上。我将它们转换为 AVAudioFile 并将它们作为 Post 记录上的几个属性之一保存到 CloudKit。

var recordedMessage: AVAudioFile?

var recordedMessageURL: URL? 
    didSet 
        if let recordedMessageURL = recordedMessageURL 
            recordedMessage = try? AVAudioFile(forReading: recordedMessageURL)
        
    

这部分过程似乎有效,尽管当我通过 CloudKit 仪表板访问文件时无法播放音频。 (双击它会打开 iTunes,但不会播放)

我创建了一个 fetchPosts 函数,该函数成功地关闭了与记录相关联的图像,但是当我尝试播放音频时,它给了我以下错误:

ExtAudioFile.cpp:192:Open: about to throw -43: open audio file

我认为这与我无法将资产正确转换为 AVAudioFile 有关。它似乎不像转换图像资产那样干净利落。

    var foundAudio: AVAudioFile?
    if let audioAsset = ckRecord[PostStrings.audioAssetKey] as? CKAsset 
        do 
            let audioData = try Data(contentsOf: audioAsset.fileURL!)
            let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
            guard let destinationPath = NSURL(fileURLWithPath: documentsPath).appendingPathComponent("filename.m4a", isDirectory: false) else return nil

            FileManager.default.createFile(atPath: destinationPath.path, contents: audioData, attributes: nil)

            foundAudio = try AVAudioFile(forReading: destinationPath)
         catch 
            print("Could not transform asset into data")
        
    

谁能告诉我哪里出错了?

【问题讨论】:

当您从 CloudKit 仪表板下载 CKAsset 并且您有一个原始文件时,是否可以将文件扩展名添加回文件中以允许您在 Mac 上播放它? 感谢您的评论,但我今天解决了这个问题。完全不同,我无法再检验你的理论。感谢您与我们联系! 【参考方案1】:

我花了很多天的时间来改变事情,但我有一个有效的解决方案,它不涉及直接将数据作为数据进行操作。相反,我使用 URL。我将 audioAsset 初始化为 URL:

var opComment: URL?
var audioAsset: CKAsset? 
  get 
    guard let audioURL = opComment else  return nil 
    return CKAsset(fileURL: audioURL)
    
    set 
      opComment = newValue?.fileURL
    
  

我使用便利的初始化器将 ckRecord 拉回:

var opCommentURL: URL?
    if let audioAsset = ckRecord[PostStrings.audioAssetKey] as? CKAsset 
            opCommentURL = audioAsset.fileURL
    

我将它作为 URL 输入到我的 AVAudioPlayer 中:

        guard let audioURL = post.opComment else return

    if !isTimerRunning 
        do 
            audioPlayer = try AVAudioPlayer(contentsOf: audioURL)
            audioPlayer.play()
         catch 
            print("Error in \(#function) : \(error.localizedDescription) /n---/n \(error)")
        
     else 
        audioPlayer.pause()
        isTimerRunning = false
    

(如果您正在阅读本文,Sam。感谢您朝着正确的方向轻轻推动!)

【讨论】:

以上是关于如何在 CloudKit 中存储和检索音频文件?的主要内容,如果未能解决你的问题,请参考以下文章

检索存储在我的 Mlab 中的音频 - 二进制文件

无法从 Cloudkit Cloud (JS) 检索所有记录

在 CloudKit 中将图像存储为 CKAsset,图像倒置

使用 CloudKit 和 Swift 检索图像

对于我的 iOS 笔记应用程序来说,这是最好的 iCloud 方法,其中包含文本、照片、音频和绘图笔记。我应该选择文档存储还是 CloudKit?

用于从 cloudkit 检索单列的代码模式/片段