是否可以在webview上显示之前预加载html

时间:2017-04-23 05:41:07

标签: ios uiwebview wkwebview

我搜索了整个互联网,找不到解决方案,所以决定向专家询问是否可能。

我有一个博客,我正在开发iOS应用,但加载内容需要太多时间。

因此可以在用户打开文章之前预加载所有文章的html(不是图像),就像FB即时文章一样。 FB即时文章被预加载和缓存,当用户打开它时,它会在闪存中打开,除了图像,用户打开它时会下载。

目前我正在使用uiwebview,我计划将其替换为wkwebview。

提前感谢您的帮助。

调用缓存

CachedArticles.shared.cacheArticles(self.articles) { success 
    print("cache creation finished, success: \(success)")
}

致电webview

tableView.deselectRow(at: indexPath, animated: true)
let webVC = storyboard!.instantiateViewController(withIdentifier:"NewsReaderViewController") as! NewsReaderViewController
webVC.article = self.articles?[indexPath.row]
navigationController?.pushViewController(webVC, animated: true)

缓存类

import UIKit

class CachedArticles: NSObject {

static let shared: CachedArticles = CachedArticles()

let cachePath = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).first!

func cacheArticles(_ articles: [ArticalClass]?, completion: @escaping (Bool)->() ) {

    guard let articles = articles else { return }

    DispatchQueue.global().async {
        DispatchQueue.main.async {
            UIApplication.shared.isNetworkActivityIndicatorVisible = true
        }

        var success = true

        for article in articles {
            guard let path = article.url, let url = URL(string: path), self.webArchive(forHeadline: article.headline!.replacingOccurrences(of: " ", with: "")) == nil else { continue }

            print("caching article: \(article)")
            do {
                let data = try Data(contentsOf: url)
                let url = self.cacheFileURL(forHeadline: article.headline!)
                STWebArchiver().archiveHTMLData(data, textEncoding: "UTF-8", baseURL: url, completionBlock: { data in
                    (data! as NSData).write(toFile: url.path, atomically: true)
                })
            } catch let error {
                success = false
                print("Error: \(error)")
            }
        }

        DispatchQueue.main.async {
            UIApplication.shared.isNetworkActivityIndicatorVisible = false
            completion(success)
        }
    }
}

func webArchive(forHeadline: String?) -> URL? {
    let url = cacheFileURL(forHeadline: forHeadline!)
    return FileManager.default.fileExists(atPath: url.path) ? url : nil
}

private func cacheFileURL(forHeadline: String) -> URL {
    let url = URL(fileURLWithPath: self.cachePath).appendingPathComponent(forHeadline.replacingOccurrences(of: " ", with: "")+".webarchive")
    return url
}

}

2 个答案:

答案 0 :(得分:2)

您可以在预览中通过HTTP请求获取html文件并将其保存到缓存中,并在您真正输入时检查它是否在缓存中。

=============================================== ==

4.24已更新 有两个因素

首先,我不知道'articles'数组是如何生成的,以及它是否包含src url。

其次,我查看了STWebArchiver代码并找到了它:

<IfModule mod_rewrite.c>
RewriteEngine on

#
# Uncomment the statement below if you want to make use of
# HTTP authentication and it does not already work.
# This could be required if you are for example using PHP via Apache CGI.
#
#RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]

#
# The following 3 lines will rewrite URLs passed through the front controller
# to not require app.php in the actual URL. In other words, a controller is
# by default accessed at /app.php/my/controller, but can also be accessed at
# /my/controller
#
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ app.php [QSA,L]

#
# If symbolic links are not already being followed,
# uncomment the line below.
# http://anothersysadmin.wordpress.com/2008/06/10/mod_rewrite-forbidden-403-with-apache-228/
#
#Options +FollowSymLinks
</IfModule>
<IfModule mod_version.c>
<IfVersion < 2.4>
    <Files "config.php">
        Order Allow,Deny
        Deny from All
    </Files>
    <Files "common.php">
        Order Allow,Deny
        Deny from All
    </Files>
</IfVersion>
<IfVersion >= 2.4>
    <Files "config.php">
        Require all denied
    </Files>
    <Files "common.php">
        Require all denied
    </Files>
</IfVersion>
</IfModule>
<IfModule !mod_version.c>
<IfModule !mod_authz_core.c>
    <Files "config.php">
        Order Allow,Deny
        Deny from All
    </Files>
    <Files "common.php">
        Order Allow,Deny
        Deny from All
    </Files>
</IfModule>
<IfModule mod_authz_core.c>
    <Files "config.php">
        Require all denied
    </Files>
    <Files "common.php">
        Require all denied
    </Files>
</IfModule>
</IfModule>

这意味着STWebArchiver不仅缓存纯HTML文件,还缓存请求的资源。

答案 1 :(得分:0)

您可以先将它们创建为“贪婪”的webview方法,然后再将它们添加到视图层次结构并启动其请求。这假设每个webview实例将显示一个不导航到其他html页面的页面。 appDidFinishLaunching将是一个进行设置的地方。