iOSアプリ内ブラウザでのオーディオ再生の制限解除

2015-12-22

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.
}
}

参考