Jac Mulder
Jac Mulder

Reputation: 47

How to upload AVAudioRecorder files to Firebase Storage with Swift 5 /SwiftUI?

Hi I know this have been asked a few times but I am needing help with uploading user voice recordings to Firebase. When the user records their audio in the app and press the stop button I want the recording to be uploaded and stored in Firebase instead of the user's phone.

Heres the function for recording

func startRecording() {
    
    let recordingSession = AVAudioSession.sharedInstance()
    
    do {
        try recordingSession.setCategory(.playAndRecord, mode: .default)
        try recordingSession.setActive(true)
    } catch {
        print("Failed to set up recording session")
    }
    let documentPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let audioFilename = documentPath.appendingPathComponent("\(Date().toString(dateFormat: "dd-MM-YY_'at'_HH:mm:ss")).m4a")
    let settings = [
        AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
        AVSampleRateKey: 12000,
        AVNumberOfChannelsKey: 1,
        AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
    ]
    
    do {
        audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings)
        audioRecorder.record()
        
        recording = true
    } catch {
        print("Could not start recording")
    }
}

Here is the function when the user stops recording

func saveRecording() {
    
    let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
       let directoryContents = try! FileManager.default.contentsOfDirectory(at: path, includingPropertiesForKeys: nil)

       for i in directoryContents {
        user.answersSent.append(CardModel(fullname: question.fullname, username: question.username, imageURL: question.imageURL, question: question.question, fileURL: i, createdAt: getCreationDate(for: i), colorChoice: question.colorChoice))
       }
   
      
            
            user.answersSent.sort(by: { $0.createdAt?.compare($1.createdAt!) == .orderedDescending})
           
            
        
        }
    }
    

Thank you so much for taking the time to read. I spent almost two days trying to figure it out.

Upvotes: 0

Views: 533

Answers (1)

jnpdx
jnpdx

Reputation: 52397

  1. Instead of letting your URL go out of scope immediately, store it in a property on whatever class is running this functions (if you're doing this in a View, move all of the recording logic to an ObservableObject).

  2. At the end of the recording, now that you have the URL, you won't have to do the createdAt sorting, which I assume maybe you're doing to get the most recent file (it's a little unclear to me at this point).

  3. Upload the local file using the method described in the Firebase documentation (https://firebase.google.com/docs/storage/ios/upload-files#upload_from_a_local_file):

// File located on disk
// Create a reference to the file you want to upload
let audioFileRef = storageRef.child("audioFiles/audioFile.m4a") //adjust this to have a unique name

let uploadTask = audioFileRef.putFile(from: localAudioURL, metadata: nil) { metadata, error in
  guard let metadata = metadata else {
    // Uh-oh, an error occurred!
    return
  }
  //optionally, delete original local file here
}
  1. Optionally, delete your local file upon completion of the upload. Also, you could choose to use the temporary directory rather than the documents directory to store the initial recording in the first place.

Upvotes: 0

Related Questions