Я создаю приложение, в которое записывается звук, и оно автоматически сохраняет аудиофайл в Firebase (который уже подключен к моему проекту) и отображается в следующем контроллере представления.Они смогут воспроизводить то, что воспроизводили, в контроллере представления, в котором сохранен файл, для дальнейшего использования.
Мои проблемы:
- Возможность сохранять аудио и автоматически сохранять его в Firebase под своей учетной записью и отображать в контроллере представления.
- Мое приложение падает при попытке создать новую учетную запись.
Вот мой код для первой страницы, которая появляется для входа / создания учетной записи:
import UIKit
import SVProgressHUD
import Firebase
import AVFoundation
class ViewController: UIViewController {
@IBOutlet weak var email: UITextField!
@IBOutlet weak var password: UITextField!
@IBAction func logIn(_ sender: Any) {
SVProgressHUD.show()
Auth.auth().signIn(withEmail: email.text!, password: password.text!) { (user, error) in
if error != nil {
print(error!)
} else {
print("Log in Succesful")
SVProgressHUD.dismiss()
self.performSegue(withIdentifier: "logIn", sender: self)
}
}
}
@IBAction func createAccount(_ sender: Any) {
self.performSegue(withIdentifier: "createAccount", sender: self)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
}
public protocol MicrophonePermissions {
typealias PermissionsState = AVAudioSession.RecordPermission
func requestPermissions(handler: @escaping (PermissionsState) -> Void)
func permissionsState() -> PermissionsState
}
open class DefaultMicrophonePermissions: MicrophonePermissions {
public init() {}
public func requestPermissions(handler: @escaping (PermissionsState) -> Void) {
AVAudioSession.sharedInstance().requestRecordPermission { _ in
DispatchQueue.main.async { [weak self] in
guard let `self` = self else { return }
handler(self.permissionsState())
}
}
}
public func permissionsState() -> PermissionsState {
return AVAudioSession.sharedInstance().recordPermission
}
}
Вот мой код для создания учетной записи:
import UIKit
import Firebase
import SVProgressHUD
class CreateAccountViewController: UIViewController, UIApplicationDelegate {
@IBOutlet weak var emailAddress: UITextField!
@IBOutlet weak var password: UITextField!
@IBAction func createAccount(_ sender: Any) {
Auth.auth().createUser(withEmail: emailAddress.text!, password: password.text!) { (user, error) in
if error != nil {
print(error!)
} else {
print("Account Created!")
SVProgressHUD.dismiss()
self.performSegue(withIdentifier: "mainPage", sender: self)
}
}
func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
Вот мой код для начала и окончания записи, а такжекак возможность сохранять свои аудиофайлы в следующем контроллере представления
import UIKit
import AVFoundation
import Firebase
var recordButton: UIButton!
var audioRecorder: AVAudioRecorder!
var recordingSession: AVAudioSession!
class PracticePageViewController: UIViewController, AVAudioPlayerDelegate, AVAudioRecorderDelegate {
@IBOutlet weak var beginRecording: UIButton!
@IBAction func endRecording(_ sender: Any) {
finishRecording(success: true)
func saveTrack(asset: AVURLAsset) {
let exporter = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetAppleM4A)
let fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("YourApp/documents/Track01.m4a")
exporter?.outputURL = fileURL
exporter?.outputFileType = AVFileType.m4a
exporter?.exportAsynchronously(completionHandler: {
print(exporter?.status)
print(exporter?.estimatedOutputFileLength)
print(exporter?.maxDuration)
print("Finished Saving File")
})
}
}
@IBAction func beginRecording(_ sender: Any) {
startRecording()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
recordingSession = AVAudioSession.sharedInstance()
do {
try recordingSession.setCategory(.playAndRecord, mode: .default)
try recordingSession.setActive(true)
recordingSession.requestRecordPermission() { [unowned self] allowed in
DispatchQueue.main.async {
if allowed {
loadRecordingUI()
} else {
print("Failed to Record")
}
}
}
} catch {
print("Failed to Record")
}
func loadRecordingUI() {
recordButton = UIButton(frame: CGRect(x: 64, y: 64, width: 128, height: 64))
recordButton.setTitle("Tap to Record", for: .normal)
recordButton.titleLabel?.font = UIFont.preferredFont(forTextStyle: UIFont.TextStyle(rawValue: title!))
recordButton.addTarget(self, action: #selector(recordTapped), for: .touchUpInside)
view.addSubview(recordButton)
}
}
func startRecording() {
let audioFilename = getDocumentsDirectory().appendingPathComponent("recording.m4a")
let settings = [
AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
AVSampleRateKey: 12000,
AVNumberOfChannelsKey: 1,
AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
]
do {
audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings)
audioRecorder.delegate = self
audioRecorder.record()
recordButton.setTitle("Tap to Stop", for: .normal)
} catch {
finishRecording(success: false)
}
}
func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
}
func finishRecording(success: Bool) {
audioRecorder.stop()
audioRecorder = nil
if success {
recordButton.setTitle("Tap to Re-record", for: .normal)
} else {
recordButton.setTitle("Tap to Record", for: .normal)
}
}
@objc func recordTapped() {
if audioRecorder == nil {
startRecording()
} else {
finishRecording(success: true)
}
}
func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
if !flag {
finishRecording(success: false)
}
}
}
Наконец, вот код, который у меня есть для контроллера просмотра, который также показывает все их аудиофайлы.давая им возможность при необходимости отправить файл в виде вложения
import UIKit
import MessageUI
import Firebase
import AVFoundation
import FirebaseStorage
class PracticeSessionsViewController: UIViewController, MFMailComposeViewControllerDelegate {
@IBAction func emailTeacher(_ sender: Any) {
let mailComposeViewController = configureMailController()
if MFMailComposeViewController.canSendMail() {
self.present(mailComposeViewController, animated: true, completion: nil)
} else {
showMailError()
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
func renameAudio(newTitle: String) {
do {
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) [0]
let documentDirectory = URL(fileURLWithPath: path)
let originPath = documentDirectory.appendingPathComponent("audio.m4a")
let destinationPath = documentDirectory.appendingPathComponent("\(newTitle).m4a")
try FileManager.default.moveItem(at: originPath, to: destinationPath)
} catch {
print(error)
}
}
}
func configureMailController() -> MFMailComposeViewController {
let mailComposeVC = MFMailComposeViewController()
mailComposeVC.mailComposeDelegate = self
mailComposeVC.setToRecipients([""])
mailComposeVC.setSubject("Hello")
return mailComposeVC
}
func showMailError() {
let sendMailErrorAlert = UIAlertController(title: "Could not send mail", message: "Your device could not send message", preferredStyle: .alert)
let dismiss = UIAlertAction(title: "Ok", style: .default, handler: nil)
sendMailErrorAlert.addAction(dismiss)
self.present(sendMailErrorAlert, animated: true, completion: nil)
}
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
controller.dismiss(animated: true, completion: nil)
}
Я пытался найти лучший способ сделать это, но безрезультатно.Мой код ниже.Просто помните, что я немного новичок в Swift, поэтому я просто хочу убедиться, что я учусь правильно.Спасибо!