Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/93.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何使用Objective-C在CoreData中保存和获取音频数据?_Ios_Objective C_Xcode_Core Data - Fatal编程技术网

Ios 如何使用Objective-C在CoreData中保存和获取音频数据?

Ios 如何使用Objective-C在CoreData中保存和获取音频数据?,ios,objective-c,xcode,core-data,Ios,Objective C,Xcode,Core Data,我是iOS开发的新手 如何使用Objective-C在CoreData中保存和获取音频数据 我只知道我必须使用NSData和二进制数据。正如@Shallowthough在他的评论中所说的,通常不应该在核心数据中存储大型二进制数据对象。将声音文件保存到应用程序的documents目录或其他沙盒目录中,然后将文件的URL或路径存储在Core Data中。我想我应该添加代码来完成我在上面的评论中描述的内容。这是在swift 3.0中,而不是ObjC中,很抱歉使用CoreData存储音频记录以及图像和视

我是iOS开发的新手

如何使用Objective-C在CoreData中保存和获取音频数据


我只知道我必须使用NSData和二进制数据。

正如@Shallowthough在他的评论中所说的,通常不应该在核心数据中存储大型二进制数据对象。将声音文件保存到应用程序的documents目录或其他沙盒目录中,然后将文件的URL或路径存储在Core Data中。

我想我应该添加代码来完成我在上面的评论中描述的内容。这是在swift 3.0中,而不是ObjC中,很抱歉使用CoreData存储音频记录以及图像和视频,尽管这些内容的捕获更复杂,此处未显示

我发现最好是将记录捕获到一个文件中,然后将其转换为NSData值,并将其存储到数据库中,再次作为二进制数据类型,并选择允许外部存储,CoreData就是这样做的

流程是首先调用setupAudio来创建一个单例音频会话,然后使用startRecordAction和stopRecordAction方法(连接到UI上的按钮)来驱动会话,因此使用sharedInstance表示法。虽然它看起来像多个会话,但它只是一个共享的单例,这种结构允许我在方法中使用该实例来分解进程

我已经对此进行了简化,因此这里的stop方法会在录音停止时自动将录音添加到数据库中。免责声明:我删掉了一堆不适用于您的问题的代码,因此我可能添加了一个bug或删除了一些必需的内容,但我认为这很接近

代码如下:

import AVFoundation

...

var audioRecorder:AVAudioRecorder!

let recordSettings = [AVSampleRateKey : NSNumber(value: Float(44100.0)),
                      AVFormatIDKey : NSNumber(value: Int32(kAudioFormatMPEG4AAC)),
                      AVNumberOfChannelsKey : NSNumber(value: 1),
                      AVEncoderAudioQualityKey : NSNumber(value: Int32(AVAudioQuality.medium.rawValue))]

func directoryURL() -> URL {
    let fileManager = FileManager.default
    let urls = fileManager.urls(for: .documentDirectory, in: .userDomainMask)  
    let documentDirectory = urls[0] as NSURL
    let soundURL = documentDirectory.appendingPathComponent(“capturedAudio.m4a")
    return soundURL!
}

func setupAudio()
{
    let audioSession = AVAudioSession.sharedInstance()

    do {
        unowned let myself = self
        try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord)
        try audioRecorder = AVAudioRecorder(url: myself.directoryURL(),
                                            settings: recordSettings)
        audioRecorder.prepareToRecord()
    } catch {
        logError...
    }
}

@IBAction func startRecordAction(_ sender: UIButton) {
    if !audioRecorder.isRecording {
        let audioSession = AVAudioSession.sharedInstance()
        do {
            try audioSession.setActive(true)
            audioRecorder.record()
        } catch {
            logError...
        }
    }
}

@IBAction func stopRecordAction(_ sender: UIButton) {
    audioRecorder.stop()
    let audioSession = AVAudioSession.sharedInstance()

    do {
        try audioSession.setActive(false)
    } catch {
        logError...
    }

    var audioTrack: Data?

    do {
        audioTrack = try Data(contentsOf: audioRecorder.url)
    } catch {
        logError...
    }

    addMediaCaptureToDB(audioTrack!, mediaType: "Recording")
}

func addMediaCaptureToDB(_ mediaData: Data, mediaType: String)
{
    guard let newRec = NSEntityDescription.insertNewObject(forEntityName: "MediaCapture", into: context) as? MediaCapture else
    {
        logError...
    }

    newRec.mediaCapture = mediaData as NSData  // Binary Data field / option set to allow External Storage
    newRec.type = mediaType
    newRec.captureDate = NSDate()
    newRec.uniqueID = String(Date().timeIntervalSince1970)

    // Save the new MediaCapture record to the database

    do {
        try context.save()
    } catch {
    logError...
    }
}

希望这有助于…

避免将大文件音频存储到核心数据中。希望保存引用文件名、URL。。。。如果您仍想这样做,但遇到了问题,请发布您尝试过的内容以及问题所在。使用NSData和二进制属性就是您的方法。你不明白什么?如果我需要录制新的音频?我应该将这个音频文件存储在哪里?我实际上已经将音频、视频和图像指定为二进制数据类型属性,并使用允许外部存储属性。检查生成的文件时,CoreData会创建所需的目录和文件,并管理创建和监督存储的过程。这对于200多个媒体文件(总计超过100MB的数据)的收集效果良好。我在其他更复杂的情况下使用手动方法,比如存储构成地图平铺覆盖的数百到数千张图像,它确实可以工作,但您拥有复杂性。