Xcode:为WKWebView中的远程内容加载自定义本地存储的字体 [英] Xcode: Load custom locally stored font for remote content in WKWebView

查看:386
本文介绍了Xcode:为WKWebView中的远程内容加载自定义本地存储的字体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用XcodeSwift的最新版本.

I'm using the newest version of Xcode and Swift.

我有以下代码来加载HTML字符串并使用自定义字体,我以前是在Xcode中导入的:

I have the following code to load an HTML string and use a custom font, I prior imported in Xcode:

let html = """
        <html>
        <body>
        <head>
        <style>
        @font-face
        {
            font-family: 'Blastimo';
            src: local('Blastimo'), url('Blastimo.ttf') format('truetype');
        }
        </style>
        </head>
        <h1 style="font-family:'Blastimo';font-size:50px;">This is my test!</h1>
        </body>
        </html>
        """
        webView.loadHTMLString(html, baseURL: Bundle.main.resourceURL)

以下代码允许我加载远程内容,例如从我的网络服务器上:

The following code allows me to load remote content, e.g. from my web server:

if let url = URL(string: "https://www.example.com") {
            let request = URLRequest(url: url)
            webView.load(request)
        }

但是,我想到达的是:加载远程内容(如第二个代码中一样),但是将本地存储的自定义字体传递给此内容,如第一个代码中一样.

But, what I want to reach is: Load remote content, as in second code, but pass my locally stored custom font to this, as in the first code.

方法:我知道如何使用本地存储的字体加载HTML字符串,并且我知道如何不使用本地存储的字体加载远程内容.但是我不知道如何使用本地存储的字体加载远程内容.

Means: I know how to load an HTML string with a locally stored font and I know how to load remote content without a locally stored font. But I don't know how to load remote content with a locally stored font.

我尝试过:

webView.load(request, baseURL: Bundle.main.resourceURL)

但是这不起作用.会引发错误.

but this isn't working. It throws an error.

我尝试了很多,但是没有成功.我的最后一个想法是从远程内容中获取源代码,将其转换为字符串,向其中添加font-face样式,并使用webView.loadHTMLString加载它.这将使我能够显示远程内容,同时仍然能够使用webView.loadHTMLString(html, baseURL: Bundle.main.resourceURL)加载该内容,以将本地存储的字体传递给它.

I tried so much but without success. My last idea is to get the source code from the remote content, convert it to a string, add font-face style to it and load it with webView.loadHTMLString. This will allow me to display the remote content while still being able to load this with webView.loadHTMLString(html, baseURL: Bundle.main.resourceURL) to pass the locally stored font to it.

真的没有其他方法可以做到这一点吗?使用webView.load(request)时,无法使用本地存储的字体吗?

Is there really no other way to do this? Is there no way to use my locally stored font when using webView.load(request)?

推荐答案

我现在找到了一个解决方案.也许不是最好的,但是它正在起作用.

I found a solution now. Maybe not the best but it's working.

首先,我使用

First, I converted the Blastimo.ttf file to a base64 encoded CSS embedded font with this converter.

这给了我以下(或类似内容):

This gives me the following (or similar):

@font-face {
    font-family: 'Blastimo';
    src: url(data:application/x-font-woff;charset=utf-8;base64,HERE_COMES_THE_QUITE_LONG_BASE64_CODE_CREATED_BY_THE_CONVERTER) format('woff');
    font-weight: normal;
    font-style: normal;
}

我使用此代码(上面的代码来自转换器)将名为fonts.css的文件导入/嵌入到我的Xcode项目中.导入/嵌入时应激活Add to targets.

I imported/embedded a file called fonts.css with this code (the code above from the converter) to my Xcode project. Add to targets should be activated when importing/embedding.

在我的ViewController.swift文件中,我具有以下代码(例如,在viewDidLoad()中)以加载远程内容并调用本地CSS文件的函数:

In my ViewController.swift file I have the following code (e.g. in viewDidLoad()) to load the remote content and call the functions for the local CSS file:

    if let url = URL(string: "https://www.example.com") {
    let request = URLRequest(url: url)
    webView.load(request)
    }
    injectToPage()

此外,这三个功能必须添加到ViewController.swift文件的某个位置:

Additionally, these three functions have to be added somewhere to the ViewController.swift file:

    private func readFileBy(name: String, type: String) -> String {
        guard let path = Bundle.main.path(forResource: name, ofType: type) else {
            return "Failed to find path"
        }
        
        do {
            return try String(contentsOfFile: path, encoding: .utf8)
        } catch {
            return "Unkown Error"
        }
    }
    func injectToPage() {
        let cssFile = readFileBy(name: "fonts", type: "css")
        let cssStyle = """
            javascript:(function() {
            var parent = document.getElementsByTagName('head').item(0);
            var style = document.createElement('style');
            style.innerHTML = window.atob('\(encodeStringTo64(fromString: cssFile)!)');
            parent.appendChild(style)})()
        """
        let cssScript = WKUserScript(source: cssStyle, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
        webView.configuration.userContentController.addUserScript(cssScript)
    }
    private func encodeStringTo64(fromString: String) -> String? {
        let plainData = fromString.data(using: .utf8)
        return plainData?.base64EncodedString(options: [])
    }

现在,尽管内容是远程加载的,但我仍可以在WKWebView中以本地方式在应用程序存储的字体中使用

Now, I can use the locally in the app stored font in my WKWebView although the content is loaded remotely.

就我而言,我将其添加到(html或php)文件中,该文件是从Web服务器远程加载的:

In my case, I added this to the (html or php) file, that's loaded remotely from my web server:

<style>
*   {
    font-family:'Blastimo';
}
</style>

注意: 您正在远程加载的文件需要具有<head></head>元素,因为字体是在此末尾注入的.

Note: The file you're loading remotely needs to have <head></head> element, since the font is injected at the end of this.

这篇关于Xcode:为WKWebView中的远程内容加载自定义本地存储的字体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆