我是iOS开发的新手。
如何使用Objective-C保存和从CoreData
获取音频数据?
我只知道我必须使用NSData和二进制数据。
答案 0 :(得分:4)
正如@shallowThought在评论中所说,通常不应该在Core Data中存储大的二进制数据对象。将声音文件保存到应用程序的文档目录或其他沙箱目录之一,然后在Core Data中存储该文件的URL或路径。
答案 1 :(得分:0)
以为我会添加用于完成我在上面评论中描述的代码。这是在swift 3.0(不是ObjC,对不起)使用CoreData来存储录音(以及图像和视频,尽管这些录制的复制更加复杂,并且未在此处显示)。
我发现最好将录制文件捕获到文件中,然后将其转换为我存储到数据库中的NSData值,再次作为二进制数据类型,并允许选择允许外部存储,CoreData可以执行此操作。
流程首先调用setupAudio()创建单例音频会话,然后使用连接到UI上按钮的startRecordAction()和stopRecordAction()方法来驱动会话(因此使用sharedInstance表示法)。虽然它看起来像是多个会话,但它只是一个共享单例,这个结构让我可以在方法中使用该实例分解进程。
我已经对此进行了简化,因此停止方法会在录制停止时自动将录音添加到数据库中。免责声明:我已经删除了一堆不适用于您的问题的代码,因此我可能添加了一个错误或删除了所需的内容,但我认为它很接近。
以下是代码:
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...
}
}
希望有帮助...