I am making an App in Swift that records some audio and then sends that recording to my PHP server.
The App records the audio clip fine (it can be played back with n
here is the swift 4 ~ 5 code. creat new a button(buttonLabel in code) on ViewController and link button action to @IBAction and @IBOutlet [Hold to recode and release to upload audio file]
import UIKit
import AVFoundation
class ViewController2: UIViewController, AVAudioRecorderDelegate{
var recordingSession: AVAudioSession!
var audioRecorder: AVAudioRecorder!
var audioPlayer: AVAudioPlayer!
var numberOfRecords = 0
@IBOutlet weak var buttonLabel: UIButton!
let E_401 = "E_401"
let DATABASE_PATH = "http:///YourPrjectName/"
override func viewDidLoad() {
super.viewDidLoad()
// Set the recognizer to recognize the button action
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(record))
longPressRecognizer.minimumPressDuration = 0
buttonLabel.addGestureRecognizer(longPressRecognizer)
// Setting up session
recordingSession = AVAudioSession.sharedInstance()
// Get permission from user to use mic
AVAudioSession.sharedInstance().requestRecordPermission{ (hasPermission) in
if hasPermission
{print ("ACCEPTED")}
}
}
@IBAction func record(_ gestureRecognizer: UILongPressGestureRecognizer) {
// Check if we have an active recorder
if (gestureRecognizer.state == .began) && (audioRecorder == nil) {
// Increase +1 total number of recordings for every new recording made
self.numberOfRecords += 1
// Setting filename and settings
let filename = getDirectory().appendingPathComponent("\(numberOfRecords).m4a")
let settings = [
AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
AVSampleRateKey: 12000,
AVNumberOfChannelsKey: 1,
AVEncoderAudioQualityKey: AVAudioQuality.medium.rawValue
]
do
{
// Start audio recording
buttonLabel.setTitle("Recording...", for: .normal)
audioRecorder = try AVAudioRecorder(url: filename, settings: settings)
audioRecorder.delegate = self
audioRecorder.record()
}
catch
{
// Catch for errors
displayAlert(title: "Oops!", message: "Recording failed")
}
} else if gestureRecognizer.state == .ended && (audioRecorder != nil)
{
// Stopping audio recording
buttonLabel.setTitle("Start Recording", for: .normal)
audioRecorder.stop()
audioRecorder = nil
do {
let filename = getDirectory().appendingPathComponent("\(numberOfRecords).m4a")
let recording: NSData = try NSData(contentsOf: filename)
self.uploadFile(fileData: recording as Data, fileName: "\(numberOfRecords).m4a"){
(fileURL, e) in
if e == nil {
print("FILE URL: " + fileURL!)
}
}
} catch {
print("Unexpected <<<<<<<<<<<<<<>>>>>>>>>>>>>> error: \(error)")
}
}
}
// Function that gets path to directory
func getDirectory () -> URL
{
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentDirectory = paths[0]
return documentDirectory
}
// Function that displays an alert
func displayAlert(title:String, message:String)
{
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "dismiss", style: .default, handler: nil))
present(alert, animated: true, completion: nil)
}
func uploadFile(fileData:Data, fileName:String , completion: @escaping (_ fileURL:String?, _ error:String?) -> Void) {
let recId = "\(numberOfRecords)"
print("FILENAME: \(fileName)")
let request = NSMutableURLRequest()
let boundary = "--------14737809831466499882746641449----"
let beginningBoundary = "--\(boundary)"
let endingBoundary = "--\(boundary)--"
let contentType = "multipart/form-data;boundary=\(boundary)"
request.url = URL(string: DATABASE_PATH + "catch.php")
// catch.php is php script on server
request.httpShouldHandleCookies = false
request.timeoutInterval = 60
request.httpMethod = "POST"
request.setValue(contentType, forHTTPHeaderField: "Content-Type")
let body = NSMutableData()
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition: form-data; name=\"fileName\"\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append("\(fileName)\r\n".data(using: String.Encoding.utf8)!)
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition: form-data; name=\"file\"; filename=\"file\"\r\n".data(using: String.Encoding.utf8)!)
body.append(("\(beginningBoundary)\r\n" as NSString).data(using: String.Encoding.utf8.rawValue)!)
body.append(("Content-Type: application/octet-stream\r\n\r\n" as NSString).data(using: String.Encoding.utf8.rawValue)!)
body.append(fileData)
body.append("\r\n".data(using: String.Encoding.utf8)!)
body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
request.addValue(contentType, forHTTPHeaderField: "Content-Type")
// request.addValue(recId, forHTTPHeaderField: "REC-ID")
request.httpBody = body as Data
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest) { (data, response, error) in
guard let _:Data = data as Data?, let _:URLResponse = response, error == nil else {
DispatchQueue.main.async { completion(nil, error!.localizedDescription) }
return
}
if let response = String(data: data!, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue)) {
print("XSUploadFile -> RESPONSE: " + self.DATABASE_PATH + response)
DispatchQueue.main.async { completion(self.DATABASE_PATH + response, nil) }
// NO response
} else { DispatchQueue.main.async { completion(nil, self.E_401) } }// ./ If response
}; task.resume()
}
}