Hi guys,
First of all, I'm sorry if this is the wrong place to post this. I'm in the last steps of my task manager app: getting the tasks to sync between devices. However, I get the error "This NSPersistentStoreCoordinator has no persistent stores (unknown). It cannot perform a save operation." What does this error exactly mean? My container is initialised so it should have a persistent store, right? I've also enabled all the proper capabilities I'm pretty sure (eg, I've enabled CloudKit, created a container, enabled background fetch and remote notifications.) Here is the code for my data controller:
import CoreData
import Foundation
class DataController: ObservableObject {
let container = NSPersistentCloudKitContainer(name: "TaskDataModel")
init() {
guard let description = container.persistentStoreDescriptions.first else {
fatalError("Container descriptions not loaded")
}
description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
container.viewContext.automaticallyMergesChangesFromParent = true
container.loadPersistentStores { description, error in
if let error = error {
print("Core Data failed to load: \(error.localizedDescription)")
}
}
}
}
Here is TaskManMain:
@main
struct TaskManApp: App {
@StateObject private var dataController = DataController()
var body: some Scene {
WindowGroup {
MainView()
.environment(\.managedObjectContext, dataController.container.viewContext)
}
}
}
Here is the full repo if y'all are interested:
https://github.com/aabagdi/TaskMan
Thanks for any help!
Post
Replies
Boosts
Views
Activity
Hi y'all,
After getting mono recording working, I want to differentiate my app from the standard voice memos to allow for stereo recording. I followed this tutorial (https://developer.apple.com/documentation/avfaudio/capturing_stereo_audio_from_built-in_microphones) to get my voice recorder to record stereo audio. However, when I look at the waveform in Audacity, both channels are the same. If I look at the file info after sharing it, it says the file is in stereo. I don't exactly know what's going on here. What I suspect is happening is that the recorder is only using one microphone. Here is the relevant part of my recorder:
// MARK: - Initialization
override init() {
super.init()
do {
try configureAudioSession()
try enableBuiltInMicrophone()
try setupAudioRecorder()
} catch {
// If any errors occur during initialization,
// terminate the app with a fatalError.
fatalError("Error: \(error)")
}
}
// MARK: - Audio Session and Recorder Configuration
private func enableBuiltInMicrophone() throws {
let audioSession = AVAudioSession.sharedInstance()
let availableInputs = audioSession.availableInputs
guard let builtInMicInput = availableInputs?.first(where: { $0.portType == .builtInMic }) else {
throw Errors.NoBuiltInMic
}
do {
try audioSession.setPreferredInput(builtInMicInput)
} catch {
throw Errors.UnableToSetBuiltInMicrophone
}
}
private func configureAudioSession() throws {
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(.record, mode: .default, options: [.allowBluetooth])
try audioSession.setActive(true)
} catch {
throw Errors.FailedToInitSessionError
}
}
private func setupAudioRecorder() throws {
let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd, HH:mm:ss"
let timestamp = dateFormatter.string(from: date)
self.recording = Recording(name: timestamp)
guard let fileURL = recording?.returnURL() else {
fatalError("Failed to create file URL")
}
self.currentURL = fileURL
print("Recording URL: \(fileURL)")
do {
let audioSettings: [String: Any] = [
AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
AVLinearPCMIsNonInterleaved: false,
AVSampleRateKey: 44_100.0,
AVNumberOfChannelsKey: isStereoSupported ? 2 : 1,
AVLinearPCMBitDepthKey: 16,
AVEncoderAudioQualityKey: AVAudioQuality.max.rawValue
]
audioRecorder = try AVAudioRecorder(url: fileURL, settings: audioSettings)
} catch {
throw Errors.UnableToCreateAudioRecorder
}
audioRecorder.delegate = self
audioRecorder.prepareToRecord()
}
//MARK: update orientation
public func updateOrientation(withDataSourceOrientation orientation: AVAudioSession.Orientation = .front, interfaceOrientation: UIInterfaceOrientation) async throws {
let session = AVAudioSession.sharedInstance()
guard let preferredInput = session.preferredInput,
let dataSources = preferredInput.dataSources,
let newDataSource = dataSources.first(where: { $0.orientation == orientation }),
let supportedPolarPatterns = newDataSource.supportedPolarPatterns else {
return
}
isStereoSupported = supportedPolarPatterns.contains(.stereo)
if isStereoSupported {
try newDataSource.setPreferredPolarPattern(.stereo)
}
try preferredInput.setPreferredDataSource(newDataSource)
try session.setPreferredInputOrientation(interfaceOrientation.inputOrientation)
}
Here is the relevant part of my SwiftUI view:
RecordView()
.onAppear {
Task {
if await AVAudioApplication.requestRecordPermission() {
// The user grants access. Present recording interface.
print("Permission granted")
} else {
// The user denies access. Present a message that indicates
// that they can change their permission settings in the
// Privacy & Security section of the Settings app.
model.showAlert.toggle()
}
try await recorder.updateOrientation(interfaceOrientation: deviceOrientation)
}
}
.onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let orientation = windowScene.windows.first?.windowScene?.interfaceOrientation {
deviceOrientation = orientation
Task {
do {
try await recorder.updateOrientation(interfaceOrientation: deviceOrientation)
} catch {
throw Errors.UnableToUpdateOrientation
}
}
}
}
Here is the full repo: https://github.com/aabagdi/MemoMan/tree/MemoManStereo
Thanks for any leads!