NSUrlRequest工作在模拟器,但不是在iPhone上

问题描述:

我有一个应用程序,从麦克风录制声音,然后通过NSUrlRequest发送到我的网站。为了测试它,我补充说音频是从网站播放的,所以我可以听到它是否工作。
当我在模拟器上测试它时,一切工作正常:录音和上传音频,我可以听到它,但是当我将它安装在我的iPhone上时,我听不到任何声音,并且在我的网站上有一个损坏的音频文件。NSUrlRequest工作在模拟器,但不是在iPhone上

我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() 
} 

}

+0

也许问题是由ATS(App Transport Security;例如不使用HTTPS)引起的? –

+0

AllowArbitaryLoads设置为YES,像iOS文件许可或类似的问题必须有问题 – kvetinac97

+0

您可以通过检查“recording”变量是否正确初始化来检查文件权限问题。但我不希望这里出现问题。也许你应该尝试发送一个虚拟的数据对象(如文本字符串),并检查服务器是否接收到正确的数据,如果没有,可能收到的数据会给你一些提示(如隐藏的“错误消息”而不是预期的数据) –

我想通了,在我的问题是

由于它的出现,iPhone模拟器不需要AVAudioSession而真正被激活iPhone的确如此。

因此,它可以很容易地audioRecorder初始化之前加入

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

固定。