import SwiftUI
import FirebaseStorage
import FirebaseFirestore
import AVFoundation
import UIKit
import FirebaseAuth
struct Phonogram: Identifiable {
var id = UUID()
var name: String
var url: String
}
struct PhonogramsView: View {
@State private var phonograms: [Phonogram] = []
@State private var player: AVAudioPlayer?
@State private var isUploading = false
@State private var isAdmin = false
@State private var showPicker = false
var body: some View {
NavigationView {
List {
ForEach(phonograms, id: \.id) { phonogram in
HStack {
Text(phonogram.name)
.onTapGesture {
playMP3(urlString: phonogram.url)
}
}
}
}
.navigationTitle("Phonograms")
.navigationBarItems(trailing: isAdmin ? uploadButton : nil)
.onAppear {
fetchPhonograms()
checkIfAdmin() // Check if the user is an admin
}
.sheet(isPresented: $showPicker) {
DocumentPicker()
}
}
}
private var uploadButton: some View {
Button(action: {
showPicker = true // This triggers the presentation of the sheet
}) {
Text("Upload")
}
}
private func fetchPhonograms() {
let db = Firestore.firestore()
db.collection("phonograms")
.getDocuments { snapshot, error in
if let error = error {
print("Error fetching documents: \(error)")
} else {
phonograms = snapshot?.documentspactMap { doc in
guard let name = doc["name"] as? String,
let url = doc["url"] as? String else { return nil }
return Phonogram(name: name, url: url)
} ?? []
phonograms.sort { $0.name.localizedCompare($1.name) == .orderedAscending }
}
}
}
private func checkIfAdmin() {
if let user = Auth.auth().currentUser {
// Replace with your admin email check
isAdmin = user.email == "[email protected]"
}
}
private func uploadMP3(fileURL: URL) {
let storage = Storage.storage()
let storageRef = storage.reference().child("phonograms/\(fileURL.lastPathComponent)")
let metadata = StorageMetadata()
metadata.contentType = "audio/mp3"
storageRef.putFile(from: fileURL, metadata: metadata) { _, error in
if let error = error {
print("Error uploading file: \(error.localizedDescription)")
} else {
storageRef.downloadURL { url, error in
if let error = error {
print("Error getting download URL: \(error.localizedDescription)")
} else if let downloadURL = url {
savePhonogramToFirestore(fileURL: fileURL, downloadURL: downloadURL.absoluteString)
}
}
}
}
}
private func savePhonogramToFirestore(fileURL: URL, downloadURL: String) {
let db = Firestore.firestore()
let phonogramData: [String: Any] = [
"name": fileURL.lastPathComponent,
"url": downloadURL
]
db.collection("phonograms").addDocument(data: phonogramData) { error in
if let error = error {
print("Error saving to Firestore: \(error.localizedDescription)")
} else {
fetchPhonograms() // Reload the list after saving
}
}
}
private func playMP3(urlString: String) {
guard let url = URL(string: urlString) else { return }
do {
player = try AVAudioPlayer(contentsOf: url)
player?.play()
} catch {
print("Error playing MP3: \(error)")
}
}
}
struct DocumentPicker: UIViewControllerRepresentable {
class Coordinator: NSObject, UIDocumentPickerDelegate {
var parent: DocumentPicker
init(parent: DocumentPicker) {
self.parent = parent
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
if let url = urls.first {
parent.uploadMP3(fileURL: url)
}
}
func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
print("Document Picker was cancelled")
}
}
func makeCoordinator() -> Coordinator {
return Coordinator(parent: self)
}
func makeUIViewController(context: Context) -> UIDocumentPickerViewController {
let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: [.audio])
documentPicker.allowsMultipleSelection = false
documentPicker.delegate = context.coordinator
return documentPicker
}
func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: Context) {}
func uploadMP3(fileURL: URL) {
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.uploadMP3(fileURL: fileURL)
}
}
}
// this is the code but it lets me select a file closes the file folder and then it does not same to app or firebase. the debug says:
AX Lookup problem - errorCode:1100 error:Permission denied portName:'com.apple.iphone.axserver' PID:5049 ( 0 AXRuntime 0x00000001d9c67758 _AXGetPortFromCache + 796 1 AXRuntime 0x00000001d9c6d02c AXUIElementPerformFencedActionWithValue + 700 2 UIKit 0x000000025fac3488 7F0274D9-D3C9-3193-B606-1C74BE53B86C + 1537160 3 libdispatch.dylib 0x0000000100f0088c _dispatch_call_block_and_release + 32 4 libdispatch.dylib 0x0000000100f02578 _dispatch_client_callout + 20 5 libdispatch.dylib 0x0000000100f0a454 _dispatch_lane_serial_drain + 840 6 libdispatch.dylib 0x0000000100f0b25c _dispatch_lane_invoke + 408 7 libdispatch.dylib 0x0000000100f186fc _dispatch_root_queue_drain_deferred_wlh + 328 8 libdispatch.dylib 0x0000000100f17d0c _dispatch_workloop_worker_thread + 580 9 libsystem_pthread.dylib 0x000000022ce6c680 _pthread_wqthread + 288 10 libsystem_pthread.dylib 0x000000022ce6a474 start_wqthread + 8 ) The view service did terminate with error: Error Domain=_UIViewServiceErrorDomain Code=1 "(null)" UserInfo={Terminated=disconnect method}
Expecting to save to app and firebase an MP3 file