iOSのブラウザではオーディオの再生に制限があって、ユーザがタッチなどの操作をした時に1つだけ鳴らすことができて、それ以外の任意のタイミングで鳴らすことができない。これは非常に困る。

SafariやChromeなど通常のブラウザではどうしようもないんだが、アプリ内でUIWebViewを使っている場合にはmediaPlaybackRequiresUserActionプロパティをfalseにしてやればこの制限が解除され、ユーザの操作がなくても好きなタイミングでオーディオを再生できるようになる:

  let webView: UIWebView = UIWebView()
  webView.mediaPlaybackRequiresUserAction = false

WKWebViewの場合

class ViewController: UIViewController {
  var webView: WKWebView!

  override func loadView() {
    super.loadView()

    let config = WKWebViewConfiguration()
    config.requiresUserActionForMediaPlayback = false

    webView = WKWebView(frame: view.bounds, configuration: config)
    view.addSubview(webView)
  }

  override func viewDidLoad() {
    super.viewDidLoad()
    // バンドルされたpublic_htmlディレクトリ以下を/temp/wwwにコピーして、その中のindex.htmlを開く
    let dirUrl = NSBundle.mainBundle().URLForResource("public_html", withExtension: "")!
    do {
      let dstUrl = try copyFilesToTempWWW(dirUrl)
      let url = dstUrl.URLByAppendingPathComponent("index.html")
      webView.loadRequest(NSURLRequest(URL: url))
    } catch let error as NSError {
      print("Error: " + error.debugDescription)
    }
  }

  func copyFilesToTempWWW(url: NSURL) throws -> NSURL {
    // Some safety checks
    var error:NSError? = nil
    if (!url.fileURL || !url.checkResourceIsReachableAndReturnError(&error)) {
      throw error ?? NSError(
        domain: "BuggyWKWebViewDomain",
        code: 1001,
        userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("URL must be a file URL.", comment:"")])
    }

    // Create "/temp/www" directory
    let fm = NSFileManager.defaultManager()
    let tmpDirURL = NSURL.fileURLWithPath(NSTemporaryDirectory()).URLByAppendingPathComponent("www")
    try! fm.createDirectoryAtURL(tmpDirURL, withIntermediateDirectories: true, attributes: nil)

    // Now copy given file to the temp directory
    let dstURL = tmpDirURL.URLByAppendingPathComponent(url.lastPathComponent!)
    let _ = try? fm.removeItemAtURL(dstURL)
    try! fm.copyItemAtURL(url, toURL: dstURL)

    // Files in "/temp/www" load flawlessly :)
    return dstURL
  }

  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }
}

参考