I’ve made a sport utilizing net applied sciences, and for the iOS model I’m utilizing a webview to show it to customers.
Whereas it’s working, I would wish to intercept requests to exterior property and serve bundled property as an alternative for efficiency causes.
Essentially the most easy implementation for me gave the impression to be utilizing a WKWebView
and setting a customized url scheme handler utilizing setURLSchemeHandler
on the WKWebViewConfiguration
. For some cause, I couldn’t get https
to work because the second argument of setURLSchemeHandler
(forURLScheme). I ‘hacked’ my manner via and got here up with the next code which doesn’t appear to crash however isn’t working correctly both.
App.swift
import SwiftUI
@principal
struct App: App {
var physique: some Scene {
WindowGroup {
ContentView()
}
}
}
ContentView.swift
import SwiftUI
import WebKit
struct ContentView: View {
// Exterior = random prefix since https isn't working
@State non-public var urlString = "exterior://instance.com/"
var physique: some View {
WebView(urlString: $urlString)
.edgesIgnoringSafeArea(.all)
}
}
struct WebView: UIViewRepresentable {
@Binding var urlString: String
func makeUIView(context: Context) -> WKWebView {
let webConfiguration = WKWebViewConfiguration()
webConfiguration.preferences.isElementFullscreenEnabled = true
let schemeHandler = CustomURLSchemeHandler()
// exterior = random string since https isn't working
webConfiguration.setURLSchemeHandler(schemeHandler, forURLScheme: "exterior")
return WKWebView(body: .zero, configuration: webConfiguration)
}
// Load the URL when the view seems or the URL modifications
func updateUIView(_ uiView: WKWebView, context: Context) {
if let url = URL(string: urlString) {
let request = URLRequest(url: url)
uiView.load(request)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
CustomUrlSchemeHandler.swift
import WebKit
class CustomURLSchemeHandler: NSObject, WKURLSchemeHandler {
let assets: [[String: String]] = [
["path": "dist/audio/ambient/action_2.mp3", "mime_type": "audio/mpeg"],
["path": "dist/fonts/Fontin-Bold.ttf", "mime_type": "font/ttf"],
["path": "dist/img/backgrounds/2_titlescreen_921x1.webp", "mime_type": "image/webp"]
]
func webView(_ webView: WKWebView, begin urlSchemeTask: WKURLSchemeTask) {
guard let url = urlSchemeTask.request.url else {
urlSchemeTask.didFailWithError(NSError(area: "CustomURLSchemeHandler", code: 0, userInfo: [NSLocalizedDescriptionKey: "Invalid URL"]))
return
}
// Take away the "exterior://" prefix
let httpsURLString = url.absoluteString.replacingOccurrences(of: "exterior://", with: "https://")
// Iterate via assets to discover a matching path
for useful resource in assets {
if let path = useful resource["path"], url.absoluteString == "https://instance.com/" + path {
// Serve the native useful resource
if let localFilePath = Bundle.principal.path(forResource: (path as NSString).lastPathComponent, ofType: nil),
let localFileData = strive? Knowledge(contentsOf: URL(fileURLWithPath: localFilePath)) {
let response = URLResponse(url: url, mimeType: mimeType, expectedContentLength: localFileData.depend, textEncodingName: nil)
urlSchemeTask.didReceive(response)
urlSchemeTask.didReceive(localFileData)
urlSchemeTask.didFinish()
return
}
}
}
// no match, load the information from httpsURLString
if let httpsURL = URL(string: httpsURLString) {
let session = URLSession.shared
let process = session.dataTask(with: httpsURL) { (knowledge, response, error) in
if let error = error {
print(error)
urlSchemeTask.didFailWithError(error)
} else if let knowledge = knowledge, let response = response {
let mimeType = response.mimeType ?? "utility/octet-stream"
let urlResponse = URLResponse(url: httpsURL, mimeType: mimeType, expectedContentLength: knowledge.depend, textEncodingName: nil)
// Ship the response and knowledge again to urlSchemeTask
urlSchemeTask.didReceive(urlResponse)
urlSchemeTask.didReceive(knowledge)
urlSchemeTask.didFinish()
}
}
process.resume()
} else {
urlSchemeTask.didFailWithError(NSError(area: "CustomURLSchemeHandler", code: 0, userInfo: [NSLocalizedDescriptionKey: "Invalid URL"]))
}
}
func webView(_ webView: WKWebView, cease urlSchemeTask: WKURLSchemeTask) {
// Deal with the cancellation of the URL scheme process if crucial
}
}
I have never even been in a position to check if serving native property even work, as a result of even when there a no matches discovered with the code above, the response is actually gradual and it appears to interrupt sure stuff (by the seems to be of it, CSS information?).
I really feel like I’ve tried all choices on the market however I really feel like I am utterly caught. To make issues worse, my server is beginning to wrestle due to all of the folks consistently retrieving all of the picture and audio property that make up my sport.
Does anybody know the right way to intercept all requests to exterior property and serve bundled property as an alternative (in the event that they exist)?
Thanks prematurely.