diff --git a/ios/Capacitor/Capacitor/WebViewAssetHandler.swift b/ios/Capacitor/Capacitor/WebViewAssetHandler.swift index 9dbff7a0cc..b25ebde723 100644 --- a/ios/Capacitor/Capacitor/WebViewAssetHandler.swift +++ b/ios/Capacitor/Capacitor/WebViewAssetHandler.swift @@ -27,25 +27,46 @@ internal class WebViewAssetHandler: NSObject, WKURLSchemeHandler { do { var data = Data() - if !stringToLoad.contains("cordova.js") { - if isMediaExtension(pathExtension: url.pathExtension) { - data = try Data(contentsOf: fileUrl, options: Data.ReadingOptions.mappedIfSafe) - } else { - data = try Data(contentsOf: fileUrl) - } - } let mimeType = mimeTypeForExtension(pathExtension: url.pathExtension) - let expectedContentLength = data.count - let headers = [ + var headers = [ "Content-Type": mimeType, "Cache-Control": "no-cache" ] - let urlResponse = URLResponse(url: localUrl, mimeType: mimeType, expectedContentLength: expectedContentLength, textEncodingName: nil) - let httpResponse = HTTPURLResponse(url: localUrl, statusCode: 200, httpVersion: nil, headerFields: headers) - if isMediaExtension(pathExtension: url.pathExtension) { - urlSchemeTask.didReceive(urlResponse) + if let rangeString = urlSchemeTask.request.value(forHTTPHeaderField: "Range"), + let totalSize = try fileUrl.resourceValues(forKeys: [.fileSizeKey]).fileSize, + isMediaExtension(pathExtension: url.pathExtension) { + let fileHandle = try FileHandle(forReadingFrom: fileUrl) + let parts = rangeString.components(separatedBy: "=") + let streamParts = parts[1].components(separatedBy: "-") + let fromRange = Int(streamParts[0]) ?? 0 + var toRange = totalSize - 1 + if streamParts.count > 1 { + toRange = Int(streamParts[1]) ?? toRange + } + let rangeLength = toRange - fromRange + 1 + try fileHandle.seek(toOffset: UInt64(fromRange)) + data = fileHandle.readData(ofLength: rangeLength) + headers["Accept-Ranges"] = "bytes" + headers["Content-Range"] = "bytes \(fromRange)-\(toRange)/\(totalSize)" + headers["Content-Length"] = String(data.count) + let response = HTTPURLResponse(url: localUrl, statusCode: 206, httpVersion: nil, headerFields: headers) + urlSchemeTask.didReceive(response!) + try fileHandle.close() } else { - urlSchemeTask.didReceive(httpResponse!) + if !stringToLoad.contains("cordova.js") { + if isMediaExtension(pathExtension: url.pathExtension) { + data = try Data(contentsOf: fileUrl, options: Data.ReadingOptions.mappedIfSafe) + } else { + data = try Data(contentsOf: fileUrl) + } + } + let urlResponse = URLResponse(url: localUrl, mimeType: mimeType, expectedContentLength: data.count, textEncodingName: nil) + let httpResponse = HTTPURLResponse(url: localUrl, statusCode: 200, httpVersion: nil, headerFields: headers) + if isMediaExtension(pathExtension: url.pathExtension) { + urlSchemeTask.didReceive(urlResponse) + } else { + urlSchemeTask.didReceive(httpResponse!) + } } urlSchemeTask.didReceive(data) } catch let error as NSError {