11 C
London
Monday, June 10, 2024

ios – Utilizing Swift, how can I intercept a request for an internet picture and serve a neighborhood picture as an alternative?


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.

Latest news
Related news

LEAVE A REPLY

Please enter your comment!
Please enter your name here