Hellooo, thanks so much for the help you are so nice 🫶
This is the complete code from the view section:
import SwiftUI
import SwiftData
import UniformTypeIdentifiers
struct AddRepertoireView: View {
@Environment(\.modelContext) private var modelContext
@Environment(\.dismiss) private var dismiss
@State private var title = ""
@State private var composer = ""
@State private var opus = ""
@State private var epoch = ""
@State private var type = ""
@State private var accompaniment = ""
@State private var length: Int?
@State private var key = ""
@State private var difficulty = ""
@State private var tempo: Int?
@State private var showingFilePicker = false
@State private var sheetMusicData: Data?
@State private var sheetMusicFileName: String?
var body: some View {
Form {
Section("Essential Information") {
TextField("Title", text: $title)
TextField("Composer", text: $composer)
TextField("Opus", text: $opus)
}
Section("Additional Details") {
TextField("Epoch", text: $epoch)
TextField("Type", text: $type)
TextField("Accompaniment", text: $accompaniment)
TextField("Length (minutes)", value: $length, format: .number)
.keyboardType(.numberPad)
TextField("Key", text: $key)
TextField("Difficulty", text: $difficulty)
TextField("Tempo (BPM)", value: $tempo, format: .number)
.keyboardType(.numberPad)
}
Section("Sheet Music") {
if let fileName = sheetMusicFileName {
HStack {
Text(fileName)
.foregroundStyle(.secondary)
Spacer()
Button(role: .destructive) {
sheetMusicData = nil
sheetMusicFileName = nil
} label: {
Label("Remove", systemImage: "trash")
}
}
}
Button {
showingFilePicker = true
} label: {
Label(sheetMusicData == nil ? "Add Sheet Music" : "Replace Sheet Music",
systemImage: sheetMusicData == nil ? "plus.circle" : "arrow.triangle.2.circlepath")
}
}
}
.navigationTitle("Add Piece")
.toolbar {
ToolbarItem(placement: .confirmationAction) {
Button("Add") {
addEntry()
}
.disabled(title.isEmpty || composer.isEmpty)
}
}
.fileImporter(
isPresented: $showingFilePicker,
allowedContentTypes: [UTType.pdf],
allowsMultipleSelection: false
) { result in
switch result {
case .success(let urls):
guard let originalURL = urls.first else { return }
let tempURL = FileManager.default.temporaryDirectory
.appendingPathComponent(UUID().uuidString)
.appendingPathExtension("pdf")
do {
if originalURL.startAccessingSecurityScopedResource() {
defer { originalURL.stopAccessingSecurityScopedResource() }
try FileManager.default.copyItem(at: originalURL, to: tempURL)
let data = try Data(contentsOf: tempURL)
sheetMusicData = data
sheetMusicFileName = originalURL.lastPathComponent
try? FileManager.default.removeItem(at: tempURL)
}
} catch {
print("Error loading PDF: \(error.localizedDescription)")
}
case .failure(let error):
print("Error selecting PDF: \(error.localizedDescription)")
}
}
}
private func addEntry() {
let entry = RepertoireEntry(
title: title,
composer: composer,
opus: opus.isEmpty ? nil : opus,
epoch: epoch.isEmpty ? nil : epoch,
type: type.isEmpty ? nil : type,
accompaniment: accompaniment.isEmpty ? nil : accompaniment,
length: length,
key: key.isEmpty ? nil : key,
difficulty: difficulty.isEmpty ? nil : difficulty,
tempo: tempo
)
entry.sheetMusicData = sheetMusicData
entry.sheetMusicFileName = sheetMusicFileName
modelContext.insert(entry)
dismiss()
}
}
#Preview {
let config = ModelConfiguration(isStoredInMemoryOnly: true)
let container = try! ModelContainer(for: RepertoireEntry.self, configurations: config)
return NavigationStack {
AddRepertoireView()
}
.modelContainer(container)
}
Yeah I'm, currently developing "The fitness tracker for practicing your instrument", but I'm having some issues trying to learn swift. But thanks for taking a look at it 😊