Как загрузить CSS-файл в комплекте для некоторого указанного URL в wkwebview? - PullRequest
0 голосов
/ 26 марта 2019

У меня есть WKWebView.Веб-страница загружает большую часть своего CSS-файла из CDN.Но есть этот часто используемый большой CSS-файл, который я хотел бы поместить в приложение Bundle, чтобы веб-просмотр загружался быстрее.Кто-нибудь знает, как загрузить из комплекта?

Я не хочу вставлять файл CSS.Вместо этого я хочу перенаправить запрос некоторых CSS-файлов на мой локальный URL-адрес.

Отличная версия Swift.

Спасибо.

Ответы [ 2 ]

1 голос
/ 26 марта 2019

Создайте файл style.css, как показано ниже, и перетащите его в каталог вашего проекта.

@font-face {
    font-family: "Titillium Web";
    font-weight: normal;
    src: url("TitilliumWeb-Regular.ttf")
}

@font-face {
    font-family: "Titillium Web";
    font-style: italic;
    src: url("TitilliumWeb-Italic.ttf")
}

@font-face {
    font-family: "Titillium Web";
    font-weight: bold;
    src: url("TitilliumWeb-Bold.ttf")
}
body {
    margin: 0;
    font-family: "Titillium Web";
    font-weight: normal;
    font-size: 13pt;
}

Добавьте приведенный ниже исходный код в viewDidLoad UIViewController ()

override func viewDidLoad() {
    super.viewDidLoad()

    let html = """
    "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. <b>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</b>
    <br>
    <i>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</i>
    <br>
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."
"""

    let htmlStart = "<HTML><HEAD><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, shrink-to-fit=no\"></HEAD><BODY>"
    let htmlEnd = "</BODY></HTML>"
    let htmlString = "\(htmlStart)\(html)\(htmlEnd)"
    webView.loadHTMLString(htmlString, baseURL: Bundle.main.bundleURL)
    self.view.addSubview(webView)
  }

Создайте объект WKWebView, как показано нижеи запустите приложение, оно загрузит контент.

  lazy var webView: WKWebView = {
    guard
      let path = Bundle.main.path(forResource: "style", ofType: "css"),
      let cssString = try? String(contentsOfFile: path).components(separatedBy: .newlines).joined()
      else {
        return WKWebView()
    }

    let source = """
    var style = document.createElement('style');
    style.innerHTML = '\(cssString)';
    document.head.appendChild(style);
    """

    let userScript = WKUserScript(source: source,
                                  injectionTime: .atDocumentEnd,
                                  forMainFrameOnly: true)

    let userContentController = WKUserContentController()
    userContentController.addUserScript(userScript)

    let configuration = WKWebViewConfiguration()
    configuration.userContentController = userContentController

    let webView = WKWebView(frame: self.view.frame,
                            configuration: configuration)
    return webView
  }()

enter image description here

0 голосов
/ 26 марта 2019

Вы можете предварительно загрузить html-код в строку, вставить содержимое локального CSS-кода в некоторые теги стиля и, наконец, показать эту измененную строку в вашем WKWebView.

Ниже вы увидите работающее решение, выпросто нужно перетащить файл с именем inject.css внутри вашего проекта.Этот файл содержит стиль, который вы хотите применить.

Убедитесь, что у вас есть WKWebView с именем webView и кнопка, подключенная к розеткам для работы следующего решения (это решение, вероятно, нуждается в некотором рефакторинге):

import UIKit
import WebKit

class ViewController: UIViewController {
  @IBOutlet weak var webView: WKWebView!

  @IBAction func loadStuffTapped(_ sender: Any) {

    injectCssAndShow(url: "https://www.wikipedia.org/")

  }

  // this one loads the css from your bundle
  func loadCss()->String? {
    if let filepath = Bundle.main.path(forResource: "inject", ofType: "css") {
      do {
        let contents = try String(contentsOfFile: filepath)
        print(contents)
        return contents
      } catch {
        // contents could not be loaded
      }
    } else {
      // inject.css not found!
    }
    return nil
  }

// this (kind of bloated...) function loads the orignal html, injects your css and shows the modified version inside of your WKWebview
  func injectCssAndShow(url: String) {

    let request = NSMutableURLRequest(url: NSURL(string: url)! as URL,
                                      cachePolicy: .useProtocolCachePolicy,
                                      timeoutInterval: 10.0)
    request.httpMethod = "GET"

    let session = URLSession.shared
    let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
      if (error != nil) {
        print(error as Any)
      } else {
        let htmlString = String(decoding: data ?? Data(), as: UTF8.self)

        DispatchQueue.main.async {

          let result = htmlString.range(of: "<title>",
                                        options: NSString.CompareOptions.literal,
                                        range: htmlString.startIndex..<htmlString.endIndex,
                                        locale: nil)

          if let range = result {
            let start = range.lowerBound
            let injection = self.loadCss() ?? ""
            let modifiedHtml = "\(htmlString[htmlString.startIndex..<start]) <style>\(injection)</style> \(htmlString[start..<htmlString.endIndex])"
            self.webView.loadHTMLString(modifiedHtml, baseURL: URL.init(string: url))
          }
        }
      }
    })

    dataTask.resume()

  }
}

Animation of posted solution

...