简体   繁体   English

NSUrlRequest可在模拟器中使用,但不能在iPhone上使用

[英]NSUrlRequest works in simulator but not on iphone

I have an app which records sound from microphone and then sends it to my website through NSUrlRequest. 我有一个可以记录麦克风声音的应用程序,然后通过NSUrlRequest将其发送到我的网站。 To test it, I added that audio is played from website so I can hear if it worked. 为了测试它,我补充说音频是从网站上播放的,所以我可以听到它是否起作用。
When I test it on simulator, everything works fine: audio is recorded and uploaded and I can hear it, but when I install it on my iPhone, I cannot hear anything and at my website, there is a corrupted audio file. 当我在模拟器上对其进行测试时,一切正常:录制并上传了音频,并且可以听到声音,但是当我将其安装在iPhone上时,却听不到任何声音,并且在我的网站上,音频文件已损坏。

My TestNahravani.swift Code: 我的TestNahravani.swift代码:

import UIKit
import AVFoundation

class TestNahravani: UIViewController, AVAudioRecorderDelegate, AVAudioPlayerDelegate {


@IBOutlet weak var recordButton: UIButton!
@IBOutlet weak var playButton: UIButton!

var soundRecorder: AVAudioRecorder!
var soundPlayer:AVAudioPlayer?

let fileName = "demo.m4a"

override func viewDidLoad() {
    super.viewDidLoad()
    setupRecorder()
}

@IBAction func recordSound(sender: UIButton) {
    if (sender.titleLabel?.text == "Record"){
        soundRecorder.record()
        sender.setTitle("Stop", for: .normal)
        playButton.isEnabled = false
    } else {
        soundRecorder.stop()
        sender.setTitle("Record", for: .normal)
    }
}

@IBAction func playSound(sender: UIButton) {
    if (sender.titleLabel?.text == "Play"){
        recordButton.isEnabled = false
        sender.setTitle("Stop", for: .normal)
        preparePlayer()
    } else {
        soundPlayer?.stop()
        sender.setTitle("Play", for: .normal)
    }
}

// MARK:- AVRecorder Setup

func setupRecorder() {

    //set the settings for recorder

    let recordSettings = [AVSampleRateKey : NSNumber(value: Float(44100.0)),
                          AVNumberOfChannelsKey : NSNumber(value: 2),
                          AVEncoderAudioQualityKey : NSNumber(value: Int32(AVAudioQuality.max.rawValue)),
                          AVFormatIDKey : NSNumber(value: kAudioFormatMPEG4AAC)]
    var error: NSError?
    do {
        soundRecorder =  try AVAudioRecorder(url: getFileURL() as URL, settings: recordSettings)
    } catch let error1 as NSError {
        error = error1
        soundRecorder = nil
    }

    if let err = error {
        print("AVAudioRecorder error: \(err.localizedDescription)")
    } else {
        soundRecorder.delegate = self
        soundRecorder.prepareToRecord()
    }
}

// MARK:- Prepare AVPlayer

func preparePlayer() {
    var errorX: NSError?




        let dirPaths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
        let docsDir: AnyObject=dirPaths[0] as AnyObject
        var recordedFilePath : String = docsDir.appendingPathComponent(fileName)
        let recordedFileURL = getFileURL()

        // "currentFilename", "recordedFilePath" and "recordedFileURL" are all global variables

        // This recording stored at "recordedFileURL" can be played back fine.

        let sendToPath = "http://www.kvetinac97.cz/jt.php"
        let sendToURL = NSURL(string: sendToPath)
        let recording: NSData! = NSData(contentsOf: recordedFileURL as URL)
    if recording == nil {
        recordedFilePath = "FailedUpload"
    }
        let boundary = "--------14737809831466499882746641449----"
        let contentType = "multipart/form-data;boundary=\(boundary)"

        let beginningBoundary = "--\(boundary)"
        let endingBoundary = "--\(boundary)--"

        let header = "Content-Disposition: form-data; name=\"\(fileName)\"; filename=\"\(recordedFilePath)\"\r\n"

        let body = NSMutableData()
        body.append(("\(beginningBoundary)\r\n" as NSString).data(using: String.Encoding.utf8.rawValue)!)
        body.append((header 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(recording! as Data) // adding the recording here
        body.append(("\r\n\(endingBoundary)\r\n" as NSString).data(using: String.Encoding.utf8.rawValue)!)

        let request = NSMutableURLRequest()
        request.url = sendToURL! as URL
        request.httpMethod = "POST"
        request.addValue(contentType, forHTTPHeaderField: "Content-Type")
        request.addValue("multipart/form-data", forHTTPHeaderField: "Accept")
        request.httpBody = body as Data

        let session = URLSession.shared
        let task = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
            if let data = NSData(contentsOf: NSURL(string: "http://www.kvetinac97.cz/uploads/demo.m4a")! as URL) {
                do {
                    try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
                    try AVAudioSession.sharedInstance().setActive(true)
                    self.soundPlayer = try AVAudioPlayer(data: data as Data, fileTypeHint: AVFileType.m4a.rawValue)
                    self.soundPlayer!.delegate = self
                    self.soundPlayer!.prepareToPlay()
                    self.soundPlayer!.volume = 1.0
                    self.soundPlayer!.play()
                } catch let error1 as NSError {
                    errorX = error1
                    self.soundPlayer = nil
                    print ("Chyba nejaka \(error1)")
                }
            }
            else {
                print ("Smulicka")
            }
        })
        task.resume()


}

func generateBoundaryString() -> String {
    return "Boundary-\(NSUUID().uuidString)"
}

// MARK:- File URL

func getCacheDirectory() -> String {

    let paths = NSSearchPathForDirectoriesInDomains(.cachesDirectory,.userDomainMask, true)

    return paths[0]
}

func getFileURL() -> NSURL {

    let path = getCacheDirectory().appending(fileName)

    let filePath = NSURL(fileURLWithPath: path)

    return filePath
}

// MARK:- AVAudioPlayer delegate methods

func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
    recordButton.isEnabled = true
    playButton.setTitle("Play", for: .normal)
}

// MARK:- AVAudioRecorder delegate methods

func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
    playButton.isEnabled = true
    recordButton.setTitle("Record", for: .normal)
}

// MARK:- didReceiveMemoryWarning

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

} }

I figured out where my problem was 我找出问题所在

As it appears, iPhone simulator does not require AVAudioSession to be activated whilst real iPhone does. 看起来,iPhone模拟器不需要激活AVAudioSession,而真正的iPhone则需要激活。

So it can be fixed easily with adding 因此可以通过添加轻松修复

try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryRecord)
try AVAudioSession.sharedInstance().setActive(true)

before audioRecorder initialization. 在audioRecorder初始化之前。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM